KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ca > commons > naming > RDN


1 package com.ca.commons.naming;
2
3 //import java.util.Vector;
4

5 //import com.ca.commons.cbutil.*;
6

7 import javax.naming.InvalidNameException JavaDoc;
8
9 /**
10  * An RDN element. May be multi-valued (but most aren't)<p>
11  *
12  * Some quick definitions: <ul>
13  * <li>'raw' means an rdn with unescaped special
14  * characters in it, suitable for display to a user - cn=fred+nurk.
15  * <li>'escaped' means with special characters escaped in a form suitable
16  * for jndi transmission (leading '\' characters, and quad slashes '\\\\' for
17  * an escaped slash.
18  * <li>'jndireturn' means an incorrectly escaped string from a jndi query
19  * which requires special handling due to bugs (?) in jndi (as of java 1.3)
20  * </ul>
21  * Values are entered and stored in the RDN <i>escaped</i>, in an internal
22  * string ldapEscapedRDN. Utility ftns
23  * are provided to translate rdns between these different forms, and functions
24  * creating/changing rdns should make sure always to pass the final (no escape
25  * character) form when using RDNs.<p>
26  *
27  * While parts of an rdn (particular attributes and values) may be manipulated
28  * as raw, unescaped strings, entire rdns are always escaped when represented
29  * as strings (e.g. by the 'toString()' method).<p>
30  *
31  * An added complication is unicode. While strings may be entered as escaped
32  * utf8, they are always converted to unicode asap, and never returned as utf8.
33  * (they are automatically translated to utf8 by jndi when transmitted to the
34  * server, or manually by JXplorer when saving ldif files as a final step).
35  *
36  * <p>The class is optimised for single valued RDNs, as this represents the
37  * majority of examples seen by the author...</p>
38  *
39  * <p>This class uses delayed evaluation of RDN strings. Hence invalid RDNs
40  * can be instantiated, and will only throw exceptions when used.</p>
41  *
42  * @author Chris Betts
43  */

