Save This Page
Home » openjdk-7 » javax » naming » [javadoc | source]
    1   /*
    2    * Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.naming;
   27   
   28   import java.util.Enumeration;
   29   import java.util.Properties;
   30   
   31   /**
   32    * This class represents a composite name -- a sequence of
   33    * component names spanning multiple namespaces.
   34    * Each component is a string name from the namespace of a
   35    * naming system. If the component comes from a hierarchical
   36    * namespace, that component can be further parsed into
   37    * its atomic parts by using the CompoundName class.
   38    *<p>
   39    * The components of a composite name are numbered.  The indexes of a
   40    * composite name with N components range from 0 up to, but not including, N.
   41    * This range may be written as [0,N).
   42    * The most significant component is at index 0.
   43    * An empty composite name has no components.
   44    *<p>
   45    * <h4>JNDI Composite Name Syntax</h4>
   46    * JNDI defines a standard string representation for composite names. This
   47    * representation is the concatenation of the components of a composite name
   48    * from left to right using the component separator (a forward
   49    * slash character (/)) to separate each component.
   50    * The JNDI syntax defines the following meta characters:
   51    * <ul>
   52    * <li>escape (backward slash \),
   53    * <li>quote characters  (single (') and double quotes (")), and
   54    * <li>component separator (forward slash character (/)).
   55    * </ul>
   56    * Any occurrence of a leading quote, an escape preceding any meta character,
   57    * an escape at the end of a component, or a component separator character
   58    * in an unquoted component must be preceded by an escape character when
   59    * that component is being composed into a composite name string.
   60    * Alternatively, to avoid adding escape characters as described,
   61    * the entire component can be quoted using matching single quotes
   62    * or matching double quotes. A single quote occurring within a double-quoted
   63    * component is not considered a meta character (and need not be escaped),
   64    * and vice versa.
   65    *<p>
   66    * When two composite names are compared, the case of the characters
   67    * is significant.
   68    *<p>
   69    * A leading component separator (the composite name string begins with
   70    * a separator) denotes a leading empty component (a component consisting
   71    * of an empty string).
   72    * A trailing component separator (the composite name string ends with
   73    * a separator) denotes a trailing empty component.
   74    * Adjacent component separators denote an empty component.
   75    *<p>
   76    *<h4>Composite Name Examples</h4>
   77    *This table shows examples of some composite names. Each row shows
   78    *the string form of a composite name and its corresponding structural form
   79    *(<tt>CompositeName</tt>).
   80    *<p>
   81   <table border="1" cellpadding=3 width="70%" summary="examples showing string form of composite name and its corresponding structural form (CompositeName)">
   82   
   83   <tr>
   84   <th>String Name</th>
   85   <th>CompositeName</th>
   86   </tr>
   87   
   88   <tr>
   89   <td>
   90   ""
   91   </td>
   92   <td>{} (the empty name == new CompositeName("") == new CompositeName())
   93   </td>
   94   </tr>
   95   
   96   <tr>
   97   <td>
   98   "x"
   99   </td>
  100   <td>{"x"}
  101   </td>
  102   </tr>
  103   
  104   <tr>
  105   <td>
  106   "x/y"
  107   </td>
  108   <td>{"x", "y"}</td>
  109   </tr>
  110   
  111   <tr>
  112   <td>"x/"</td>
  113   <td>{"x", ""}</td>
  114   </tr>
  115   
  116   <tr>
  117   <td>"/x"</td>
  118   <td>{"", "x"}</td>
  119   </tr>
  120   
  121   <tr>
  122   <td>"/"</td>
  123   <td>{""}</td>
  124   </tr>
  125   
  126   <tr>
  127   <td>"//"</td>
  128   <td>{"", ""}</td>
  129   </tr>
  130   
  131   <tr><td>"/x/"</td>
  132   <td>{"", "x", ""}</td>
  133   </tr>
  134   
  135   <tr><td>"x//y"</td>
  136   <td>{"x", "", "y"}</td>
  137   </tr>
  138   </table>
  139    * <p>
  140    *<h4>Composition Examples</h4>
  141    * Here are some composition examples.  The right column shows composing
  142    * string composite names while the left column shows composing the
  143    * corresponding <tt>CompositeName</tt>s.  Notice that composing the
  144    * string forms of two composite names simply involves concatenating
  145    * their string forms together.
  146   
  147   <p> <table border="1" cellpadding=3 width="70%" summary="composition examples showing string names and composite names">
  148   
  149   <tr>
  150   <th>String Names</th>
  151   <th>CompositeNames</th>
  152   </tr>
  153   
  154   <tr>
  155   <td>
  156   "x/y"           + "/"   = x/y/
  157   </td>
  158   <td>
  159   {"x", "y"}      + {""}  = {"x", "y", ""}
  160   </td>
  161   </tr>
  162   
  163   <tr>
  164   <td>
  165   ""              + "x"   = "x"
  166   </td>
  167   <td>
  168   {}              + {"x"} = {"x"}
  169   </td>
  170   </tr>
  171   
  172   <tr>
  173   <td>
  174   "/"             + "x"   = "/x"
  175   </td>
  176   <td>
  177   {""}            + {"x"} = {"", "x"}
  178   </td>
  179   </tr>
  180   
  181   <tr>
  182   <td>
  183   "x"   + ""      + ""    = "x"
  184   </td>
  185   <td>
  186   {"x"} + {}      + {}    = {"x"}
  187   </td>
  188   </tr>
  189   
  190   </table>
  191    *<p>
  192    *<h4>Multithreaded Access</h4>
  193    * A <tt>CompositeName</tt> instance is not synchronized against concurrent
  194    * multithreaded access. Multiple threads trying to access and modify a
  195    * <tt>CompositeName</tt> should lock the object.
  196    *
  197    * @author Rosanna Lee
  198    * @author Scott Seligman
  199    * @since 1.3
  200    */
  201   
  202   
  203   public class CompositeName implements Name {
  204   
  205       private transient NameImpl impl;
  206       /**
  207         * Constructs a new composite name instance using the components
  208         * specified by 'comps'. This protected method is intended to be
  209         * to be used by subclasses of CompositeName when they override
  210         * methods such as clone(), getPrefix(), getSuffix().
  211         *
  212         * @param comps A non-null enumeration containing the components for the new
  213         *              composite name. Each element is of class String.
  214         *               The enumeration will be consumed to extract its
  215         *               elements.
  216         */
  217       protected CompositeName(Enumeration<String> comps) {
  218           impl = new NameImpl(null, comps); // null means use default syntax
  219       }
  220   
  221       /**
  222         * Constructs a new composite name instance by parsing the string n
  223         * using the composite name syntax (left-to-right, slash separated).
  224         * The composite name syntax is described in detail in the class
  225         * description.
  226         *
  227         * @param  n       The non-null string to parse.
  228         * @exception InvalidNameException If n has invalid composite name syntax.
  229         */
  230       public CompositeName(String n) throws InvalidNameException {
  231           impl = new NameImpl(null, n);  // null means use default syntax
  232       }
  233   
  234       /**
  235         * Constructs a new empty composite name. Such a name returns true
  236         * when <code>isEmpty()</code> is invoked on it.
  237         */
  238       public CompositeName() {
  239           impl = new NameImpl(null);  // null means use default syntax
  240       }
  241   
  242       /**
  243         * Generates the string representation of this composite name.
  244         * The string representation consists of enumerating in order
  245         * each component of the composite name and separating
  246         * each component by a forward slash character. Quoting and
  247         * escape characters are applied where necessary according to
  248         * the JNDI syntax, which is described in the class description.
  249         * An empty component is represented by an empty string.
  250         *
  251         * The string representation thus generated can be passed to
  252         * the CompositeName constructor to create a new equivalent
  253         * composite name.
  254         *
  255         * @return A non-null string representation of this composite name.
  256         */
  257       public String toString() {
  258           return impl.toString();
  259       }
  260   
  261       /**
  262         * Determines whether two composite names are equal.
  263         * If obj is null or not a composite name, false is returned.
  264         * Two composite names are equal if each component in one is equal
  265         * to the corresponding component in the other. This implies
  266         * both have the same number of components, and each component's
  267         * equals() test against the corresponding component in the other name
  268         * returns true.
  269         *
  270         * @param  obj     The possibly null object to compare against.
  271         * @return true if obj is equal to this composite name, false otherwise.
  272         * @see #hashCode
  273         */
  274       public boolean equals(Object obj) {
  275           return (obj != null &&
  276                   obj instanceof CompositeName &&
  277                   impl.equals(((CompositeName)obj).impl));
  278       }
  279   
  280       /**
  281         * Computes the hash code of this composite name.
  282         * The hash code is the sum of the hash codes of individual components
  283         * of this composite name.
  284         *
  285         * @return An int representing the hash code of this name.
  286         * @see #equals
  287         */
  288       public int hashCode() {
  289           return impl.hashCode();
  290       }
  291   
  292   
  293       /**
  294        * Compares this CompositeName with the specified Object for order.
  295        * Returns a
  296        * negative integer, zero, or a positive integer as this Name is less
  297        * than, equal to, or greater than the given Object.
  298        * <p>
  299        * If obj is null or not an instance of CompositeName, ClassCastException
  300        * is thrown.
  301        * <p>
  302        * See equals() for what it means for two composite names to be equal.
  303        * If two composite names are equal, 0 is returned.
  304        * <p>
  305        * Ordering of composite names follows the lexicographical rules for
  306        * string comparison, with the extension that this applies to all
  307        * the components in the composite name. The effect is as if all the
  308        * components were lined up in their specified ordered and the
  309        * lexicographical rules applied over the two line-ups.
  310        * If this composite name is "lexicographically" lesser than obj,
  311        * a negative number is returned.
  312        * If this composite name is "lexicographically" greater than obj,
  313        * a positive number is returned.
  314        * @param obj The non-null object to compare against.
  315        *
  316        * @return  a negative integer, zero, or a positive integer as this Name
  317        *          is less than, equal to, or greater than the given Object.
  318        * @exception ClassCastException if obj is not a CompositeName.
  319        */
  320       public int compareTo(Object obj) {
  321           if (!(obj instanceof CompositeName)) {
  322               throw new ClassCastException("Not a CompositeName");
  323           }
  324           return impl.compareTo(((CompositeName)obj).impl);
  325       }
  326   
  327       /**
  328         * Generates a copy of this composite name.
  329         * Changes to the components of this composite name won't
  330         * affect the new copy and vice versa.
  331         *
  332         * @return A non-null copy of this composite name.
  333         */
  334       public Object clone() {
  335           return (new CompositeName(getAll()));
  336       }
  337   
  338       /**
  339         * Retrieves the number of components in this composite name.
  340         *
  341         * @return The nonnegative number of components in this composite name.
  342         */
  343       public int size() {
  344           return (impl.size());
  345       }
  346   
  347       /**
  348         * Determines whether this composite name is empty. A composite name
  349         * is empty if it has zero components.
  350         *
  351         * @return true if this composite name is empty, false otherwise.
  352         */
  353       public boolean isEmpty() {
  354           return (impl.isEmpty());
  355       }
  356   
  357       /**
  358         * Retrieves the components of this composite name as an enumeration
  359         * of strings.
  360         * The effects of updates to this composite name on this enumeration
  361         * is undefined.
  362         *
  363         * @return A non-null enumeration of the components of
  364         *         this composite name. Each element of the enumeration is of
  365         *         class String.
  366         */
  367       public Enumeration<String> getAll() {
  368           return (impl.getAll());
  369       }
  370   
  371       /**
  372         * Retrieves a component of this composite name.
  373         *
  374         * @param  posn    The 0-based index of the component to retrieve.
  375         *                 Must be in the range [0,size()).
  376         * @return The non-null component at index posn.
  377         * @exception ArrayIndexOutOfBoundsException if posn is outside the
  378         *         specified range.
  379         */
  380       public String get(int posn) {
  381           return (impl.get(posn));
  382       }
  383   
  384       /**
  385         * Creates a composite name whose components consist of a prefix of the
  386         * components in this composite name. Subsequent changes to
  387         * this composite name does not affect the name that is returned.
  388         *
  389         * @param  posn    The 0-based index of the component at which to stop.
  390         *                 Must be in the range [0,size()].
  391         * @return A composite name consisting of the components at indexes in
  392         *         the range [0,posn).
  393         * @exception ArrayIndexOutOfBoundsException
  394         *         If posn is outside the specified range.
  395         */
  396       public Name getPrefix(int posn) {
  397           Enumeration comps = impl.getPrefix(posn);
  398           return (new CompositeName(comps));
  399       }
  400   
  401       /**
  402         * Creates a composite name whose components consist of a suffix of the
  403         * components in this composite name. Subsequent changes to
  404         * this composite name does not affect the name that is returned.
  405         *
  406         * @param  posn    The 0-based index of the component at which to start.
  407         *                 Must be in the range [0,size()].
  408         * @return A composite name consisting of the components at indexes in
  409         *         the range [posn,size()).  If posn is equal to
  410         *         size(), an empty composite name is returned.
  411         * @exception ArrayIndexOutOfBoundsException
  412         *         If posn is outside the specified range.
  413         */
  414       public Name getSuffix(int posn) {
  415           Enumeration comps = impl.getSuffix(posn);
  416           return (new CompositeName(comps));
  417       }
  418   
  419       /**
  420         * Determines whether a composite name is a prefix of this composite name.
  421         * A composite name 'n' is a prefix if it is equal to
  422         * getPrefix(n.size())--in other words, this composite name
  423         * starts with 'n'. If 'n' is null or not a composite name, false is returned.
  424         *
  425         * @param  n       The possibly null name to check.
  426         * @return true if n is a CompositeName and
  427         *         is a prefix of this composite name, false otherwise.
  428         */
  429       public boolean startsWith(Name n) {
  430           if (n instanceof CompositeName) {
  431               return (impl.startsWith(n.size(), n.getAll()));
  432           } else {
  433               return false;
  434           }
  435       }
  436   
  437       /**
  438         * Determines whether a composite name is a suffix of this composite name.
  439         * A composite name 'n' is a suffix if it it is equal to
  440         * getSuffix(size()-n.size())--in other words, this
  441         * composite name ends with 'n'.
  442         * If n is null or not a composite name, false is returned.
  443         *
  444         * @param  n       The possibly null name to check.
  445         * @return true if n is a CompositeName and
  446         *         is a suffix of this composite name, false otherwise.
  447         */
  448       public boolean endsWith(Name n) {
  449           if (n instanceof CompositeName) {
  450               return (impl.endsWith(n.size(), n.getAll()));
  451           } else {
  452               return false;
  453           }
  454       }
  455   
  456       /**
  457         * Adds the components of a composite name -- in order -- to the end of
  458         * this composite name.
  459         *
  460         * @param suffix   The non-null components to add.
  461         * @return The updated CompositeName, not a new one. Cannot be null.
  462         * @exception InvalidNameException If suffix is not a composite name.
  463         */
  464       public Name addAll(Name suffix)
  465           throws InvalidNameException
  466       {
  467           if (suffix instanceof CompositeName) {
  468               impl.addAll(suffix.getAll());
  469               return this;
  470           } else {
  471               throw new InvalidNameException("Not a composite name: " +
  472                   suffix.toString());
  473           }
  474       }
  475   
  476       /**
  477         * Adds the components of a composite name -- in order -- at a specified
  478         * position within this composite name.
  479         * Components of this composite name at or after the index of the first
  480         * new component are shifted up (away from index 0)
  481         * to accommodate the new components.
  482         *
  483         * @param n        The non-null components to add.
  484         * @param posn     The index in this name at which to add the new
  485         *                 components.  Must be in the range [0,size()].
  486         * @return The updated CompositeName, not a new one. Cannot be null.
  487         * @exception InvalidNameException If n is not a composite name.
  488         * @exception ArrayIndexOutOfBoundsException
  489         *         If posn is outside the specified range.
  490         */
  491       public Name addAll(int posn, Name n)
  492           throws InvalidNameException
  493       {
  494           if (n instanceof CompositeName) {
  495               impl.addAll(posn, n.getAll());
  496               return this;
  497           } else {
  498               throw new InvalidNameException("Not a composite name: " +
  499                   n.toString());
  500           }
  501       }
  502   
  503       /**
  504         * Adds a single component to the end of this composite name.
  505         *
  506         * @param comp     The non-null component to add.
  507         * @return The updated CompositeName, not a new one. Cannot be null.
  508         * @exception InvalidNameException If adding comp at end of the name
  509         *                         would violate the name's syntax.
  510         */
  511       public Name add(String comp) throws InvalidNameException {
  512           impl.add(comp);
  513           return this;
  514       }
  515   
  516       /**
  517         * Adds a single component at a specified position within this
  518         * composite name.
  519         * Components of this composite name at or after the index of the new
  520         * component are shifted up by one (away from index 0) to accommodate
  521         * the new component.
  522         *
  523         * @param  comp    The non-null component to add.
  524         * @param  posn    The index at which to add the new component.
  525         *                 Must be in the range [0,size()].
  526         * @return The updated CompositeName, not a new one. Cannot be null.
  527         * @exception ArrayIndexOutOfBoundsException
  528         *         If posn is outside the specified range.
  529         * @exception InvalidNameException If adding comp at the specified position
  530         *                         would violate the name's syntax.
  531         */
  532       public Name add(int posn, String comp)
  533           throws InvalidNameException
  534       {
  535           impl.add(posn, comp);
  536           return this;
  537       }
  538   
  539       /**
  540         * Deletes a component from this composite name.
  541         * The component of this composite name at position 'posn' is removed,
  542         * and components at indices greater than 'posn'
  543         * are shifted down (towards index 0) by one.
  544         *
  545         * @param  posn    The index of the component to delete.
  546         *                 Must be in the range [0,size()).
  547         * @return The component removed (a String).
  548         * @exception ArrayIndexOutOfBoundsException
  549         *         If posn is outside the specified range (includes case where
  550         *         composite name is empty).
  551         * @exception InvalidNameException If deleting the component
  552         *                         would violate the name's syntax.
  553         */
  554       public Object remove(int posn) throws InvalidNameException{
  555           return impl.remove(posn);
  556       }
  557   
  558       /**
  559        * Overridden to avoid implementation dependency.
  560        * @serialData The number of components (an <tt>int</tt>) followed by
  561        * the individual components (each a <tt>String</tt>).
  562        */
  563       private void writeObject(java.io.ObjectOutputStream s)
  564               throws java.io.IOException {
  565           s.writeInt(size());
  566           Enumeration comps = getAll();
  567           while (comps.hasMoreElements()) {
  568               s.writeObject(comps.nextElement());
  569           }
  570       }
  571   
  572       /**
  573        * Overridden to avoid implementation dependency.
  574        */
  575       private void readObject(java.io.ObjectInputStream s)
  576               throws java.io.IOException, ClassNotFoundException {
  577           impl = new NameImpl(null);  // null means use default syntax
  578           int n = s.readInt();    // number of components
  579           try {
  580               while (--n >= 0) {
  581                   add((String)s.readObject());
  582               }
  583           } catch (InvalidNameException e) {
  584               throw (new java.io.StreamCorruptedException("Invalid name"));
  585           }
  586       }
  587   
  588       /**
  589        * Use serialVersionUID from JNDI 1.1.1 for interoperability
  590        */
  591       private static final long serialVersionUID = 1667768148915813118L;
  592   
  593   /*
  594       // %%% Test code for serialization.
  595       public static void main(String[] args) throws Exception {
  596           CompositeName c = new CompositeName("aaa/bbb");
  597           java.io.FileOutputStream f1 = new java.io.FileOutputStream("/tmp/ser");
  598           java.io.ObjectOutputStream s1 = new java.io.ObjectOutputStream(f1);
  599           s1.writeObject(c);
  600           s1.close();
  601           java.io.FileInputStream f2 = new java.io.FileInputStream("/tmp/ser");
  602           java.io.ObjectInputStream s2 = new java.io.ObjectInputStream(f2);
  603           c = (CompositeName)s2.readObject();
  604   
  605           System.out.println("Size: " + c.size());
  606           System.out.println("Size: " + c.snit);
  607       }
  608   */
  609   
  610   /*
  611      %%% Testing code
  612       public static void main(String[] args) {
  613           try {
  614               for (int i = 0; i < args.length; i++) {
  615                   Name name;
  616                   Enumeration e;
  617                   System.out.println("Given name: " + args[i]);
  618                   name = new CompositeName(args[i]);
  619                   e = name.getComponents();
  620                   while (e.hasMoreElements()) {
  621                       System.out.println("Element: " + e.nextElement());
  622                   }
  623                   System.out.println("Constructed name: " + name.toString());
  624               }
  625           } catch (Exception ne) {
  626               ne.printStackTrace();
  627           }
  628       }
  629   */
  630   }

Save This Page
Home » openjdk-7 » javax » naming » [javadoc | source]