libjava/ChangeLog:
[official-gcc.git] / libjava / classpath / gnu / CORBA / NamingService / NameTransformer.java
blob132c5dd8f04e4b6d5390d0ed1a006ae4939818d5
1 /* NameTransformer.java --
2 Copyright (C) 2005, 2006 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)
9 any later version.
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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
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
24 combination.
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. */
39 package gnu.CORBA.NamingService;
41 import gnu.java.lang.CPStringBuilder;
43 import org.omg.CORBA.IntHolder;
44 import org.omg.CosNaming.NameComponent;
45 import org.omg.CosNaming.NamingContextPackage.InvalidName;
47 import java.util.ArrayList;
48 import java.util.StringTokenizer;
50 /**
51 * This class converts between string and array representations of the
52 * multi component object names.
54 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
56 public class NameTransformer
58 /**
59 * A string, indicating the escape character.
61 public static final String ESCAPE = "\\";
63 /**
64 * Convert the string name representation into the array name
65 * representation. See {@link #toString(NameComponent)} for the
66 * description of this format.
68 * @param a_name the string form of the name.
70 * @return the array form of the name.
72 * @throws InvalidName if the name cannot be parsed.
74 public NameComponent[] toName(String a_name)
75 throws InvalidName
77 ArrayList components = new ArrayList();
78 StringTokenizer st = new StringTokenizer(a_name, "./\\", true);
80 // Create the buffer array, reserving the last element for null.
81 String[] n = new String[ st.countTokens() + 1 ];
83 int pp = 0;
84 while (st.hasMoreTokens())
85 n [ pp++ ] = st.nextToken();
87 IntHolder p = new IntHolder();
89 NameComponent node = readNode(p, n);
91 while (node != null)
93 components.add(node);
94 node = readNode(p, n);
97 NameComponent[] name = new NameComponent[ components.size() ];
98 for (int i = 0; i < name.length; i++)
100 name [ i ] = (NameComponent) components.get(i);
103 NameValidator.check(name);
105 return name;
109 * Converts the name into its string representation, as defined in
110 * the specification CORBA naming service.
112 * A string representation for the name consists of the name components,
113 * separated by a slash '/' character (for example, 'a/b/c'). If the
114 * {@link NameComponent#kind} field is not empty, it is given after
115 * period ('.'), for example 'a.b/c.d/.' .
116 * The period alone represents node where part where both
117 * {@link NameComponent#kind} and {@link NameComponent#id} are empty strings.
119 * If slash or dot are part of the name, they are escaped by backslash ('\').
120 * If the backslash itself is part of the name, it is doubled.
122 * @param a_name a name to convert.
123 * @return a string representation.
125 public String toString(NameComponent[] a_name)
126 throws InvalidName
128 NameValidator.check(a_name);
130 CPStringBuilder b = new CPStringBuilder();
132 NameComponent n;
134 for (int ni = 0; ni < a_name.length; ni++)
136 n = a_name [ ni ];
137 appEscaping(b, n.id);
138 if (n.kind.length() > 0)
140 b.append('.');
141 appEscaping(b, n.kind);
144 if (ni < a_name.length - 1)
145 b.append('/');
147 return b.toString();
151 * Append the contents of the string to this
152 * string buffer, inserting the escape sequences, where required.
154 * @param b a buffer to append the contents to.
155 * @param s a string to append.
157 private void appEscaping(CPStringBuilder b, String s)
159 char c;
160 for (int i = 0; i < s.length(); i++)
162 c = s.charAt(i);
163 switch (c)
165 case '.' :
166 case '/' :
167 case '\\' :
168 b.append('\\');
169 b.append(c);
170 break;
172 default :
173 b.append(c);
174 break;
180 * Assert the end of the current name component.
182 private void assertEndOfNode(IntHolder p, String[] t)
183 throws InvalidName
185 if (t [ p.value ] != null)
186 if (!t [ p.value ].equals("/"))
187 throw new InvalidName("End of node expected at token " + p.value);
191 * Read the named component node. After reading the current positon
192 * advances to the beginning of the next node in an array.
194 * @param p the current position being wrapped inside the passed
195 * IntHolder.
197 * @param t the text buffer.
199 * @return the created node.
201 private NameComponent readNode(IntHolder p, String[] t)
202 throws InvalidName
204 // End of stream has been reached.
205 if (t [ p.value ] == null)
206 return null;
208 NameComponent n = new NameComponent();
210 if (t [ p.value ].equals("."))
212 // The 'id' is missing, but the 'kind' may follow.
213 n.id = "";
214 p.value++;
215 n.kind = readPart(p, t);
216 assertEndOfNode(p, t);
217 if (t [ p.value ] != null)
218 p.value++;
220 else if (t [ p.value ].equals("/"))
222 // This is not allowed here and may happen only
223 // on two subsequent slashes.
224 throw new InvalidName("Unexpected '/' token " + p.value);
226 else
228 n.id = readPart(p, t);
230 // If some chars follow the id.
231 if (t [ p.value ] != null)
233 // Dot means that the kind part follows
234 if (t [ p.value ].equals("."))
236 p.value++;
237 n.kind = readPart(p, t);
238 assertEndOfNode(p, t);
239 if (t [ p.value ] != null)
240 p.value++;
243 // The next name component follows - advance to
244 // the beginning of the next name component.
245 else if (t [ p.value ].equals("/"))
247 n.kind = "";
248 p.value++;
250 else
251 throw new InvalidName("Unexpected '" + t [ p.value ] +
252 "' at token " + p.value
255 else
257 // Id, and then end of sequence.
258 n.kind = "";
261 return n;
265 * Read the name part (id or kind).
267 * @param p the current position. After reading, advances
268 * to the beginning of the next name fragment.
270 * @param t the string buffer.
272 * @return the name part with resolved escape sequences.
274 private String readPart(IntHolder p, String[] t)
276 CPStringBuilder part = new CPStringBuilder();
278 while (t [ p.value ] != null && !t [ p.value ].equals(".") &&
279 !t [ p.value ].equals("/")
282 if (t [ p.value ].equals(ESCAPE))
284 p.value++;
285 part.append(t [ p.value ]);
287 else
288 part.append(t [ p.value ]);
290 p.value++;
293 return part.toString();
296 public static void main(String[] args)
298 NameComponent a = new NameComponent("a", "ak");
299 NameComponent b = new NameComponent("b/z", "b.k");
300 NameComponent c = new NameComponent("c", "");
302 NameTransformer sn = new NameTransformer();
306 String s = sn.toString(new NameComponent[] { a, b, c });
307 System.out.println(s);
309 //NameComponent[] k = toName("a.k/b.k2/c/d/.");
310 //NameComponent[] k = toName("a.bc/.b/c.x");
312 NameComponent[] k = sn.toName(s);
313 System.out.println("ToString");
315 for (int i = 0; i < k.length; i++)
317 System.out.println(k [ i ].id + ":" + k [ i ].kind);
320 catch (InvalidName ex)
322 ex.printStackTrace();