1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50:
51:
59: public class CompositeName implements Name, Cloneable, Serializable
60: {
61: private static final long serialVersionUID = 1667768148915813118L;
62:
63: private transient Vector<String> elts;
64:
65: public CompositeName ()
66: {
67: elts = new Vector<String> ();
68: }
69:
70: protected CompositeName (Enumeration<String> comps)
71: {
72: elts = new Vector<String> ();
73: try
74: {
75: while (comps.hasMoreElements ())
76: elts.add (comps.nextElement ());
77: }
78: catch (NoSuchElementException ignore)
79: {
80: }
81: }
82:
83: public CompositeName (String n) throws InvalidNameException
84: {
85: elts = new Vector<String> ();
86:
87: final char no_quote = 'x';
88: char quote = no_quote;
89: boolean escaped = false;
90: StringBuilder new_element = new StringBuilder ();
91: for (int i = 0; i < n.length (); ++i)
92: {
93: char c = n.charAt (i);
94: if (escaped)
95: escaped = false;
96: else if (c == '\\')
97: {
98: escaped = true;
99: continue;
100: }
101: else if (quote != no_quote)
102: {
103: if (quote == c)
104: {
105:
106: if (i + 1 < n.length () && n.charAt (i + 1) != '/')
107: throw new InvalidNameException ("close quote before end of component");
108: elts.add (new_element.toString ());
109: new_element.setLength (0);
110: quote = no_quote;
111: continue;
112: }
113:
114: }
115:
116: else if (new_element.length () == 0
117: && (c == '\'' || c == '"'))
118: {
119: quote = c;
120: continue;
121: }
122: else if (c == '/')
123: {
124: elts.add (new_element.toString ());
125: new_element.setLength (0);
126: continue;
127: }
128:
129: new_element.append (c);
130: }
131:
132: if (new_element.length () != 0)
133: elts.add (new_element.toString ());
134:
135:
136: if (quote != no_quote)
137: throw new InvalidNameException ("unterminated quote");
138: if (escaped)
139: throw new InvalidNameException ("trailing escape character");
140: }
141:
142: public Name add (int posn, String comp) throws InvalidNameException
143: {
144: elts.add (posn, comp);
145: return this;
146: }
147:
148: public Name add (String comp) throws InvalidNameException
149: {
150: elts.add (comp);
151: return this;
152: }
153:
154: public Name addAll (int posn, Name n) throws InvalidNameException
155: {
156: Enumeration<String> e = n.getAll ();
157: try
158: {
159: while (e.hasMoreElements ())
160: {
161: elts.add (posn, e.nextElement ());
162: ++posn;
163: }
164: }
165: catch (NoSuchElementException ignore)
166: {
167: }
168: return this;
169: }
170:
171: public Name addAll (Name suffix) throws InvalidNameException
172: {
173: Enumeration<String> e = suffix.getAll ();
174: try
175: {
176: while (e.hasMoreElements ())
177: elts.add (e.nextElement ());
178: }
179: catch (NoSuchElementException ignore)
180: {
181: }
182: return this;
183: }
184:
185: public Object clone ()
186: {
187: return new CompositeName (elts.elements ());
188: }
189:
190: public int compareTo (Object obj)
191: {
192: if (obj == null || ! (obj instanceof CompositeName))
193: throw new ClassCastException ("CompositeName.compareTo() expected CompositeName");
194: CompositeName cn = (CompositeName) obj;
195: int last = Math.min (cn.elts.size (), elts.size ());
196: for (int i = 0; i < last; ++i)
197: {
198: String f = elts.get (i);
199: int comp = f.compareTo (cn.elts.get (i));
200: if (comp != 0)
201: return comp;
202: }
203: return elts.size () - cn.elts.size ();
204: }
205:
206: public boolean endsWith (Name n)
207: {
208: if (! (n instanceof CompositeName))
209: return false;
210: CompositeName cn = (CompositeName) n;
211: if (cn.elts.size () > elts.size ())
212: return false;
213: int delta = elts.size () - cn.elts.size ();
214: for (int i = 0; i < cn.elts.size (); ++i)
215: {
216: if (! cn.elts.get (i).equals (elts.get (delta + i)))
217: return false;
218: }
219: return true;
220: }
221:
222: public boolean equals (Object obj)
223: {
224: if (! (obj instanceof CompositeName))
225: return false;
226: CompositeName cn = (CompositeName) obj;
227: return elts.equals (cn.elts);
228: }
229:
230: public String get (int posn)
231: {
232: return elts.get (posn);
233: }
234:
235: public Enumeration<String> getAll ()
236: {
237: return elts.elements ();
238: }
239:
240: public Name getPrefix (int posn)
241: {
242: CompositeName cn = new CompositeName ();
243: for (int i = 0; i < posn; ++i)
244: cn.elts.add (elts.get (i));
245: return cn;
246: }
247:
248: public Name getSuffix (int posn)
249: {
250: if (posn > elts.size ())
251: throw new ArrayIndexOutOfBoundsException (posn);
252: CompositeName cn = new CompositeName ();
253: for (int i = posn; i < elts.size (); ++i)
254: cn.elts.add (elts.get (i));
255: return cn;
256: }
257:
258: public int hashCode ()
259: {
260:
261: int h = 0;
262: for (int i = 0; i < elts.size (); ++i)
263: h += elts.get (i).hashCode ();
264: return h;
265: }
266:
267: public boolean isEmpty ()
268: {
269: return elts.isEmpty ();
270: }
271:
272: public Object remove (int posn) throws InvalidNameException
273: {
274: return elts.remove (posn);
275: }
276:
277: public int size ()
278: {
279: return elts.size ();
280: }
281:
282: public boolean startsWith (Name n)
283: {
284: if (! (n instanceof CompositeName))
285: return false;
286: CompositeName cn = (CompositeName) n;
287: if (cn.elts.size () > elts.size ())
288: return false;
289: for (int i = 0; i < cn.elts.size (); ++i)
290: {
291: if (! cn.elts.get (i).equals (elts.get (i)))
292: return false;
293: }
294: return true;
295: }
296:
297: public String toString ()
298: {
299: CPStringBuilder result = new CPStringBuilder ();
300: for (int i = 0; i < elts.size (); ++i)
301: {
302:
303:
304: String elt = elts.get (i);
305: if (i > 0
306: || (i == elts.size () - 1 && elt.equals ("")))
307: result.append ('/');
308: for (int k = 0; k < elt.length (); ++k)
309: {
310: char c = elt.charAt (k);
311:
312:
313: if ((k == 0 && (c == '"' || c == '\''))
314:
315:
316: || (c == '\\'
317: && (k == elt.length () - 1
318: || "\\'\"/".indexOf (elt.charAt (k + 1)) != -1))
319:
320: || c == '/')
321: result.append ('\\');
322: result.append (c);
323: }
324: }
325: return result.toString ();
326: }
327:
328: private void readObject(ObjectInputStream s)
329: throws IOException, ClassNotFoundException
330: {
331: int size = s.readInt();
332: elts = new Vector<String>(size);
333: for (int i = 0; i < size; i++)
334: elts.add((String) s.readObject());
335: }
336:
337: private void writeObject(ObjectOutputStream s) throws IOException
338: {
339: s.writeInt(elts.size());
340: for (int i = 0; i < elts.size(); i++)
341: s.writeObject(elts.get(i));
342: }
343: }