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)
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
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. */
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
;
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
59 * A string, indicating the escape character.
61 public static final String ESCAPE
= "\\";
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
)
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 ];
84 while (st
.hasMoreTokens())
85 n
[ pp
++ ] = st
.nextToken();
87 IntHolder p
= new IntHolder();
89 NameComponent node
= readNode(p
, n
);
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
);
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
)
128 NameValidator
.check(a_name
);
130 CPStringBuilder b
= new CPStringBuilder();
134 for (int ni
= 0; ni
< a_name
.length
; ni
++)
137 appEscaping(b
, n
.id
);
138 if (n
.kind
.length() > 0)
141 appEscaping(b
, n
.kind
);
144 if (ni
< a_name
.length
- 1)
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
)
160 for (int i
= 0; i
< s
.length(); i
++)
180 * Assert the end of the current name component.
182 private void assertEndOfNode(IntHolder p
, String
[] t
)
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
197 * @param t the text buffer.
199 * @return the created node.
201 private NameComponent
readNode(IntHolder p
, String
[] t
)
204 // End of stream has been reached.
205 if (t
[ p
.value
] == null)
208 NameComponent n
= new NameComponent();
210 if (t
[ p
.value
].equals("."))
212 // The 'id' is missing, but the 'kind' may follow.
215 n
.kind
= readPart(p
, t
);
216 assertEndOfNode(p
, t
);
217 if (t
[ p
.value
] != null)
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
);
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("."))
237 n
.kind
= readPart(p
, t
);
238 assertEndOfNode(p
, t
);
239 if (t
[ p
.value
] != null)
243 // The next name component follows - advance to
244 // the beginning of the next name component.
245 else if (t
[ p
.value
].equals("/"))
251 throw new InvalidName("Unexpected '" + t
[ p
.value
] +
252 "' at token " + p
.value
257 // Id, and then end of sequence.
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
))
285 part
.append(t
[ p
.value
]);
288 part
.append(t
[ 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();