1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51:
52:
67: public class CompoundName implements Name, Cloneable, Serializable
68: {
69: private static final long serialVersionUID = 3513100557083972036L;
70:
71: private CompoundName (Properties syntax)
72: {
73: elts = new Vector<String> ();
74: mySyntax = syntax;
75: initializeSyntax ();
76: }
77:
78: protected CompoundName (Enumeration<String> comps, Properties syntax)
79: {
80: elts = new Vector<String> ();
81: mySyntax = syntax;
82: initializeSyntax ();
83: try
84: {
85: while (comps.hasMoreElements ())
86: elts.add (comps.nextElement ());
87: }
88: catch (NoSuchElementException ignore)
89: {
90: }
91: }
92:
93: public CompoundName (String n, Properties syntax)
94: throws InvalidNameException
95: {
96: elts = new Vector<String> ();
97: mySyntax = syntax;
98: initializeSyntax ();
99:
100: StringBuilder new_element = new StringBuilder ();
101: int i = 0;
102:
103:
104: String quote = null;
105: while (i < n.length ())
106: {
107: String special = isSpecial (n, i);
108:
109: if (special == escape && escape != null)
110: {
111: if (n.length () == i + special.length ())
112: {
113:
114: new_element.append (special);
115: i += special.length ();
116: }
117: else
118: {
119: String eSpecial = isSpecial (n, i + special.length ());
120: if (eSpecial != null)
121: {
122:
123: new_element.append (eSpecial);
124: i += special.length () + eSpecial.length ();
125: }
126: else
127: {
128:
129: new_element.append (special);
130: i += special.length ();
131: }
132: continue;
133: }
134: }
135: else if (quote != null)
136: {
137:
138: if (quote == special)
139: {
140:
141: if (i + quote.length () < n.length ()
142: && ! n.startsWith (separator, i + quote.length ()))
143: throw new InvalidNameException ("close quote before end of component");
144: elts.add (new_element.toString ());
145: new_element.setLength (0);
146: i += quote.length ();
147: quote = null;
148: continue;
149: }
150:
151: }
152:
153: else if (new_element.length () == 0
154: && special == beginQuote
155: && beginQuote != null)
156: {
157: quote = endQuote;
158: i += special.length ();
159: continue;
160: }
161: else if (new_element.length () == 0
162: && special == beginQuote2
163: && beginQuote2 != null)
164: {
165: quote = endQuote2;
166: i += special.length ();
167: continue;
168: }
169: else if (direction != FLAT && special == separator)
170: {
171: elts.add (new_element.toString ());
172: new_element.setLength (0);
173: i += special.length ();
174: continue;
175: }
176:
177:
178: new_element.append (n.charAt (i));
179: ++i;
180: }
181:
182: if (new_element.length () != 0)
183: elts.add (new_element.toString ());
184:
185: if (direction == RIGHT_TO_LEFT)
186: {
187:
188: int len = elts.size ();
189: for (i = 0; i < len / 2; ++i)
190: {
191: String t = elts.set (i, elts.get (len - i - 1));
192: elts.set (len - i - 1, t);
193: }
194: }
195:
196:
197: if (quote != null)
198: throw new InvalidNameException ("unterminated quote");
199: }
200:
201: public Name add (int posn, String comp) throws InvalidNameException
202: {
203: elts.add (posn, comp);
204: return this;
205: }
206:
207: public Name add (String comp) throws InvalidNameException
208: {
209: elts.add (comp);
210: return this;
211: }
212:
213: public Name addAll (int posn, Name n) throws InvalidNameException
214: {
215: Enumeration<String> e = n.getAll ();
216: try
217: {
218: while (e.hasMoreElements ())
219: {
220: elts.add (posn, e.nextElement ());
221: ++posn;
222: }
223: }
224: catch (NoSuchElementException ignore)
225: {
226: }
227: return this;
228: }
229:
230: public Name addAll (Name suffix) throws InvalidNameException
231: {
232: Enumeration<String> e = suffix.getAll ();
233: try
234: {
235: while (e.hasMoreElements ())
236: elts.add (e.nextElement ());
237: }
238: catch (NoSuchElementException ignore)
239: {
240: }
241: return this;
242: }
243:
244: public Object clone ()
245: {
246: return new CompoundName (elts.elements (), mySyntax);
247: }
248:
249: public int compareTo (Object obj)
250: {
251: if (! (obj instanceof CompoundName))
252: throw new ClassCastException ("CompoundName.compareTo() expected CompoundName");
253: CompoundName cn = (CompoundName) obj;
254: int last = Math.min (cn.elts.size (), elts.size ());
255: for (int i = 0; i < last; ++i)
256: {
257: String f = canonicalize (elts.get (i));
258: int comp = f.compareTo (canonicalize (cn.elts.get (i)));
259: if (comp != 0)
260: return comp;
261: }
262: return elts.size () - cn.elts.size ();
263: }
264:
265: public boolean endsWith (Name n)
266: {
267: if (! (n instanceof CompoundName))
268: return false;
269: CompoundName cn = (CompoundName) n;
270: if (cn.elts.size () > elts.size ())
271: return false;
272: int delta = elts.size () - cn.elts.size ();
273: for (int i = 0; i < cn.elts.size (); ++i)
274: {
275: String f = canonicalize (elts.get (delta + i));
276: if (! f.equals (canonicalize (cn.elts.get (i))))
277: return false;
278: }
279: return true;
280: }
281:
282: public boolean equals (Object obj)
283: {
284: if (! (obj instanceof CompoundName))
285: return false;
286: return compareTo (obj) == 0;
287: }
288:
289: public String get (int posn)
290: {
291: return elts.get (posn);
292: }
293:
294: public Enumeration<String> getAll ()
295: {
296: return elts.elements ();
297: }
298:
299: public Name getPrefix (int posn)
300: {
301: CompoundName cn = new CompoundName (mySyntax);
302: for (int i = 0; i < posn; ++i)
303: cn.elts.add (elts.get (i));
304: return cn;
305: }
306:
307: public Name getSuffix (int posn)
308: {
309: if (posn > elts.size ())
310: throw new ArrayIndexOutOfBoundsException (posn);
311: CompoundName cn = new CompoundName (mySyntax);
312: for (int i = posn; i < elts.size (); ++i)
313: cn.elts.add (elts.get (i));
314: return cn;
315: }
316:
317: public int hashCode ()
318: {
319: int h = 0;
320: for (int i = 0; i < elts.size (); ++i)
321: h += canonicalize (elts.get (i)).hashCode ();
322: return h;
323: }
324:
325: public boolean isEmpty ()
326: {
327: return elts.isEmpty ();
328: }
329:
330: public Object remove (int posn) throws InvalidNameException
331: {
332: return elts.remove (posn);
333: }
334:
335: public int size ()
336: {
337: return elts.size ();
338: }
339:
340: public boolean startsWith (Name n)
341: {
342: if (! (n instanceof CompoundName))
343: return false;
344: CompoundName cn = (CompoundName) n;
345: if (cn.elts.size () > elts.size ())
346: return false;
347: for (int i = 0; i < cn.elts.size (); ++i)
348: {
349: String f = canonicalize (elts.get (i));
350: if (! f.equals (canonicalize (cn.elts.get (i))))
351: return false;
352: }
353: return true;
354: }
355:
356:
357:
358:
359: private String isSpecial (String element, int offset)
360: {
361: String special = null;
362: if (separator != null && element.startsWith (separator, offset))
363: special = separator;
364: else if (escape != null && element.startsWith (escape, offset))
365: special = escape;
366: else if (beginQuote != null && element.startsWith (beginQuote, offset))
367: special = beginQuote;
368: else if (endQuote != null && element.startsWith (endQuote, offset))
369: special = endQuote;
370: else if (beginQuote2 != null
371: && element.startsWith (beginQuote2, offset))
372: special = beginQuote2;
373: else if (endQuote2 != null && element.startsWith (endQuote2, offset))
374: special = endQuote2;
375:
376: return special;
377: }
378:
379: public String toString ()
380: {
381: CPStringBuilder result = new CPStringBuilder ();
382: int size = elts.size ();
383: for (int i = 0; i < size; ++i)
384: {
385:
386:
387: int offset = (direction == RIGHT_TO_LEFT) ? (size - i - 1) : i;
388: String element = elts.get (offset);
389: if (i > 0
390: || (i == size - 1 && element.equals ("")))
391: result.append (separator);
392:
393: int k = 0;
394: while (k < element.length ())
395: {
396: String special = isSpecial (element, k);
397: if (special != null)
398: {
399: result.append (escape);
400: result.append (special);
401: k += special.length ();
402: }
403: else
404: {
405: result.append (element.charAt (k));
406: ++k;
407: }
408: }
409: }
410:
411: return result.toString ();
412: }
413:
414:
415:
416: private String canonicalize (String element)
417: {
418: String ret = element;
419:
420: if (ignoreCase)
421: ret = ret.toLowerCase ();
422:
423: if (trimBlanks)
424: {
425: int first = 0;
426: while (first < ret.length ()
427: && Character.isWhitespace (ret.charAt (first)))
428: ++first;
429:
430: int last = ret.length () - 1;
431: while (last >= first
432: && Character.isWhitespace (ret.charAt (last)))
433: --last;
434:
435: ret = ret.substring (first, last);
436: }
437:
438: return ret;
439: }
440:
441:
442:
443:
444:
445: private void initializeSyntax ()
446: {
447: String t = mySyntax.getProperty ("jndi.syntax.direction", "flat");
448: if (t.equals ("right_to_left"))
449: this.direction = RIGHT_TO_LEFT;
450: else if (t.equals ("left_to_right"))
451: this.direction = LEFT_TO_RIGHT;
452: else
453: {
454:
455: this.direction = FLAT;
456: }
457:
458:
459:
460: this.separator = mySyntax.getProperty ("jndi.syntax.separator", "");
461:
462: this.ignoreCase
463: = Boolean.valueOf (mySyntax.getProperty ("jndi.syntax.ignorecase",
464: "false")).booleanValue ();
465: this.escape = mySyntax.getProperty ("jndi.syntax.escape", null);
466: this.beginQuote = mySyntax.getProperty ("jndi.syntax.beginquote", null);
467: this.endQuote = mySyntax.getProperty ("jndi.syntax.endquote",
468: this.beginQuote);
469: this.beginQuote2 = mySyntax.getProperty ("jndi.syntax.beginquote2",
470: null);
471: this.endQuote2 = mySyntax.getProperty ("jndi.syntax.endquote2",
472: this.beginQuote2);
473: this.trimBlanks
474: = Boolean.valueOf (mySyntax.getProperty ("jndi.syntax.trimblanks",
475: "false")).booleanValue ();
476: }
477:
478: private void readObject(ObjectInputStream s)
479: throws IOException, ClassNotFoundException
480: {
481: mySyntax = (Properties) s.readObject();
482: int count = s.readInt();
483: elts = new Vector<String>(count);
484: for (int i = 0; i < count; i++)
485: elts.addElement((String) s.readObject());
486: }
487:
488: private void writeObject(ObjectOutputStream s)
489: throws IOException
490: {
491: s.writeObject(mySyntax);
492: s.writeInt(elts.size());
493: for (int i = 0; i < elts.size(); i++)
494: s.writeObject(elts.elementAt(i));
495: }
496:
497:
498:
499:
500:
501: protected transient Properties mySyntax;
502:
503:
504: private transient Vector<String> elts;
505:
506:
507: private transient int direction;
508: private transient String separator;
509: private transient boolean ignoreCase;
510: private transient String escape;
511: private transient String beginQuote;
512: private transient String endQuote;
513: private transient String beginQuote2;
514: private transient String endQuote2;
515: private transient boolean trimBlanks;
516:
517:
518:
519:
520: private static final int RIGHT_TO_LEFT = -1;
521: private static final int LEFT_TO_RIGHT = 1;
522: private static final int FLAT = 0;
523: }