source: trunk/gcc/libjava/javax/naming/CompoundName.java

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 13.1 KB
Line 
1/* CompoundName.java --
2 Copyright (C) 2001 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38
39package javax.naming;
40
41import java.io.Serializable;
42import java.util.Enumeration;
43import java.util.Properties;
44import java.util.NoSuchElementException;
45import java.util.Vector;
46
47/**
48 * @author Tom Tromey <tromey@redhat.com>
49 * @date May 16, 2001
50 *
51 * FIXME: must write readObject and writeObject to conform to
52 * serialization spec.
53 *
54 * FIXME: this class is underspecified. For instance, the `flat'
55 * direction is never described. If it means that the CompoundName
56 * can only have a single element, then the Enumeration-based
57 * constructor ought to throw InvalidNameException.
58 */
59public class CompoundName implements Name, Cloneable, Serializable
60{
61 private CompoundName (Properties syntax)
62 {
63 elts = new Vector ();
64 mySyntax = syntax;
65 initializeSyntax ();
66 }
67
68 protected CompoundName (Enumeration comps, Properties syntax)
69 {
70 elts = new Vector ();
71 mySyntax = syntax;
72 initializeSyntax ();
73 try
74 {
75 while (comps.hasMoreElements ())
76 elts.add (comps.nextElement ());
77 }
78 catch (NoSuchElementException ignore)
79 {
80 }
81 }
82
83 public CompoundName (String n, Properties syntax)
84 throws InvalidNameException
85 {
86 elts = new Vector ();
87 mySyntax = syntax;
88 initializeSyntax ();
89
90 StringBuffer new_element = new StringBuffer ();
91 int i = 0;
92 // QUOTE==null means no quoting right now. When it is set it is
93 // the value of the closing quote.
94 String quote = null;
95 while (i < n.length ())
96 {
97 String special = isSpecial (n, i);
98
99 if (special == escape && escape != null)
100 {
101 if (n.length () == i + special.length ())
102 {
103 // A trailing escape is treated as itself.
104 new_element.append (special);
105 i += special.length ();
106 }
107 else
108 {
109 String eSpecial = isSpecial (n, i + special.length ());
110 if (eSpecial != null)
111 {
112 // Treat the escape as an escape.
113 new_element.append (eSpecial);
114 i += special.length () + eSpecial.length ();
115 }
116 else
117 {
118 // Treat the escape as itself.
119 new_element.append (special);
120 i += special.length ();
121 }
122 continue;
123 }
124 }
125 else if (quote != null)
126 {
127 // It is safe to use == here.
128 if (quote == special)
129 {
130 // Quotes must surround a complete component.
131 if (i + quote.length () < n.length ()
132 && ! n.startsWith (separator, i + quote.length ()))
133 throw new InvalidNameException ("close quote before end of component");
134 elts.add (new_element.toString ());
135 new_element.setLength (0);
136 i += quote.length ();
137 quote = null;
138 continue;
139 }
140 // Otherwise, fall through.
141 }
142 // Quotes are only special at the start of a component.
143 else if (new_element.length () == 0 && special == beginQuote)
144 {
145 quote = endQuote;
146 i += special.length ();
147 continue;
148 }
149 else if (new_element.length () == 0 && special == beginQuote2)
150 {
151 quote = endQuote2;
152 i += special.length ();
153 continue;
154 }
155 else if (special == separator)
156 {
157 elts.add (new_element.toString ());
158 new_element.setLength (0);
159 i += special.length ();
160 continue;
161 }
162
163 // Nothing in particular, so try the next character.
164 new_element.append (n.charAt (i));
165 ++i;
166 }
167
168 if (new_element.length () != 0)
169 elts.add (new_element.toString ());
170
171 if (direction == RIGHT_TO_LEFT)
172 {
173 // Reverse the order of the elements.
174 int len = elts.size ();
175 for (i = 0; i < len / 2; ++i)
176 {
177 Object t = elts.set (i, elts.get (len - i - 1));
178 elts.set (len - i - 1, t);
179 }
180 }
181
182 // Error checking.
183 if (quote != null)
184 throw new InvalidNameException ("unterminated quote");
185 }
186
187 public Name add (int posn, String comp) throws InvalidNameException
188 {
189 elts.add (posn, comp);
190 return this;
191 }
192
193 public Name add (String comp) throws InvalidNameException
194 {
195 elts.add (comp);
196 return this;
197 }
198
199 public Name addAll (int posn, Name n) throws InvalidNameException
200 {
201 Enumeration e = n.getAll ();
202 try
203 {
204 while (e.hasMoreElements ())
205 {
206 elts.add (posn, e.nextElement ());
207 ++posn;
208 }
209 }
210 catch (NoSuchElementException ignore)
211 {
212 }
213 return this;
214 }
215
216 public Name addAll (Name suffix) throws InvalidNameException
217 {
218 Enumeration e = suffix.getAll ();
219 try
220 {
221 while (e.hasMoreElements ())
222 elts.add (e.nextElement ());
223 }
224 catch (NoSuchElementException ignore)
225 {
226 }
227 return this;
228 }
229
230 public Object clone ()
231 {
232 return new CompoundName (elts.elements (), mySyntax);
233 }
234
235 public int compareTo (Object obj)
236 {
237 if (obj == null || ! (obj instanceof CompoundName))
238 throw new ClassCastException ("CompoundName.compareTo() expected CompoundName");
239 CompoundName cn = (CompoundName) obj;
240 int last = Math.min (cn.elts.size (), elts.size ());
241 for (int i = 0; i < last; ++i)
242 {
243 String f = canonicalize ((String) elts.get (i));
244 int comp = f.compareTo (canonicalize ((String) cn.elts.get (i)));
245 if (comp != 0)
246 return comp;
247 }
248 return elts.size () - cn.elts.size ();
249 }
250
251 public boolean endsWith (Name n)
252 {
253 if (! (n instanceof CompoundName))
254 return false;
255 CompoundName cn = (CompoundName) n;
256 if (cn.elts.size () > elts.size ())
257 return false;
258 int delta = elts.size () - cn.elts.size ();
259 for (int i = 0; i < cn.elts.size (); ++i)
260 {
261 String f = canonicalize ((String) elts.get (i));
262 if (! f.equals (canonicalize ((String) cn.elts.get (i))))
263 return false;
264 }
265 return true;
266 }
267
268 public boolean equals (Object obj)
269 {
270 if (! (obj instanceof CompoundName))
271 return false;
272 return compareTo (obj) == 0;
273 }
274
275 public String get (int posn)
276 {
277 return (String) elts.get (posn);
278 }
279
280 public Enumeration getAll ()
281 {
282 return elts.elements ();
283 }
284
285 public Name getPrefix (int posn)
286 {
287 CompoundName cn = new CompoundName (mySyntax);
288 for (int i = 0; i < posn; ++i)
289 cn.elts.add (elts.get (i));
290 return cn;
291 }
292
293 public Name getSuffix (int posn)
294 {
295 if (posn > elts.size ())
296 throw new ArrayIndexOutOfBoundsException (posn);
297 CompoundName cn = new CompoundName (mySyntax);
298 for (int i = posn; i < elts.size (); ++i)
299 cn.elts.add (elts.get (i));
300 return cn;
301 }
302
303 public int hashCode ()
304 {
305 int h = 0;
306 for (int i = 0; i < elts.size (); ++i)
307 h += canonicalize ((String) elts.get (i)).hashCode ();
308 return h;
309 }
310
311 public boolean isEmpty ()
312 {
313 return elts.isEmpty ();
314 }
315
316 public Object remove (int posn) throws InvalidNameException
317 {
318 return elts.remove (posn);
319 }
320
321 public int size ()
322 {
323 return elts.size ();
324 }
325
326 public boolean startsWith (Name n)
327 {
328 if (! (n instanceof CompoundName))
329 return false;
330 CompoundName cn = (CompoundName) n;
331 if (cn.elts.size () > elts.size ())
332 return false;
333 for (int i = 0; i < cn.elts.size (); ++i)
334 {
335 String f = canonicalize ((String) elts.get (i));
336 if (! f.equals (canonicalize ((String) cn.elts.get (i))))
337 return false;
338 }
339 return true;
340 }
341
342 // If ELEMENT starts with some meta-sequence at OFFSET, then return
343 // the string representing the meta-sequence. Otherwise return
344 // null.
345 private String isSpecial (String element, int offset)
346 {
347 String special = null;
348 if (separator != null && element.startsWith (separator, offset))
349 special = separator;
350 else if (escape != null && element.startsWith (escape, offset))
351 special = escape;
352 else if (beginQuote != null && element.startsWith (beginQuote, offset))
353 special = beginQuote;
354 else if (endQuote != null && element.startsWith (endQuote, offset))
355 special = endQuote;
356 else if (beginQuote2 != null
357 && element.startsWith (beginQuote2, offset))
358 special = beginQuote2;
359 else if (endQuote2 != null && element.startsWith (endQuote2, offset))
360 special = endQuote2;
361
362 return special;
363 }
364
365 public String toString ()
366 {
367 StringBuffer result = new StringBuffer ();
368 int size = elts.size ();
369 for (int i = 0; i < size; ++i)
370 {
371 // Find the appropriate element. FIXME: not clear what FLAT
372 // means.
373 int offset = (direction == RIGHT_TO_LEFT) ? (size - i - 1) : i;
374 String element = (String) elts.get (offset);
375 if (i > 0
376 || (i == size - 1 && element.equals ("")))
377 result.append (separator);
378
379 int k = 0;
380 while (k < element.length ())
381 {
382 String special = isSpecial (element, k);
383 if (special != null)
384 {
385 result.append (escape);
386 result.append (special);
387 k += special.length ();
388 }
389 else
390 {
391 result.append (element.charAt (k));
392 ++k;
393 }
394 }
395 }
396
397 return result.toString ();
398 }
399
400 // This canonicalizes a String, based on the syntax, for comparison
401 // or other similar purposes.
402 private String canonicalize (String element)
403 {
404 String ret = element;
405
406 if (ignoreCase)
407 ret = ret.toLowerCase ();
408
409 if (trimBlanks)
410 {
411 int first = 0;
412 while (first < ret.length ()
413 && Character.isWhitespace (ret.charAt (first)))
414 ++first;
415
416 int last = ret.length () - 1;
417 while (last >= first
418 && Character.isWhitespace (ret.charAt (last)))
419 --last;
420
421 ret = ret.substring (first, last);
422 }
423
424 return ret;
425 }
426
427 // This initializes all the syntax variables. This seems easier
428 // than re-querying the properties every time. We're allowed to do
429 // this because the spec says that subclasses should consider the
430 // syntax as being read-only.
431 private void initializeSyntax ()
432 {
433 String t = mySyntax.getProperty ("jndi.syntax.direction", "flat");
434 if (t.equals ("right_to_left"))
435 this.direction = RIGHT_TO_LEFT;
436 else if (t.equals ("left_to_right"))
437 this.direction = LEFT_TO_RIGHT;
438 else
439 {
440 // If we don't recognize it, default to flat.
441 this.direction = FLAT;
442 }
443
444 // This is required unless the direction is FLAT. Unfortunately
445 // there is no way to report this error.
446 this.separator = mySyntax.getProperty ("jndi.syntax.separator", "");
447
448 this.ignoreCase
449 = Boolean.valueOf (mySyntax.getProperty ("jndi.syntax.ignorecase",
450 "false")).booleanValue ();
451 this.escape = mySyntax.getProperty ("jndi.syntax.escape", null);
452 this.beginQuote = mySyntax.getProperty ("jndi.syntax.beginquote", null);
453 this.endQuote = mySyntax.getProperty ("jndi.syntax.endquote",
454 this.beginQuote);
455 this.beginQuote2 = mySyntax.getProperty ("jndi.syntax.beginquote2",
456 null);
457 this.endQuote2 = mySyntax.getProperty ("jndi.syntax.endquote2",
458 this.beginQuote2);
459 this.trimBlanks
460 = Boolean.valueOf (mySyntax.getProperty ("jndi.syntax.trimblanks",
461 "false")).booleanValue ();
462 }
463
464 // The spec specifies this but does not document it in any way (it
465 // is a package-private class). It is useless as far as I can tell.
466 // So we ignore it.
467 // protected transient NameImpl impl;
468 protected transient Properties mySyntax;
469
470 // The actual elements.
471 private transient Vector elts;
472
473 // The following are all used for syntax.
474 private transient int direction;
475 private transient String separator;
476 private transient boolean ignoreCase;
477 private transient String escape;
478 private transient String beginQuote;
479 private transient String endQuote;
480 private transient String beginQuote2;
481 private transient String endQuote2;
482 private transient boolean trimBlanks;
483 // We didn't need these for parsing, so they are gone.
484 // private transient String avaSeparator;
485 // private transient String typevalSeparator;
486
487 private static final int RIGHT_TO_LEFT = -1;
488 private static final int LEFT_TO_RIGHT = 1;
489 private static final int FLAT = 0;
490}
Note: See TracBrowser for help on using the repository browser.