1 /* CompositeName.java --
2 Copyright (C) 2001 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import java
.io
.Serializable
;
42 import java
.util
.Enumeration
;
43 import java
.util
.NoSuchElementException
;
44 import java
.util
.Vector
;
47 * @author Tom Tromey <tromey@redhat.com>
50 * FIXME: must write readObject and writeObject to conform to
53 public class CompositeName
implements Name
, Cloneable
, Serializable
55 private static final long serialVersionUID
= 1667768148915813118L;
57 public CompositeName ()
62 protected CompositeName (Enumeration comps
)
67 while (comps
.hasMoreElements ())
68 elts
.add (comps
.nextElement ());
70 catch (NoSuchElementException ignore
)
75 public CompositeName (String n
) throws InvalidNameException
78 // Parse the string into its components.
79 final char no_quote
= 'x'; // Use 'x' to mean no quoting.
80 char quote
= no_quote
;
81 boolean escaped
= false;
82 StringBuffer new_element
= new StringBuffer ();
83 for (int i
= 0; i
< n
.length (); ++i
)
85 char c
= n
.charAt (i
);
93 else if (quote
!= no_quote
)
97 // The quotes must surround a complete component.
98 if (i
+ 1 < n
.length () && n
.charAt (i
+ 1) != '/')
99 throw new InvalidNameException ("close quote before end of component");
100 elts
.add (new_element
.toString ());
101 new_element
.setLength (0);
105 // Otherwise, fall through.
107 // Quotes are only special at the start of a component.
108 else if (new_element
.length () == 0
109 && (c
== '\'' || c
== '"'))
116 elts
.add (new_element
.toString ());
117 new_element
.setLength (0);
121 new_element
.append (c
);
124 if (new_element
.length () != 0)
125 elts
.add (new_element
.toString ());
128 if (quote
!= no_quote
)
129 throw new InvalidNameException ("unterminated quote");
131 throw new InvalidNameException ("trailing escape character");
134 public Name
add (int posn
, String comp
) throws InvalidNameException
136 elts
.add (posn
, comp
);
140 public Name
add (String comp
) throws InvalidNameException
146 public Name
addAll (int posn
, Name n
) throws InvalidNameException
148 Enumeration e
= n
.getAll ();
151 while (e
.hasMoreElements ())
153 elts
.add (posn
, e
.nextElement ());
157 catch (NoSuchElementException ignore
)
163 public Name
addAll (Name suffix
) throws InvalidNameException
165 Enumeration e
= suffix
.getAll ();
168 while (e
.hasMoreElements ())
169 elts
.add (e
.nextElement ());
171 catch (NoSuchElementException ignore
)
177 public Object
clone ()
179 return new CompositeName (elts
.elements ());
182 public int compareTo (Object obj
)
184 if (obj
== null || ! (obj
instanceof CompositeName
))
185 throw new ClassCastException ("CompositeName.compareTo() expected CompositeName");
186 CompositeName cn
= (CompositeName
) obj
;
187 int last
= Math
.min (cn
.elts
.size (), elts
.size ());
188 for (int i
= 0; i
< last
; ++i
)
190 String f
= (String
) elts
.get (i
);
191 int comp
= f
.compareTo ((String
) cn
.elts
.get (i
));
195 return elts
.size () - cn
.elts
.size ();
198 public boolean endsWith (Name n
)
200 if (! (n
instanceof CompositeName
))
202 CompositeName cn
= (CompositeName
) n
;
203 if (cn
.elts
.size () > elts
.size ())
205 int delta
= elts
.size () - cn
.elts
.size ();
206 for (int i
= 0; i
< cn
.elts
.size (); ++i
)
208 if (! cn
.elts
.get (i
).equals (elts
.get (delta
+ i
)))
214 public boolean equals (Object obj
)
216 if (! (obj
instanceof CompositeName
))
218 CompositeName cn
= (CompositeName
) obj
;
219 return elts
.equals (cn
.elts
);
222 public String
get (int posn
)
224 return (String
) elts
.get (posn
);
227 public Enumeration
getAll ()
229 return elts
.elements ();
232 public Name
getPrefix (int posn
)
234 CompositeName cn
= new CompositeName ();
235 for (int i
= 0; i
< posn
; ++i
)
236 cn
.elts
.add ((String
) elts
.get (i
));
240 public Name
getSuffix (int posn
)
242 if (posn
> elts
.size ())
243 throw new ArrayIndexOutOfBoundsException (posn
);
244 CompositeName cn
= new CompositeName ();
245 for (int i
= posn
; i
< elts
.size (); ++i
)
246 cn
.elts
.add ((String
) elts
.get (i
));
250 public int hashCode ()
252 // Specified in documentation.
254 for (int i
= 0; i
< elts
.size (); ++i
)
255 h
+= elts
.get (i
).hashCode ();
259 public boolean isEmpty ()
261 return elts
.isEmpty ();
264 public Object
remove (int posn
) throws InvalidNameException
266 return elts
.remove (posn
);
274 public boolean startsWith (Name n
)
276 if (! (n
instanceof CompositeName
))
278 CompositeName cn
= (CompositeName
) n
;
279 if (cn
.elts
.size () > elts
.size ())
281 for (int i
= 0; i
< cn
.elts
.size (); ++i
)
283 if (! cn
.elts
.get (i
).equals (elts
.get (i
)))
289 public String
toString ()
291 StringBuffer result
= new StringBuffer ();
292 for (int i
= 0; i
< elts
.size (); ++i
)
294 // For simplicity we choose to always quote using escapes and
296 String elt
= (String
) elts
.get (i
);
298 || (i
== elts
.size () - 1 && elt
.equals ("")))
300 for (int k
= 0; k
< elt
.length (); ++k
)
302 char c
= elt
.charAt (k
);
304 // ... a leading quote,
305 if ((k
== 0 && (c
== '"' || c
== '\''))
306 // ... an escape preceding a meta character,
307 // or at the end of a component,
309 && (k
== elt
.length () - 1
310 || "\\'\"/".indexOf (elt
.charAt (k
+ 1)) != -1))
311 // ... or a component separator.
313 result
.append ('\\');
317 return result
.toString ();
320 private transient Vector elts
;