KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > naming > ldap > LdapName


1 /*
2  * @(#)LdapName.java 1.7 04/06/21
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.ldap;
9
10 import javax.naming.Name JavaDoc;
11 import javax.naming.InvalidNameException JavaDoc;
12
13 import java.util.Enumeration JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.ListIterator JavaDoc;
19 import java.util.Collections JavaDoc;
20
21 import java.io.ObjectOutputStream JavaDoc;
22 import java.io.ObjectInputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24
25 /**
26  * This class represents a distinguished name as specified by
27  * <a HREF="http://ietf.org//rfc/rfc2253.txt">RFC 2253</a>.
28  * A distinguished name, or DN, is composed of an ordered list of
29  * components called <em>relative distinguished name</em>s, or RDNs.
30  * Details of a DN's syntax are described in RFC 2253.
31  *<p>
32  * This class resolves a few ambiguities found in RFC 2253
33  * as follows:
34  * <ul>
35  * <li> RFC 2253 leaves the term "whitespace" undefined. The
36  * ASCII space character 0x20 (" ") is used in its place.
37  * <li> Whitespace is allowed on either side of ',', ';', '=', and '+'.
38  * Such whitespace is accepted but not generated by this code,
39  * and is ignored when comparing names.
40  * <li> AttributeValue strings containing '=' or non-leading '#'
41  * characters (unescaped) are accepted.
42  * </ul>
43  *<p>
44  * String names passed to <code>LdapName</code> or returned by it
45  * use the full Unicode character set. They may also contain
46  * characters encoded into UTF-8 with each octet represented by a
47  * three-character substring such as "\\B4".
48  * They may not, however, contain characters encoded into UTF-8 with
49  * each octet represented by a single character in the string: the
50  * meaning would be ambiguous.
51  *<p>
52  * <code>LdapName</code> will properly parse all valid names, but
53  * does not attempt to detect all possible violations when parsing
54  * invalid names. It is "generous" in accepting invalid names.
55  * The "validity" of a name is determined ultimately when it
56  * is supplied to an LDAP server, which may accept or
57  * reject the name based on factors such as its schema information
58  * and interoperability considerations.
59  *<p>
60  * When names are tested for equality, attribute types, both binary
61  * and string values, are case-insensitive.
62  * String values with different but equivalent usage of quoting,
63  * escaping, or UTF8-hex-encoding are considered equal. The order of
64  * components in multi-valued RDNs (such as "ou=Sales+cn=Bob") is not
65  * significant.
66  * <p>
67  * The components of a LDAP name, that is, RDNs, are numbered. The
68  * indexes of a LDAP name with n RDNs range from 0 to n-1.
69  * This range may be written as [0,n).
70  * The right most RDN is at index 0, and the left most RDN is at
71  * index n-1. For example, the distinguished name:
72  * "CN=Steve Kille, O=Isode Limited, C=GB" is numbered in the following
73  * sequence ranging from 0 to 2: {C=GB, O=Isode Limited, CN=Steve Kille}. An
74  * empty LDAP name is represented by an empty RDN list.
75  *<p>
76  * Concurrent multithreaded read-only access of an instance of
77  * <tt>LdapName</tt> need not be synchronized.
78  *<p>
79  * Unless otherwise noted, the behavior of passing a null argument
80  * to a constructor or method in this class will cause a
81  * NullPointerException to be thrown.
82  *
83  * @author Scott Seligman
84  * @version 1.7 04/06/21
85  * @since 1.5
86  */

