KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > naming > CompositeName


1 /*
2  * @(#)CompositeName.java 1.14 04/05/05
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.naming;
9
10 import java.util.Enumeration JavaDoc;
11 import java.util.Properties JavaDoc;
12
13 /**
14  * This class represents a composite name -- a sequence of
15  * component names spanning multiple namespaces.
16  * Each component is a string name from the namespace of a
17  * naming system. If the component comes from a hierarchical
18  * namespace, that component can be further parsed into
19  * its atomic parts by using the CompoundName class.
20  *<p>
21  * The components of a composite name are numbered. The indexes of a
22  * composite name with N components range from 0 up to, but not including, N.
23  * This range may be written as [0,N).
24  * The most significant component is at index 0.
25  * An empty composite name has no components.
26  *<p>
27  * <h4>JNDI Composite Name Syntax</h4>
28  * JNDI defines a standard string representation for composite names. This
29  * representation is the concatenation of the components of a composite name
30  * from left to right using the component separator (a forward
31  * slash character (/)) to separate each component.
32  * The JNDI syntax defines the following meta characters:
33  * <ul>
34  * <li>escape (backward slash \),
35  * <li>quote characters (single (') and double quotes (")), and
36  * <li>component separator (forward slash character (/)).
37  * </ul>
38  * Any occurrence of a leading quote, an escape preceding any meta character,
39  * an escape at the end of a component, or a component separator character
40  * in an unquoted component must be preceded by an escape character when
41  * that component is being composed into a composite name string.
42  * Alternatively, to avoid adding escape characters as described,
43  * the entire component can be quoted using matching single quotes
44  * or matching double quotes. A single quote occurring within a double-quoted
45  * component is not considered a meta character (and need not be escaped),
46  * and vice versa.
47  *<p>
48  * When two composite names are compared, the case of the characters
49  * is significant.
50  *<p>
51  * A leading component separator (the composite name string begins with
52  * a separator) denotes a leading empty component (a component consisting
53  * of an empty string).
54  * A trailing component separator (the composite name string ends with
55  * a separator) denotes a trailing empty component.
56  * Adjacent component separators denote an empty component.
57  *<p>
58  *<h4>Composite Name Examples</h4>
59  *This table shows examples of some composite names. Each row shows
60  *the string form of a composite name and its corresponding structural form
61  *(<tt>CompositeName</tt>).
62  *<p>
63 <table border="1" cellpadding=3 width="70%" summary="examples showing string form of composite name and its corresponding structural form (CompositeName)">
64
65 <tr>
66 <th>String Name</th>
67 <th>CompositeName</th>
68 </tr>
69
70 <tr>
71 <td>
72 ""
73 </td>
74 <td>{} (the empty name == new CompositeName("") == new CompositeName())
75 </td>
76 </tr>
77
78 <tr>
79 <td>
80 "x"
81 </td>
82 <td>{"x"}
83 </td>
84 </tr>
85
86 <tr>
87 <td>
88 "x/y"
89 </td>
90 <td>{"x", "y"}</td>
91 </tr>
92
93 <tr>
94 <td>"x/"</td>
95 <td>{"x", ""}</td>
96 </tr>
97
98 <tr>
99 <td>"/x"</td>
100 <td>{"", "x"}</td>
101 </tr>
102
103 <tr>
104 <td>"/"</td>
105 <td>{""}</td>
106 </tr>
107
108 <tr>
109 <td>"//"</td>
110 <td>{"", ""}</td>
111 </tr>
112
113 <tr><td>"/x/"</td>
114 <td>{"", "x", ""}</td>
115 </tr>
116
117 <tr><td>"x//y"</td>
118 <td>{"x", "", "y"}</td>
119 </tr>
120 </table>
121  * <p>
122  *<h4>Composition Examples</h4>
123  * Here are some composition examples. The right column shows composing
124  * string composite names while the left column shows composing the
125  * corresponding <tt>CompositeName</tt>s. Notice that composing the
126  * string forms of two composite names simply involves concatenating
127  * their string forms together.
128
129 <p> <table border="1" cellpadding=3 width="70%" summary="composition examples showing string names and composite names">
130
131 <tr>
132 <th>String Names</th>
133 <th>CompositeNames</th>
134 </tr>
135
136 <tr>
137 <td>
138 "x/y" + "/" = x/y/
139 </td>
140 <td>
141 {"x", "y"} + {""} = {"x", "y", ""}
142 </td>
143 </tr>
144
145 <tr>
146 <td>
147 "" + "x" = "x"
148 </td>
149 <td>
150 {} + {"x"} = {"x"}
151 </td>
152 </tr>
153
154 <tr>
155 <td>
156 "/" + "x" = "/x"
157 </td>
158 <td>
159 {""} + {"x"} = {"", "x"}
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 </table>
173  *<p>
174  *<h4>Multithreaded Access</h4>
175  * A <tt>CompositeName</tt> instance is not synchronized against concurrent
176  * multithreaded access. Multiple threads trying to access and modify a
177  * <tt>CompositeName</tt> should lock the object.
178  *
179  * @author Rosanna Lee
180  * @author Scott Seligman
181  * @version 1.14 04/05/05
182  * @since 1.3
183  */