44
45 public class RDN
46 {
47     /**
48      * <p>This gives the positions of seperators ('+') or '1 past the end of string'
49      * for att-value sub elements in a multi-valued rdn. The first element is
50      * always -1, the last is the length of the string.
51      * Usually length 2, since most RDNs are
52      * not multivalued.</p>
53      *
54      * <pre>
55      * cn=Sue\,Grabbit\+Run+sn=Law (27 characters)
56      * ^ ^ ^
57      * | | |
58      * -1 20 27
59      * [0] [1] [2]
60      * </pre>
61      *
62      * Any rdn sub string (i) is thus element[i]+1 to element[i+1]
63      */

64
65     private int[] elements = null;
66
67     /**
68      * The escaped ldap RDN (e.g. cn=Sue\,Grabbit\+Run+sn=Law)
69      */

70
71     private String JavaDoc ldapEscapedRDN;
72
73
74     /**
75      * status constants of the RDN - whether it has been tested,
76      * and if it has, whether it is single valued or multi valued.
77      */

78
79     private int UNTESTED = 0, SINGLEVALUED = 1, MULTIVALUED = 2;
80
81     /**
82      * the status of the RDN (one of UNTESTED|SINGLEVALUED|MULTIVALUED)
83      */

84
85     private int status = UNTESTED;
86
87     /**
88      * Default number of allowable elements (before a manual array resize
89      * must be done).
90      */

91
92     private static int MAXELEMENTS = 16; // maximum number of multi-valued attributes...
93

94     /**
95      * Empty constructor - creates an RDN with no values.
96      */

97
98     public RDN() { ldapEscapedRDN = "";}
99
100
101     private boolean debug = false;
102
103     /**
104      * Standard constructor - creates an RDN using an ldap escaped utf8
105      * rdn string, which may be multi-valued.
106      * @param rdn the string rdn to be parsed
107      */

108
109
110
111     public RDN(String JavaDoc rdn)
112     {
113         if (rdn == null)
114         {
115             rdn = "";
116         }
117         else
118         {
119             // trim any unnecessary white space off the end...
120
int len = rdn.length();
121
122             if ((rdn.indexOf('\\') > -1) && (len >=2 && rdn.charAt(len-2) == '\\' && rdn.charAt(len-1) == ' '))
123             {
124                     rdn = specialSpaceHandling(rdn); // pathalogical case
125
}
126             else
127                 rdn = rdn.trim();
128         }
129
130         ldapEscapedRDN = rdn;
131
132         if (debug) System.out.println(" % NEW RDN: " + rdn);
133     }
134
135     /**
136      * clones an RDN.
137      * @param copyMe the RDN to copy.
138      */

139
140     public RDN(RDN copyMe)
141     {
142         this(copyMe.ldapEscapedRDN);
143     }
144
145     /**
146      * This RDN may have a special escaped space on the end...
147      * this method handles this (rare) case and cleans up the rdn
148      * in a process that takes a bit longer than normal.
149      */

150
151     // XXX this is kinda messy, and only works for single valued RDNs.. Can we come up with a nicer algorithm?
152

153     private String JavaDoc specialSpaceHandling(String JavaDoc rdn)
154     {
155         // count the slashes...
156

157         int finalPos = rdn.length() - 2;
158         int pos = finalPos;
159
160         // work backwards from the second last position, deleting slashes
161

162         while (rdn.charAt(pos) == '\\') // remember '\\' is a *single* slash!
163
{
164             pos--;
165         }
166
167         int numSlashesDeleted = finalPos - pos;
168
169         int valuePos = rdn.indexOf('=')+1;
170         String JavaDoc att = rdn.substring(0, valuePos);
171         String JavaDoc val = rdn.substring(valuePos);
172
173         if (numSlashesDeleted%2 == 0) // o.k. - we can trim that pesky space
174
{
175             val = val.trim();
176         } // (otherwise leave it alone, it's
177
else // escaped and meant to be there) - so
178
{ // just get rid of leading spaces...
179
val = val.trim() + " ";
180         }
181
182         rdn = att + val;
183
184         return rdn;
185     }
186
187     /**
188      * Whether the rdn is empty (i.e. is an empty string)
189      */

190
191     public boolean isEmpty()
192     {
193         return ("".equals(ldapEscapedRDN));
194     }
195
196     /**
197      * adds an ldap escaped utf8 Name element (i.e. the portion of an rdn separated by a '+' sign)
198      * @param rdnfragment an attribute = value pair.
199      */

200
201     public void addEscaped(String JavaDoc rdnfragment)
202                  throws InvalidNameException JavaDoc
203     {
204         validate(); // throws InvalidNameException
205

206         int equalpos = NameUtility.next(rdnfragment, 0, '=');
207         // check rdn has at least one non null attribute and one non null value
208

209         if (equalpos <= 0 || equalpos == rdnfragment.length()-1)
210             throw new InvalidNameException JavaDoc("RDN.add(): invalid rdn fragment '" + ((rdnfragment==null)?"<null>":rdnfragment) + "' (can't find equal sign)");
211
212         if (ldapEscapedRDN.length()>0)
213             ldapEscapedRDN += "+" + rdnfragment;
214         else
215             ldapEscapedRDN = rdnfragment;
216
217     }
218
219     /**
220      * adds an unescaped unicode Name element (i.e. one of the parts seperated by a '+' sign).
221      * This will fail on multi-part elements (e.g. cn="fred" will work, cn="fred"+sn="erick" won't).
222      * XXX - this escapes the equals sign?
223      * @param rdnfragment an attribute = value pair.
224      */

225
226     public void addRaw(String JavaDoc rdnfragment)
227                  throws InvalidNameException JavaDoc
228     {
229         int equalpos = NameUtility.next(rdnfragment, 0, '=');
230         // check rdn has at least one non null attribute and one non null value
231

232         if (equalpos <= 0 || equalpos == rdnfragment.length()-1)
233             throw new InvalidNameException JavaDoc("RDN.addRaw(): invalid rdn fragment '" + ((rdnfragment==null)?"<null>":rdnfragment) + "' (can't find equal sign)");
234
235         String JavaDoc attribute = rdnfragment.substring(0, equalpos);
236         String JavaDoc value = rdnfragment.substring(equalpos+1);
237
238         addEscaped(attribute + "=" + NameUtility.escape(value));
239     }
240
241
242     /**
243      * Returns the RDN as an ldap escaped ldap utf8 string.
244      * (This is a very inexpensive operation - it simply
245      * returns the pre-existing string.)
246      * @return the internal representation of the RDN as an ldap escaped string.
247      */

248
249     public String JavaDoc toString()
250     {
251         return ldapEscapedRDN;
252     }
253
254     /**
255      * Debug prints the raw, unescaped form of the elements.
256      */

257
258     public void dump()
259     {
260         if (status == UNTESTED)
261             checkForMultiValued();
262
263         System.out.println("DEBUG DUMP - RDN: " + ldapEscapedRDN + ((status==MULTIVALUED)?" MULTI VALUED":" SINGLE VALUED"));
264
265         if (status == MULTIVALUED)
266         {
267             for (int i=0; i<(elements.length - 1); i++)
268             {
269                 System.out.println("element-m (" + (elements[i]+1) + ") -> (" + elements[i+1] + ") " + i + ": " + getElement(i));
270             }
271         }
272         else
273         {
274             System.out.println("element-s 0: " + ldapEscapedRDN);
275         }
276
277         Thread.currentThread().dumpStack();
278
279     }
280
281     /**
282      * Returns the Ith att-val pair in escaped ldap form.
283      * @param i the element index to get (counting from 0)
284      * @return the attribute value pair.
285      */

286
287     public String JavaDoc getElement(int i)
288     {
289         if (status == UNTESTED)
290             checkForMultiValued();
291
292         if (status == SINGLEVALUED && i==0)
293             return ldapEscapedRDN;
294
295         if (i<0 || elements == null || elements.length <= i+1)
296             return "error VII";
297
298         return ldapEscapedRDN.substring(elements[i]+1, elements[i+1]);
299     }
300
301     /**
302      * Returns all elements as a string array, in escaped ldap form.
303      */

304
305     public String JavaDoc[] getElements()
306     {
307         if (status == UNTESTED)
308             checkForMultiValued();
309
310         if (status == SINGLEVALUED)
311             return new String JavaDoc[] {ldapEscapedRDN};
312
313         if (elements == null)
314             return new String JavaDoc[] {"error VIIB"};
315
316         String JavaDoc[] elementArray = new String JavaDoc[elements.length-1];
317
318         for (int i=0; i<(elements.length-1); i++)
319             elementArray[i] = ldapEscapedRDN.substring(elements[i]+1, elements[i+1]);
320
321         return elementArray;
322     }
323
324     /**
325      * Sets the Ith att-val pair in escaped ldap form.
326      * @param i the element index to get (counting from 0)
327      * @param ldapEscapedElement the element to replace (if the
328      * rdn is single valued, this would be the whole rdn.)
329      */

330
331     public void setElement(int i, String JavaDoc ldapEscapedElement)
332         throws InvalidNameException JavaDoc
333     {
334         validate();
335
336         if (status == SINGLEVALUED)
337         {
338             if (i==0)
339                 ldapEscapedRDN = ldapEscapedElement;
340             else
341                 throw new InvalidNameException JavaDoc("cannot set non zero element of single valued rdn.");
342         }
343         else
344         {
345             if (i < 0 || i >= size())
346                 throw new InvalidNameException JavaDoc("attempt to set element " + i + " of rdn: '" + ldapEscapedRDN + "' (size = " + size() + ")");
347
348             ldapEscapedRDN = ldapEscapedRDN.substring(0, elements[i]+1) +
349                              ldapEscapedElement +
350                              ldapEscapedRDN.substring(elements[i+1]);
351
352             parseMultiValued();
353
354         }
355     }
356
357
358
359     /**
360      * Gets the first attribute name.
361      */

362
363     public String JavaDoc getAtt()
364     {
365         return getAtt(0);
366     }
367
368     /**
369      * gets the attribute name from a particular indexed rdn element.
370      */

371
372     public String JavaDoc getAtt(int i)
373     {
374         if (status == UNTESTED)
375             checkForMultiValued();
376
377         if (status == SINGLEVALUED && i!=0)
378             return "rdn error VIII";
379
380         String JavaDoc element = getElement(i);
381
382         int pos = element.indexOf('='); // no need for escape check, since att must be unescaped always.
383

384         if (pos == -1) return "rdn error IX";
385
386 if (debug)
387 {
388     System.out.println("Debug = " + debug);
389     Thread.currentThread().dumpStack();
390     System.out.println(" % RDN -> found attribute as '" + element.substring(0,pos) + "'");
391 }
392
393         return element.substring(0, pos);
394     }
395
396     /**
397      * gets the attribute type names as a String array.
398      * @return an array of attribute types as a string; e.g. {'cn', 'uid'}
399      */

400
401     public String JavaDoc[] getAtts()
402     {
403         if (status == UNTESTED)
404             checkForMultiValued();
405
406         String JavaDoc[] atts = getElements();
407
408         for (int i=0; i<atts.length; i++)
409         {
410             int pos = atts[i].indexOf('='); // no need for escape check, since att must be unescaped always.
411

412             if (pos == -1) return new String JavaDoc[] {"rdn error IXB"};
413
414             atts[i] = atts[i].substring(0, pos);
415         }
416
417         return atts;
418     }
419
420
421
422
423     /**
424      * Utility function - returns true if the passed attribute value
425      * is contained within the RDN. This is case insensitive.
426      *
427      * @param attributeType the Attribute name (e.g. "cn") to search for.
428      * @return true if it exists in the RDN, false if not.
429      */

430
431     public boolean contains(String JavaDoc attributeType)
432     {
433         if (status == UNTESTED)
434             checkForMultiValued();
435
436         if (attributeType == null || attributeType.length()==0)
437             return false;
438
439         for (int i=0; i<size(); i++)
440             if (attributeType.equalsIgnoreCase(getAtt(i)))
441                 return true;
442
443         return false;
444     }
445
446     /**
447      * Utility function - returns a raw attribute value looked up
448      * by name. This search is case insensitive. Note that this
449      * class is not optimized for this function .
450      *
451      * @param attributeType the attribute type to find the corresponding
452      * value for (e.g. "cn").
453      * @return String the corresponding value (e.g. "Fred"), or null
454      * if there is no such value.
455      */

456
457     public String JavaDoc getRawVal(String JavaDoc attributeType)
458     {
459         if (status == UNTESTED)
460             checkForMultiValued();
461
462         if (attributeType == null || attributeType.length()==0)
463             return null;
464
465         for (int i=0; i<size(); i++)
466             if (attributeType.equalsIgnoreCase(getAtt(i)))
467                 return getRawVal(i);
468
469         return null;
470
471     }
472
473     /**
474      * Gets the first raw, unescaped, attribute value.
475      */

476
477     public String JavaDoc getRawVal()
478     {
479         return getRawVal(0);
480     }
481
482     /**
483      * gets the raw, unescaped, attribute value from a particular indexed rdn element.
484      */

485
486     public String JavaDoc getRawVal(int i)
487     {
488         if (status == UNTESTED)
489             checkForMultiValued();
490
491         if (status == SINGLEVALUED && i!=0)
492             return "rdn error X";
493
494         String JavaDoc element = getElement(i);
495
496         int pos = element.indexOf('='); // no need for escape check, since att must be unescaped always.
497

498         if (pos == -1)
499         {
500             return "rdn error XI";
501         }
502
503         String JavaDoc raw = element.substring(pos+1);
504
505         // since the value may be escaped, try to unescape it...
506
try
507         {
508             return NameUtility.unescape(raw);
509         }
510         catch (Exception JavaDoc e)
511         {
512             return "rdn error XII";
513         }
514     }
515
516     /**
517      * gets the attribute values as a String array.
518      * @return an array of attribute types as a string; e.g. {'cn', 'uid'}
519      */

520
521     public String JavaDoc[] getRawVals()
522     {
523         if (status == UNTESTED)
524             checkForMultiValued();
525
526         String JavaDoc[] vals = getElements();
527
528         for (int i=0; i<vals.length; i++)
529         {
530             vals[i] = getRawVal(i);
531         }
532
533         return vals;
534     }
535
536
537
538     /**
539      * Sets the raw, unescaped value of uni-valued rdn.
540      */

541
542     public void setRawVal(String JavaDoc v)
543         throws InvalidNameException JavaDoc
544     {
545         setRawVal(v, 0);
546     }
547
548     /**
549      * sets a raw, unescaped, value at a particular index position.
550      */

551
552     public void setRawVal(String JavaDoc v, int i)
553         throws InvalidNameException JavaDoc
554     {
555         validate();
556
557         String JavaDoc attval = getElement(i);
558         String JavaDoc att = attval.substring(0, attval.indexOf('='));
559         if (att == null || att.length()==0)
560             throw new InvalidNameException JavaDoc("can't parse old RDN '" + ldapEscapedRDN);
561
562         String JavaDoc newElement = att + "=" + NameUtility.escape(v);
563         setElement(i, newElement);
564     }
565
566     /**
567      * returns the number of sub-elements in this rdn. (usually one!)
568      */

569
570     public int size()
571     {
572         if (status == UNTESTED)
573             checkForMultiValued();
574
575         return (status==SINGLEVALUED)?1:elements.length-1;
576     }
577
578
579
580    /**
581     * Returns whether the rdn is multi-valued.
582     */

583
584     public boolean isMultiValued()
585     {
586        if (status == UNTESTED)
587            checkForMultiValued();
588
589        return (status == MULTIVALUED);
590     }
591
592
593
594    /**
595     * Test two RDNs for equivalence. Takes a bit of a shortcut -
596     * checks for case insensitive equivalence, doesn't check schema
597     * to see whether the value is case sensitive or not...i.e. the importance
598     * is low because currently we set delete RDN to false by default therefore
599     * you can't store two attributes in the dir that are only different b/c of their
600     * case. Having delete RDN set to false means that in changing the case we will
601     * have two copies of it in the entry - which can't happen if their differences are
602     * just in their case (upper/lower).
603     * @param test the RDN to test this RDN against for equality.
604     * @return true if the two RDNs are the same, false otherwise.
605     */

606
607     public boolean equals(RDN test)
608     {
609         if (test == null)
610             return false;
611         else if (test.size() != size()) return false;
612
613         if (isMultiValued())
614         {
615             // XXX complex equality test for multi valued RDNs
616
// should be made here - e.g. ordering of RDN subelements
617
// shouldn't be important... in the meantime, we'll cheat.
618
//TE: Eventually this will come up as a bug...to do: sort the arrays
619
//TE: so that we avoid saying that two multivalued RDNs are different if in fact they are
620
//TE: the same but just ordered differently. [e.g cn=A+sn=B == sn=B+cn=A but this method will
621
//TE: return false].
622

623             // el hack.
624

625             String JavaDoc[] atts = getAtts();
626             String JavaDoc[] vals = getRawVals(); // get unescaped unicode value
627
String JavaDoc[] testAtts = test.getAtts();
628             String JavaDoc[] testVals = test.getRawVals(); // get unescaped unicode value
629

630             for (int i=0; i<size(); i++)
631                 if (!elementsEqual(atts[i], testAtts[i], vals[i], testVals[i]) )
632                     return false;
633
634             return true;
635         }
636         else
637         {
638             return elementsEqual(getAtt(), test.getAtt(), getRawVal(), test.getRawVal()); // use unescaped unicode value
639
}
640     }
641
642
643
644    /**
645     * Check that the two attributes are the same, and that the values
646     * are the same. The values must be passed in *unescaped* (we use
647     * the unescaped form to get around the problem of having different
648     * types of utf-8/unicode/whatever floating around).
649     * @param att1 the attribute type of the first RDN.
650     * @param att2 the attribute type of the second RDN.
651     * @param val1 the attribute value of the first RDN.
652     * @param val2 the attribute value of the second RDN.
653     * @return true if the the attribute type and value of the first and second RDN are the same (ignoring case).
654     */

655
656     private boolean elementsEqual(String JavaDoc att1, String JavaDoc att2, String JavaDoc val1, String JavaDoc val2)
657     {
658 /* Multiple trailing white spaces will be cut off val2 but not val1...therefore this method will return false &
659     try to mod DN which fails b/c DN already exists? I would expect this to succeed. If I trim val1
660     a mod DN is not done but a modify is done - and again fails because a modify on a DN is not allowed??
661     --JX doesn't allow the user to enter spaces at the end of values. But it should handle values that already
662     has a space at the end. I think this multiple trailing white space thing could be a dir bug - the white
663     spaces appear not to be escaped. eg... baseObject: ou=AAA \ ,o=DEMOCORP,c=AU. Seems to work fine with
664     correctly escaped single white space eg...baseObject: ou=AAA\ ,o=DEMOCORP,c=AU.
665 System.out.println(">>"+val1+"<<");
666 System.out.println(">>"+val2+"<<");
667         val1=val1.trim();
668 System.out.println(">>"+val1+"<<");
669 System.out.println(">>"+val2+"<<");
670 */

671
672             if (att1.equalsIgnoreCase(att2) == false)
673                 return false;
674
675             // XXX THIS ASSUME CASE INSENSITIVE MATCH! (Really should check schema...)
676
if (val1.equalsIgnoreCase(val2) == false)
677                 return false;
678
679             return true;
680     }
681
682
683
684    /**
685     * Generic equality test allows for test against non-RDN objects
686     * via their 'toString()' and a case-insensitive match.
687     */

688
689     public boolean equals(Object JavaDoc o)
690     {
691         if (o == null)
692             return false;
693         if (o instanceof RDN)
694             return equals((RDN)o);
695         else
696             return (ldapEscapedRDN.equalsIgnoreCase(o.toString()));
697     }
698
699
700
701     /**
702      * Test for multivaluedness by simply checking for unescaped
703      * plus symbols. Does *not* validate the entire RDN, or do
704      * any syntax checking, but does break the rdn up into sub units.
705      */

706
707     private void checkForMultiValued()
708     {
709         if (status != UNTESTED) return; // nothing to do
710

711         if (NameUtility.next(ldapEscapedRDN, 0, '+') == -1) // test for simplest case
712
{
713             status = SINGLEVALUED;
714         }
715         else // things now get complicated and slow...
716
{
717             status = MULTIVALUED;
718             parseMultiValued(MAXELEMENTS);
719         }
720     }
721
722     /**
723      * Parse a multi valued RDN.
724      */

725
726     private void parseMultiValued()
727     {
728         parseMultiValued(MAXELEMENTS);
729     }
730
731
732     private void parseMultiValued(int max)
733     {
734         if (max > 512)
735         {
736             System.err.println("wierd error in RDN - attempt to parse RDN with more than 512 sub units???");
737             return;
738         }
739
740         try
741         {
742             int[] temp = new int[max];
743
744             temp[0] = -1; // each element is one *before* the next attval pair, including the first
745

746             int numElements = 0;
747             int pos = 0;
748
749 if (debug) System.out.println("\n*** parsing multi valued rdn");
750 if (debug) System.out.println("parsing " + ldapEscapedRDN);
751             while ((pos = NameUtility.next(ldapEscapedRDN, pos, '+'))>-1)
752             {
753                 numElements++;
754                 temp[numElements] = pos;
755
756 if (debug) System.out.println("found " + numElements + " -th element at " + pos);
757
758                 int pos1, pos2;
759                 pos1 = temp[numElements-1] + 1;
760                 pos2 = temp[numElements];
761 if (debug) System.out.println(" = string " + pos1 + " -> " + pos2 + " = ");
762 if (debug) System.out.println(ldapEscapedRDN.substring(pos1, pos2));
763
764                 pos++;
765             }
766
767             numElements++;
768             temp[numElements] = ldapEscapedRDN.length();
769
770             int pos1, pos2;
771             pos1 = temp[numElements-1] + 1;
772             pos2 = temp[numElements];
773
774 if (debug) System.out.println("found " + numElements + " -th element at " + pos + " = string " +
775              pos1 + " -> " + pos2 + " final len: " + ldapEscapedRDN.length());
776 if (debug) System.out.println(" = '" + ldapEscapedRDN.substring(pos1, pos2) + "'");
777
778
779
780 if (debug) System.out.println("found total of " + numElements + " elements...\n*****\n");
781
782             elements = new int[numElements+1];
783             System.arraycopy(temp, 0, elements, 0, numElements+1);
784         }
785         catch (IndexOutOfBoundsException JavaDoc e)
786         {
787 if (debug) e.printStackTrace();
788             System.err.println("huge number of multi-valued RDN units - increasing to: " + max*2);
789             parseMultiValued(max*2);
790
791         }
792     }
793
794     /**
795      * Checks whether the RDN is valid (i.e. has non null, correctly escaped elements).
796      * A (relatively) expensive operation.
797      */

798
799     public boolean validate()
800     {
801         try
802         {
803             if (status == UNTESTED)
804                 checkForMultiValued();
805
806             if (isEmpty()) // *technically* an empty RDN isn't valid...
807
return false;
808
809             int noElements = size();
810             for (int i=0; i<noElements; i++)
811             {
812                 String JavaDoc att = getAtt(i);
813                 String JavaDoc val = getRawVal(i);
814
815                 if (att == null || att.length()==0)
816                 {
817                     return false;
818                 }
819                 if (val == null || val.length()==0 || val.startsWith("error "))
820                 {
821                     return false;
822                 }
823             }
824         }
825         catch (Exception JavaDoc e)
826         {
827             return false;
828         }
829
830         return true; // XXX check whether the RDN is sane - i.e. parse it and confirm.
831
}
832
833 }
Popular Tags