87
88 public class LdapName implements Name JavaDoc {
89
90     // private transient ArrayList<Rdn> rdns; // parsed name components
91

92     private transient ArrayList JavaDoc rdns; // parsed name components
93
private transient String JavaDoc unparsed; // if non-null, the DN in unparsed form
94
private static final long serialVersionUID = -1595520034788997356L;
95
96     /**
97      * Constructs an LDAP name from the given distinguished name.
98      *
99      * @param name This is a non-null distinguished name formatted
100      * according to the rules defined in
101      * <a HREF="http://ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
102      *
103      * @throws InvalidNameException if a syntax violation is detected.
104      * @see Rdn#escapeValue(Object value)
105      */

106     public LdapName(String JavaDoc name) throws InvalidNameException JavaDoc {
107     unparsed = name;
108     parse();
109     }
110
111     /**
112      * Constructs an LDAP name given its parsed RDN components.
113      * <p>
114      * The indexing of RDNs in the list follows the numbering of
115      * RDNs described in the class description.
116      *
117      * @param rdns The non-null list of <tt>Rdn</tt>s forming this LDAP name.
118      */

119     public LdapName(List JavaDoc<Rdn JavaDoc> rdns) {
120
121     // if (rdns instanceof ArrayList<Rdn>) {
122
// this.rdns = rdns.clone();
123
// } else if (rdns instanceof List<Rdn>) {
124
// this.rdns = new ArrayList<Rdn>(rdns);
125
// } else {
126
// throw IllegalArgumentException(
127
// "Invalid entries, list entries must be of type Rdn");
128
// }
129

130     this.rdns = new ArrayList JavaDoc(rdns.size());
131     for (int i = 0; i < rdns.size(); i++) {
132         Object JavaDoc obj = rdns.get(i);
133         if (!(obj instanceof Rdn JavaDoc)) {
134         throw new IllegalArgumentException JavaDoc("Entry:" + obj +
135             " not a valid type;list entries must be of type Rdn");
136         }
137         this.rdns.add(obj);
138     }
139     }
140
141     /*
142      * Constructs an LDAP name given its parsed components (the elements
143      * of "rdns" in the range [beg,end)) and, optionally
144      * (if "name" is not null), the unparsed DN.
145      *
146      */

147     // private LdapName(String name, List<Rdn> rdns, int beg, int end) {
148

149     private LdapName(String JavaDoc name, ArrayList JavaDoc rdns, int beg, int end) {
150     unparsed = name;
151     // this.rdns = rdns.subList(beg, end);
152

153     List JavaDoc sList = rdns.subList(beg, end);
154     this.rdns = new ArrayList JavaDoc(sList);
155     }
156
157     /**
158      * Retrieves the number of components in this LDAP name.
159      * @return The non-negative number of components in this LDAP name.
160      */

161     public int size() {
162     return rdns.size();
163     }
164
165     /**
166      * Determines whether this LDAP name is empty.
167      * An empty name is one with zero components.
168      * @return true if this LDAP name is empty, false otherwise.
169      */

170     public boolean isEmpty() {
171     return rdns.isEmpty();
172     }
173
174     /**
175      * Retrieves the components of this name as an enumeration
176      * of strings. The effect of updates to this name on this enumeration
177      * is undefined. If the name has zero components, an empty (non-null)
178      * enumeration is returned.
179      * The order of the components returned by the enumeration is same as
180      * the order in which the components are numbered as described in the
181      * class description.
182      *
183      * @return A non-null enumeration of the components of this LDAP name.
184      * Each element of the enumeration is of class String.
185      */

186     public Enumeration JavaDoc<String JavaDoc> getAll() {
187     final Iterator JavaDoc iter = rdns.iterator();
188
189     return new Enumeration JavaDoc<String JavaDoc>() {
190         public boolean hasMoreElements() {
191                 return iter.hasNext();
192             }
193             public String JavaDoc nextElement() {
194                 return iter.next().toString();
195             }
196         };
197     }
198
199     /**
200      * Retrieves a component of this LDAP name as a string.
201      * @param posn The 0-based index of the component to retrieve.
202      * Must be in the range [0,size()).
203      * @return The non-null component at index posn.
204      * @exception IndexOutOfBoundsException if posn is outside the
205      * specified range.
206      */

207     public String JavaDoc get(int posn) {
208     return rdns.get(posn).toString();
209     }
210
211     /**
212      * Retrieves an RDN of this LDAP name as an Rdn.
213      * @param posn The 0-based index of the RDN to retrieve.
214      * Must be in the range [0,size()).
215      * @return The non-null RDN at index posn.
216      * @exception IndexOutOfBoundsException if posn is outside the
217      * specified range.
218      */

219     public Rdn JavaDoc getRdn(int posn) {
220     return (Rdn JavaDoc) rdns.get(posn);
221     }
222
223     /**
224      * Creates a name whose components consist of a prefix of the
225      * components of this LDAP name.
226      * Subsequent changes to this name will not affect the name
227      * that is returned and vice versa.
228      * @param posn The 0-based index of the component at which to stop.
229      * Must be in the range [0,size()].
230      * @return An instance of <tt>LdapName</tt> consisting of the
231      * components at indexes in the range [0,posn).
232      * If posn is zero, an empty LDAP name is returned.
233      * @exception IndexOutOfBoundsException
234      * If posn is outside the specified range.
235      */

236     public Name JavaDoc getPrefix(int posn) {
237     try {
238         return new LdapName JavaDoc(null, rdns, 0, posn);
239     } catch (IllegalArgumentException JavaDoc e) {
240         throw new IndexOutOfBoundsException JavaDoc(
241         "Posn: " + posn + ", Size: "+ rdns.size());
242     }
243     }
244
245     /**
246      * Creates a name whose components consist of a suffix of the
247      * components in this LDAP name.
248      * Subsequent changes to this name do not affect the name that is
249      * returned and vice versa.
250      *
251      * @param posn The 0-based index of the component at which to start.
252      * Must be in the range [0,size()].
253      * @return An instance of <tt>LdapName</tt> consisting of the
254      * components at indexes in the range [posn,size()).
255      * If posn is equal to size(), an empty LDAP name is
256      * returned.
257      * @exception IndexOutOfBoundsException
258      * If posn is outside the specified range.
259      */

260     public Name JavaDoc getSuffix(int posn) {
261     try {
262         return new LdapName JavaDoc(null, rdns, posn, rdns.size());
263     } catch (IllegalArgumentException JavaDoc e) {
264         throw new IndexOutOfBoundsException JavaDoc(
265         "Posn: " + posn + ", Size: "+ rdns.size());
266     }
267     }
268
269     /**
270      * Determines whether this LDAP name starts with a specified LDAP name
271      * prefix.
272      * A name <tt>n</tt> is a prefix if it is equal to
273      * <tt>getPrefix(n.size())</tt>--in other words this LDAP
274      * name starts with 'n'. If n is null or not a RFC2253 formatted name
275      * as described in the class description, false is returned.
276      *
277      * @param n The LDAP name to check.
278      * @return true if <tt>n</tt> is a prefix of this LDAP name,
279      * false otherwise.
280      * @see #getPrefix(int posn)
281      */

282     public boolean startsWith(Name JavaDoc n) {
283     if (n == null) {
284         return false;
285     }
286     int len1 = rdns.size();
287         int len2 = n.size();
288         return (len1 >= len2 &&
289                 matches(0, len2, n));
290     }
291
292     /**
293      * Determines whether the specified RDN sequence forms a prefix of this
294      * LDAP name. Returns true if this LdapName is at least as long as rdns,
295      * and for every position p in the range [0, rdns.size()) the component
296      * getRdn(p) matches rdns.get(p). Returns false otherwise. If rdns is
297      * null, false is returned.
298      *
299      * @param rdns The sequence of <tt>Rdn</tt>s to check.
300      * @return true if <tt>rdns</tt> form a prefix of this LDAP name,
301      * false otherwise.
302      */

303     public boolean startsWith(List JavaDoc<Rdn JavaDoc> rdns) {
304     if (rdns == null) {
305         return false;
306     }
307     int len1 = this.rdns.size();
308         int len2 = rdns.size();
309         return (len1 >= len2 &&
310                 doesListMatch(0, len2, rdns));
311     }
312
313     /**
314      * Determines whether this LDAP name ends with a specified
315      * LDAP name suffix.
316      * A name <tt>n</tt> is a suffix if it is equal to
317      * <tt>getSuffix(size()-n.size())</tt>--in other words this LDAP
318      * name ends with 'n'. If n is null or not a RFC2253 formatted name
319      * as described in the class description, false is returned.
320      *
321      * @param n The LDAP name to check.
322      * @return true if <tt>n</tt> is a suffix of this name, false otherwise.
323      * @see #getSuffix(int posn)
324      */

325     public boolean endsWith(Name JavaDoc n) {
326     if (n == null) {
327         return false;
328     }
329     int len1 = rdns.size();
330         int len2 = n.size();
331         return (len1 >= len2 &&
332                 matches(len1 - len2, len1, n));
333     }
334
335     /**
336      * Determines whether the specified RDN sequence forms a suffix of this
337      * LDAP name. Returns true if this LdapName is at least as long as rdns,
338      * and for every position p in the range [size() - rdns.size(), size())
339      * the component getRdn(p) matches rdns.get(p). Returns false otherwise.
340      * If rdns is null, false is returned.
341      *
342      * @param rdns The sequence of <tt>Rdn</tt>s to check.
343      * @return true if <tt>rdns</tt> form a suffix of this LDAP name,
344      * false otherwise.
345      */

346     public boolean endsWith(List JavaDoc<Rdn JavaDoc> rdns) {
347     if (rdns == null) {
348         return false;
349     }
350     int len1 = this.rdns.size();
351         int len2 = rdns.size();
352         return (len1 >= len2 &&
353                 doesListMatch(len1 - len2, len1, rdns));
354     }
355
356     private boolean doesListMatch(int beg, int end, List JavaDoc rdns) {
357     for (int i = beg; i < end; i++) {
358         if (!this.rdns.get(i).equals(rdns.get(i - beg))) {
359         return false;
360         }
361     }
362     return true;
363     }
364
365     /*
366      * Helper method for startsWith() and endsWith().
367      * Returns true if components [beg,end) match the components of "n".
368      * If "n" is not an LdapName, each of its components is parsed as
369      * the string form of an RDN.
370      * The following must hold: end - beg == n.size().
371      */

372     private boolean matches(int beg, int end, Name JavaDoc n) {
373     if (n instanceof LdapName JavaDoc) {
374         LdapName JavaDoc ln = (LdapName JavaDoc) n;
375         return doesListMatch(beg, end, ln.rdns);
376     } else {
377         for (int i = beg; i < end; i++) {
378         Rdn JavaDoc rdn;
379         String JavaDoc rdnString = n.get(i - beg);
380                 try {
381                     rdn = (new Rfc2253Parser JavaDoc(rdnString)).parseRdn();
382                 } catch (InvalidNameException JavaDoc e) {
383                     return false;
384                 }
385         if (!rdn.equals(rdns.get(i))) {
386                     return false;
387                 }
388         }
389     }
390     return true;
391     }
392
393     /**
394      * Adds the components of a name -- in order -- to the end of this name.
395      *
396      * @param suffix The non-null components to add.
397      * @return The updated name (not a new instance).
398      *
399      * @throws InvalidNameException if <tt>suffix</tt> is not a valid LDAP
400      * name, or if the addition of the components would violate the
401      * syntax rules of this LDAP name.
402      */

403     public Name JavaDoc addAll(Name JavaDoc suffix) throws InvalidNameException JavaDoc {
404      return addAll(size(), suffix);
405     }
406
407
408     /**
409      * Adds the RDNs of a name -- in order -- to the end of this name.
410      *
411      * @param suffixRdns The non-null suffix <tt>Rdn</tt>s to add.
412      * @return The updated name (not a new instance).
413      */

414     public Name JavaDoc addAll(List JavaDoc<Rdn JavaDoc> suffixRdns) {
415     return addAll(size(), suffixRdns);
416     }
417
418     /**
419      * Adds the components of a name -- in order -- at a specified position
420      * within this name. Components of this LDAP name at or after the
421      * index (if any) of the first new component are shifted up
422      * (away from index 0) to accomodate the new components.
423      *
424      * @param suffix The non-null components to add.
425      * @param posn The index at which to add the new component.
426      * Must be in the range [0,size()].
427      *
428      * @return The updated name (not a new instance).
429      *
430      * @throws InvalidNameException if <tt>suffix</tt> is not a valid LDAP
431      * name, or if the addition of the components would violate the
432      * syntax rules of this LDAP name.
433      * @throws IndexOutOfBoundsException.
434      * If posn is outside the specified range.
435      */

436     public Name JavaDoc addAll(int posn, Name JavaDoc suffix)
437     throws InvalidNameException JavaDoc {
438         unparsed = null; // no longer valid
439
if (suffix instanceof LdapName JavaDoc) {
440             LdapName JavaDoc s = (LdapName JavaDoc) suffix;
441             rdns.addAll(posn, s.rdns);
442         } else {
443         Enumeration JavaDoc comps = suffix.getAll();
444             while (comps.hasMoreElements()) {
445         rdns.add(posn++,
446             (new Rfc2253Parser JavaDoc((String JavaDoc) comps.nextElement()).
447             parseRdn()));
448             }
449         }
450         return this;
451     }
452
453     /**
454      * Adds the RDNs of a name -- in order -- at a specified position
455      * within this name. RDNs of this LDAP name at or after the
456      * index (if any) of the first new RDN are shifted up (away from index 0) to
457      * accomodate the new RDNs.
458      *
459      * @param suffixRdns The non-null suffix <tt>Rdn</tt>s to add.
460      * @param posn The index at which to add the suffix RDNs.
461      * Must be in the range [0,size()].
462      *
463      * @return The updated name (not a new instance).
464      * @throws IndexOutOfBoundsException.
465      * If posn is outside the specified range.
466      */

467     public Name JavaDoc addAll(int posn, List JavaDoc<Rdn JavaDoc> suffixRdns) {
468     unparsed = null;
469     for (int i = 0; i < suffixRdns.size(); i++) {
470         Object JavaDoc obj = suffixRdns.get(i);
471         if (!(obj instanceof Rdn JavaDoc)) {
472         throw new IllegalArgumentException JavaDoc("Entry:" + obj +
473         " not a valid type;suffix list entries must be of type Rdn");
474         }
475         rdns.add(i + posn, obj);
476     }
477         return this;
478     }
479
480     /**
481      * Adds a single component to the end of this LDAP name.
482      *
483      * @param comp The non-null component to add.
484      * @return The updated LdapName, not a new instance.
485      * Cannot be null.
486      * @exception InvalidNameException If adding comp at end of the name
487      * would violate the name's syntax.
488      */

489     public Name JavaDoc add(String JavaDoc comp) throws InvalidNameException JavaDoc {
490     return add(size(), comp);
491     }
492
493     /**
494      * Adds a single RDN to the end of this LDAP name.
495      *
496      * @param comp The non-null RDN to add.
497      *
498      * @return The updated LdapName, not a new instance.
499      * Cannot be null.
500      */

501     public Name JavaDoc add(Rdn JavaDoc comp) {
502     return add(size(), comp);
503     }
504
505     /**
506      * Adds a single component at a specified position within this
507      * LDAP name.
508      * Components of this LDAP name at or after the index (if any) of the new
509      * component are shifted up by one (away from index 0) to accommodate
510      * the new component.
511      *
512      * @param comp The non-null component to add.
513      * @param posn The index at which to add the new component.
514      * Must be in the range [0,size()].
515      * @return The updated LdapName, not a new instance.
516      * Cannot be null.
517      * @exception IndexOutOfBoundsException.
518      * If posn is outside the specified range.
519      * @exception InvalidNameException If adding comp at the
520      * specified position would violate the name's syntax.
521      */

522     public Name JavaDoc add(int posn, String JavaDoc comp) throws InvalidNameException JavaDoc {
523     Rdn JavaDoc rdn = (new Rfc2253Parser JavaDoc(comp)).parseRdn();
524         rdns.add(posn, rdn);
525         unparsed = null; // no longer valid
526
return this;
527     }
528
529     /**
530      * Adds a single RDN at a specified position within this
531      * LDAP name.
532      * RDNs of this LDAP name at or after the index (if any) of the new
533      * RDN are shifted up by one (away from index 0) to accommodate
534      * the new RDN.
535      *
536      * @param comp The non-null RDN to add.
537      * @param posn The index at which to add the new RDN.
538      * Must be in the range [0,size()].
539      * @return The updated LdapName, not a new instance.
540      * Cannot be null.
541      * @exception IndexOutOfBoundsException
542      * If posn is outside the specified range.
543      */

544     public Name JavaDoc add(int posn, Rdn JavaDoc comp) {
545     if (comp == null) {
546         throw new NullPointerException JavaDoc("Cannot set comp to null");
547     }
548     rdns.add(posn, comp);
549         unparsed = null; // no longer valid
550
return this;
551     }
552
553     /**
554      * Removes a component from this LDAP name.
555      * The component of this name at the specified position is removed.
556      * Components with indexes greater than this position (if any)
557      * are shifted down (toward index 0) by one.
558      *
559      * @param posn The index of the component to remove.
560      * Must be in the range [0,size()).
561      * @return The component removed (a String).
562      *
563      * @throws IndexOutOfBoundsException
564      * if posn is outside the specified range.
565      * @throws InvalidNameException if deleting the component
566      * would violate the syntax rules of the name.
567      */

568     public Object JavaDoc remove(int posn) throws InvalidNameException JavaDoc {
569     unparsed = null; // no longer valid
570
return rdns.remove(posn).toString();
571     }
572
573     /**
574      * Retrieves the list of relative distinguished names.
575      * The contents of the list are unmodifiable.
576      * The indexing of RDNs in the returned list follows the numbering of
577      * RDNs as described in the class description.
578      * If the name has zero components, an empty list is returned.
579      *
580      * @return The name as a list of RDNs which are instances of
581      * the class {@link Rdn Rdn}.
582      */

583     public List JavaDoc<Rdn JavaDoc> getRdns() {
584     return Collections.unmodifiableList(rdns);
585     }
586
587     /**
588      * Generates a new copy of this name.
589      * Subsequent changes to the components of this name will not
590      * affect the new copy, and vice versa.
591      *
592      * @return A copy of the this LDAP name.
593      */

594     public Object JavaDoc clone() {
595     return new LdapName JavaDoc(unparsed, rdns, 0, rdns.size());
596     }
597
598     /**
599      * Returns a string representation of this LDAP name in a format
600      * defined by <a HREF="http://ietf.org/rfc/rfc2253.txt">RFC 2253</a>
601      * and described in the class description. If the name has zero
602      * components an empty string is returned.
603      *
604      * @return The string representation of the LdapName.
605      */

606     public String JavaDoc toString() {
607     if (unparsed != null) {
608         return unparsed;
609     }
610     StringBuilder JavaDoc builder = new StringBuilder JavaDoc();
611     int size = rdns.size();
612     if ((size - 1) >= 0) {
613         builder.append((Rdn JavaDoc) rdns.get(size - 1));
614     }
615     for (int next = size - 2; next >= 0; next--) {
616         builder.append(',');
617         builder.append((Rdn JavaDoc) rdns.get(next));
618     }
619     unparsed = builder.toString();
620     return unparsed;
621     }
622
623     /**
624      * Determines whether two LDAP names are equal.
625      * If obj is null or not an LDAP name, false is returned.
626      * <p>
627      * Two LDAP names are equal if each RDN in one is equal
628      * to the corresponding RDN in the other. This implies
629      * both have the same number of RDNs, and each RDN's
630      * equals() test against the corresponding RDN in the other
631      * name returns true. See {@link Rdn#equals(Object obj)}
632      * for a definition of RDN equality.
633      *
634      * @param obj The possibly null object to compare against.
635      * @return true if obj is equal to this LDAP name,
636      * false otherwise.
637      * @see #hashCode
638      */

639     public boolean equals(Object JavaDoc obj) {
640     // check possible shortcuts
641
if (obj == this) {
642         return true;
643     }
644     if (!(obj instanceof LdapName JavaDoc)) {
645         return false;
646     }
647     LdapName JavaDoc that = (LdapName JavaDoc) obj;
648     if (rdns.size() != that.rdns.size()) {
649         return false;
650     }
651     if (unparsed != null && unparsed.equalsIgnoreCase(
652         that.unparsed)) {
653         return true;
654     }
655     // Compare RDNs one by one for equality
656
for (int i = 0; i < rdns.size(); i++) {
657         // Compare a single pair of RDNs.
658
Rdn JavaDoc rdn1 = (Rdn JavaDoc) rdns.get(i);
659         Rdn JavaDoc rdn2 = (Rdn JavaDoc) that.rdns.get(i);
660         if (!rdn1.equals(rdn2)) {
661         return false;
662         }
663     }
664     return true;
665     }
666
667     /**
668      * Compares this LdapName with the specified Object for order.
669      * Returns a negative integer, zero, or a positive integer as this
670      * Name is less than, equal to, or greater than the given Object.
671      * <p>
672      * If obj is null or not an instance of LdapName, ClassCastException
673      * is thrown.
674      * <p>
675      * Ordering of LDAP names follows the lexicographical rules for
676      * string comparison, with the extension that this applies to all
677      * the RDNs in the LDAP name. All the RDNs are lined up in their
678      * specified order and compared lexicographically.
679      * See {@link Rdn#compareTo(Object obj) Rdn.compareTo(Object obj)}
680      * for RDN comparison rules.
681      * <p>
682      * If this LDAP name is lexicographically lesser than obj,
683      * a negative number is returned.
684      * If this LDAP name is lexicographically greater than obj,
685      * a positive number is returned.
686      * @param obj The non-null LdapName instance to compare against.
687      *
688      * @return A negative integer, zero, or a positive integer as this Name
689      * is less than, equal to, or greater than the given obj.
690      * @exception ClassCastException if obj is null or not a LdapName.
691      */

692     public int compareTo(Object JavaDoc obj) {
693
694     if (!(obj instanceof LdapName JavaDoc)) {
695             throw new ClassCastException JavaDoc("The obj is not a LdapName");
696         }
697
698     // check possible shortcuts
699
if (obj == this) {
700         return 0;
701     }
702     LdapName JavaDoc that = (LdapName JavaDoc) obj;
703
704     if (unparsed != null && unparsed.equalsIgnoreCase(
705             that.unparsed)) {
706         return 0;
707     }
708
709     // Compare RDNs one by one, lexicographically.
710
int minSize = Math.min(rdns.size(), that.rdns.size());
711     for (int i = 0; i < minSize; i++) {
712         // Compare a single pair of RDNs.
713
Rdn JavaDoc rdn1 = (Rdn JavaDoc)rdns.get(i);
714         Rdn JavaDoc rdn2 = (Rdn JavaDoc)that.rdns.get(i);
715
716         int diff = rdn1.compareTo(rdn2);
717         if (diff != 0) {
718         return diff;
719         }
720     }
721     return (rdns.size() - that.rdns.size()); // longer DN wins
722
}
723
724     /**
725      * Computes the hash code of this LDAP name.
726      * The hash code is the sum of the hash codes of individual RDNs
727      * of this name.
728      *
729      * @return An int representing the hash code of this name.
730      * @see #equals
731      */

732     public int hashCode() {
733     // Sum up the hash codes of the components.
734
int hash = 0;
735
736     // For each RDN...
737
for (int i = 0; i < rdns.size(); i++) {
738         Rdn JavaDoc rdn = (Rdn JavaDoc) rdns.get(i);
739         hash += rdn.hashCode();
740     }
741     return hash;
742     }
743
744     /**
745      * Serializes only the unparsed DN, for compactness and to avoid
746      * any implementation dependency.
747      *
748      * @serialData The DN string
749      */

750     private void writeObject(ObjectOutputStream JavaDoc s)
751             throws java.io.IOException JavaDoc {
752     s.defaultWriteObject();
753         s.writeObject(toString());
754     }
755
756     private void readObject(ObjectInputStream JavaDoc s)
757             throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc {
758     s.defaultReadObject();
759         unparsed = (String JavaDoc)s.readObject();
760         try {
761             parse();
762         } catch (InvalidNameException JavaDoc e) {
763             // shouldn't happen
764
throw new java.io.StreamCorruptedException JavaDoc(
765                     "Invalid name: " + unparsed);
766     }
767     }
768
769     private void parse() throws InvalidNameException JavaDoc {
770     // rdns = (ArrayList<Rdn>) (new RFC2253Parser(unparsed)).getDN();
771

772     rdns = (ArrayList JavaDoc) (new Rfc2253Parser JavaDoc(unparsed)).parseDn();
773     }
774 }
775
Popular Tags