184
185
186 public class CompositeName implements Name JavaDoc {
187
188     private transient NameImpl JavaDoc impl;
189     /**
190       * Constructs a new composite name instance using the components
191       * specified by 'comps'. This protected method is intended to be
192       * to be used by subclasses of CompositeName when they override
193       * methods such as clone(), getPrefix(), getSuffix().
194       *
195       * @param comps A non-null enumeration containing the components for the new
196       * composite name. Each element is of class String.
197       * The enumeration will be consumed to extract its
198       * elements.
199       */

200     protected CompositeName(Enumeration JavaDoc<String JavaDoc> comps) {
201     impl = new NameImpl JavaDoc(null, comps); // null means use default syntax
202
}
203
204     /**
205       * Constructs a new composite name instance by parsing the string n
206       * using the composite name syntax (left-to-right, slash separated).
207       * The composite name syntax is described in detail in the class
208       * description.
209       *
210       * @param n The non-null string to parse.
211       * @exception InvalidNameException If n has invalid composite name syntax.
212       */

213     public CompositeName(String JavaDoc n) throws InvalidNameException JavaDoc {
214     impl = new NameImpl JavaDoc(null, n); // null means use default syntax
215
}
216
217     /**
218       * Constructs a new empty composite name. Such a name returns true
219       * when <code>isEmpty()</code> is invoked on it.
220       */

221     public CompositeName() {
222     impl = new NameImpl JavaDoc(null); // null means use default syntax
223
}
224
225     /**
226       * Generates the string representation of this composite name.
227       * The string representation consists of enumerating in order
228       * each component of the composite name and separating
229       * each component by a forward slash character. Quoting and
230       * escape characters are applied where necessary according to
231       * the JNDI syntax, which is described in the class description.
232       * An empty component is represented by an empty string.
233       *
234       * The string representation thus generated can be passed to
235       * the CompositeName constructor to create a new equivalent
236       * composite name.
237       *
238       * @return A non-null string representation of this composite name.
239       */

240     public String JavaDoc toString() {
241     return impl.toString();
242     }
243
244     /**
245       * Determines whether two composite names are equal.
246       * If obj is null or not a composite name, false is returned.
247       * Two composite names are equal if each component in one is equal
248       * to the corresponding component in the other. This implies
249       * both have the same number of components, and each component's
250       * equals() test against the corresponding component in the other name
251       * returns true.
252       *
253       * @param obj The possibly null object to compare against.
254       * @return true if obj is equal to this composite name, false otherwise.
255       * @see #hashCode
256       */

257     public boolean equals(Object JavaDoc obj) {
258     return (obj != null &&
259         obj instanceof CompositeName JavaDoc &&
260         impl.equals(((CompositeName JavaDoc)obj).impl));
261     }
262
263     /**
264       * Computes the hash code of this composite name.
265       * The hash code is the sum of the hash codes of individual components
266       * of this composite name.
267       *
268       * @return An int representing the hash code of this name.
269       * @see #equals
270       */

271     public int hashCode() {
272     return impl.hashCode();
273     }
274
275
276     /**
277      * Compares this CompositeName with the specified Object for order.
278      * Returns a
279      * negative integer, zero, or a positive integer as this Name is less
280      * than, equal to, or greater than the given Object.
281      * <p>
282      * If obj is null or not an instance of CompositeName, ClassCastException
283      * is thrown.
284      * <p>
285      * See equals() for what it means for two composite names to be equal.
286      * If two composite names are equal, 0 is returned.
287      * <p>
288      * Ordering of composite names follows the lexicographical rules for
289      * string comparison, with the extension that this applies to all
290      * the components in the composite name. The effect is as if all the
291      * components were lined up in their specified ordered and the
292      * lexicographical rules applied over the two line-ups.
293      * If this composite name is "lexicographically" lesser than obj,
294      * a negative number is returned.
295      * If this composite name is "lexicographically" greater than obj,
296      * a positive number is returned.
297      * @param obj The non-null object to compare against.
298      *
299      * @return a negative integer, zero, or a positive integer as this Name
300      * is less than, equal to, or greater than the given Object.
301      * @exception ClassCastException if obj is not a CompositeName.
302      */

303     public int compareTo(Object JavaDoc obj) {
304     if (!(obj instanceof CompositeName JavaDoc)) {
305         throw new ClassCastException JavaDoc("Not a CompositeName");
306     }
307     return impl.compareTo(((CompositeName JavaDoc)obj).impl);
308     }
309
310     /**
311       * Generates a copy of this composite name.
312       * Changes to the components of this composite name won't
313       * affect the new copy and vice versa.
314       *
315       * @return A non-null copy of this composite name.
316       */

317     public Object JavaDoc clone() {
318     return (new CompositeName JavaDoc(getAll()));
319     }
320
321     /**
322       * Retrieves the number of components in this composite name.
323       *
324       * @return The nonnegative number of components in this composite name.
325       */

326     public int size() {
327     return (impl.size());
328     }
329
330     /**
331       * Determines whether this composite name is empty. A composite name
332       * is empty if it has zero components.
333       *
334       * @return true if this composite name is empty, false otherwise.
335       */

336     public boolean isEmpty() {
337     return (impl.isEmpty());
338     }
339
340     /**
341       * Retrieves the components of this composite name as an enumeration
342       * of strings.
343       * The effects of updates to this composite name on this enumeration
344       * is undefined.
345       *
346       * @return A non-null enumeration of the components of
347       * this composite name. Each element of the enumeration is of
348       * class String.
349       */

350     public Enumeration JavaDoc<String JavaDoc> getAll() {
351     return (impl.getAll());
352     }
353
354     /**
355       * Retrieves a component of this composite name.
356       *
357       * @param posn The 0-based index of the component to retrieve.
358       * Must be in the range [0,size()).
359       * @return The non-null component at index posn.
360       * @exception ArrayIndexOutOfBoundsException if posn is outside the
361       * specified range.
362       */

363     public String JavaDoc get(int posn) {
364     return (impl.get(posn));
365     }
366
367     /**
368       * Creates a composite name whose components consist of a prefix of the
369       * components in this composite name. Subsequent changes to
370       * this composite name does not affect the name that is returned.
371       *
372       * @param posn The 0-based index of the component at which to stop.
373       * Must be in the range [0,size()].
374       * @return A composite name consisting of the components at indexes in
375       * the range [0,posn).
376       * @exception ArrayIndexOutOfBoundsException
377       * If posn is outside the specified range.
378       */

379     public Name JavaDoc getPrefix(int posn) {
380     Enumeration JavaDoc comps = impl.getPrefix(posn);
381     return (new CompositeName JavaDoc(comps));
382     }
383
384     /**
385       * Creates a composite name whose components consist of a suffix 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 start.
390       * Must be in the range [0,size()].
391       * @return A composite name consisting of the components at indexes in
392       * the range [posn,size()). If posn is equal to
393       * size(), an empty composite name is returned.
394       * @exception ArrayIndexOutOfBoundsException
395       * If posn is outside the specified range.
396       */

397     public Name JavaDoc getSuffix(int posn) {
398     Enumeration JavaDoc comps = impl.getSuffix(posn);
399     return (new CompositeName JavaDoc(comps));
400     }
401
402     /**
403       * Determines whether a composite name is a prefix of this composite name.
404       * A composite name 'n' is a prefix if it is equal to
405       * getPrefix(n.size())--in other words, this composite name
406       * starts with 'n'. If 'n' is null or not a composite name, false is returned.
407       *
408       * @param n The possibly null name to check.
409       * @return true if n is a CompositeName and
410       * is a prefix of this composite name, false otherwise.
411       */

412     public boolean startsWith(Name JavaDoc n) {
413     if (n instanceof CompositeName JavaDoc) {
414         return (impl.startsWith(n.size(), n.getAll()));
415     } else {
416         return false;
417     }
418     }
419
420     /**
421       * Determines whether a composite name is a suffix of this composite name.
422       * A composite name 'n' is a suffix if it it is equal to
423       * getSuffix(size()-n.size())--in other words, this
424       * composite name ends with 'n'.
425       * If n is null or not a composite name, false is returned.
426       *
427       * @param n The possibly null name to check.
428       * @return true if n is a CompositeName and
429       * is a suffix of this composite name, false otherwise.
430       */

431     public boolean endsWith(Name JavaDoc n) {
432     if (n instanceof CompositeName JavaDoc) {
433         return (impl.endsWith(n.size(), n.getAll()));
434     } else {
435         return false;
436     }
437     }
438
439     /**
440       * Adds the components of a composite name -- in order -- to the end of
441       * this composite name.
442       *
443       * @param suffix The non-null components to add.
444       * @return The updated CompositeName, not a new one. Cannot be null.
445       * @exception InvalidNameException If suffix is not a composite name.
446       */

447     public Name JavaDoc addAll(Name JavaDoc suffix)
448     throws InvalidNameException JavaDoc
449     {
450     if (suffix instanceof CompositeName JavaDoc) {
451         impl.addAll(suffix.getAll());
452         return this;
453     } else {
454         throw new InvalidNameException JavaDoc("Not a composite name: " +
455         suffix.toString());
456     }
457     }
458
459     /**
460       * Adds the components of a composite name -- in order -- at a specified
461       * position within this composite name.
462       * Components of this composite name at or after the index of the first
463       * new component are shifted up (away from index 0)
464       * to accommodate the new components.
465       *
466       * @param n The non-null components to add.
467       * @param posn The index in this name at which to add the new
468       * components. Must be in the range [0,size()].
469       * @return The updated CompositeName, not a new one. Cannot be null.
470       * @exception InvalidNameException If n is not a composite name.
471       * @exception ArrayIndexOutOfBoundsException
472       * If posn is outside the specified range.
473       */

474     public Name JavaDoc addAll(int posn, Name JavaDoc n)
475     throws InvalidNameException JavaDoc
476     {
477     if (n instanceof CompositeName JavaDoc) {
478         impl.addAll(posn, n.getAll());
479         return this;
480     } else {
481         throw new InvalidNameException JavaDoc("Not a composite name: " +
482         n.toString());
483     }
484     }
485
486     /**
487       * Adds a single component to the end of this composite name.
488       *
489       * @param comp The non-null component to add.
490       * @return The updated CompositeName, not a new one. Cannot be null.
491       * @exception InvalidNameException If adding comp at end of the name
492       * would violate the name's syntax.
493       */

494     public Name JavaDoc add(String JavaDoc comp) throws InvalidNameException JavaDoc {
495     impl.add(comp);
496     return this;
497     }
498
499     /**
500       * Adds a single component at a specified position within this
501       * composite name.
502       * Components of this composite name at or after the index of the new
503       * component are shifted up by one (away from index 0) to accommodate
504       * the new component.
505       *
506       * @param comp The non-null component to add.
507       * @param posn The index at which to add the new component.
508       * Must be in the range [0,size()].
509       * @return The updated CompositeName, not a new one. Cannot be null.
510       * @exception ArrayIndexOutOfBoundsException
511       * If posn is outside the specified range.
512       * @exception InvalidNameException If adding comp at the specified position
513       * would violate the name's syntax.
514       */

515     public Name JavaDoc add(int posn, String JavaDoc comp)
516     throws InvalidNameException JavaDoc
517     {
518     impl.add(posn, comp);
519     return this;
520     }
521
522     /**
523       * Deletes a component from this composite name.
524       * The component of this composite name at position 'posn' is removed,
525       * and components at indices greater than 'posn'
526       * are shifted down (towards index 0) by one.
527       *
528       * @param posn The index of the component to delete.
529       * Must be in the range [0,size()).
530       * @return The component removed (a String).
531       * @exception ArrayIndexOutOfBoundsException
532       * If posn is outside the specified range (includes case where
533       * composite name is empty).
534       * @exception InvalidNameException If deleting the component
535       * would violate the name's syntax.
536       */

537     public Object JavaDoc remove(int posn) throws InvalidNameException JavaDoc{
538     return impl.remove(posn);
539     }
540
541     /**
542      * Overridden to avoid implementation dependency.
543      * @serialData The number of components (an <tt>int</tt>) followed by
544      * the individual components (each a <tt>String</tt>).
545      */

546     private void writeObject(java.io.ObjectOutputStream JavaDoc s)
547         throws java.io.IOException JavaDoc {
548     s.writeInt(size());
549     Enumeration JavaDoc comps = getAll();
550     while (comps.hasMoreElements()) {
551         s.writeObject(comps.nextElement());
552     }
553     }
554
555     /**
556      * Overridden to avoid implementation dependency.
557      */

558     private void readObject(java.io.ObjectInputStream JavaDoc s)
559         throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc {
560     impl = new NameImpl JavaDoc(null); // null means use default syntax
561
int n = s.readInt(); // number of components
562
try {
563         while (--n >= 0) {
564         add((String JavaDoc)s.readObject());
565         }
566     } catch (InvalidNameException JavaDoc e) {
567         throw (new java.io.StreamCorruptedException JavaDoc("Invalid name"));
568     }
569     }
570
571     /**
572      * Use serialVersionUID from JNDI 1.1.1 for interoperability
573      */

574     private static final long serialVersionUID = 1667768148915813118L;
575
576 /*
577     // %%% Test code for serialization.
578     public static void main(String[] args) throws Exception {
579     CompositeName c = new CompositeName("aaa/bbb");
580     java.io.FileOutputStream f1 = new java.io.FileOutputStream("/tmp/ser");
581     java.io.ObjectOutputStream s1 = new java.io.ObjectOutputStream(f1);
582     s1.writeObject(c);
583     s1.close();
584     java.io.FileInputStream f2 = new java.io.FileInputStream("/tmp/ser");
585     java.io.ObjectInputStream s2 = new java.io.ObjectInputStream(f2);
586     c = (CompositeName)s2.readObject();
587
588     System.out.println("Size: " + c.size());
589     System.out.println("Size: " + c.snit);
590     }
591 */

592
593 /*
594    %%% Testing code
595     public static void main(String[] args) {
596     try {
597         for (int i = 0; i < args.length; i++) {
598         Name name;
599         Enumeration e;
600         System.out.println("Given name: " + args[i]);
601         name = new CompositeName(args[i]);
602         e = name.getComponents();
603         while (e.hasMoreElements()) {
604             System.out.println("Element: " + e.nextElement());
605         }
606         System.out.println("Constructed name: " + name.toString());
607         }
608     } catch (Exception ne) {
609         ne.printStackTrace();
610     }
611     }
612 */

613 }
614
Popular Tags