Imported GNU Classpath 0.19 + gcj-import-20051115.
* sources.am: Regenerated.
* Makefile.in: Likewise.
* scripts/makemake.tcl: Use glob -nocomplain.
From-SVN: r107049
This commit is contained in:
@@ -0,0 +1,328 @@
|
||||
/* NameTransformer.java --
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.CORBA.NamingService;
|
||||
|
||||
import org.omg.CORBA.IntHolder;
|
||||
import org.omg.CosNaming.NameComponent;
|
||||
import org.omg.CosNaming.NamingContextPackage.InvalidName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* This class converts between string and array representations of the
|
||||
* multi component object names.
|
||||
*
|
||||
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
|
||||
*/
|
||||
public class NameTransformer
|
||||
{
|
||||
/**
|
||||
* A string, indicating the escape character.
|
||||
*/
|
||||
public static final String ESCAPE = "\\";
|
||||
|
||||
/**
|
||||
* Convert the string name representation into the array name
|
||||
* representation. See {@link #toString(NameComponent)} for the
|
||||
* description of this format.
|
||||
*
|
||||
* @param name the string form of the name.
|
||||
*
|
||||
* @return the array form of the name.
|
||||
*
|
||||
* @throws InvalidName if the name cannot be parsed.
|
||||
*/
|
||||
public NameComponent[] toName(String a_name)
|
||||
throws InvalidName
|
||||
{
|
||||
ArrayList components = new ArrayList();
|
||||
StringTokenizer st = new StringTokenizer(a_name, "./\\", true);
|
||||
|
||||
String id;
|
||||
String kind;
|
||||
String next;
|
||||
|
||||
// Create the buffer array, reserving the last element for null.
|
||||
String[] n = new String[ st.countTokens() + 1 ];
|
||||
|
||||
int pp = 0;
|
||||
while (st.hasMoreTokens())
|
||||
n [ pp++ ] = st.nextToken();
|
||||
|
||||
IntHolder p = new IntHolder();
|
||||
|
||||
NameComponent node = readNode(p, n);
|
||||
|
||||
while (node != null)
|
||||
{
|
||||
components.add(node);
|
||||
node = readNode(p, n);
|
||||
}
|
||||
|
||||
NameComponent[] name = new NameComponent[ components.size() ];
|
||||
for (int i = 0; i < name.length; i++)
|
||||
{
|
||||
name [ i ] = (NameComponent) components.get(i);
|
||||
}
|
||||
|
||||
NameValidator.check(name);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the name into its string representation, as defined in
|
||||
* the specification CORBA naming service.
|
||||
*
|
||||
* A string representation for the name consists of the name components,
|
||||
* separated by a slash '/' character (for example, 'a/b/c'). If the
|
||||
* {@link NameComponent#kind} field is not empty, it is given after
|
||||
* period ('.'), for example 'a.b/c.d/.' .
|
||||
* The period alone represents node where part where both
|
||||
* {@link NameComponent#kind} and {@link NameComponent#id} are empty strings.
|
||||
*
|
||||
* If slash or dot are part of the name, they are escaped by backslash ('\').
|
||||
* If the backslash itself is part of the name, it is doubled.
|
||||
*
|
||||
* @param a_name a name to convert.
|
||||
* @return a string representation.
|
||||
*/
|
||||
public String toString(NameComponent[] a_name)
|
||||
throws InvalidName
|
||||
{
|
||||
NameValidator.check(a_name);
|
||||
|
||||
StringBuffer b = new StringBuffer();
|
||||
|
||||
NameComponent n;
|
||||
|
||||
for (int ni = 0; ni < a_name.length; ni++)
|
||||
{
|
||||
n = a_name [ ni ];
|
||||
appEscaping(b, n.id);
|
||||
if (n.kind.length() > 0)
|
||||
{
|
||||
b.append('.');
|
||||
appEscaping(b, n.kind);
|
||||
}
|
||||
|
||||
if (ni < a_name.length - 1)
|
||||
b.append('/');
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the contents of the string to this
|
||||
* string buffer, inserting the escape sequences, where required.
|
||||
*
|
||||
* @param b a buffer to append the contents to.
|
||||
* @param s a string to append.
|
||||
*/
|
||||
private void appEscaping(StringBuffer b, String s)
|
||||
{
|
||||
char c;
|
||||
for (int i = 0; i < s.length(); i++)
|
||||
{
|
||||
c = s.charAt(i);
|
||||
switch (c)
|
||||
{
|
||||
case '.' :
|
||||
case '/' :
|
||||
case '\\' :
|
||||
b.append('\\');
|
||||
b.append(c);
|
||||
break;
|
||||
|
||||
default :
|
||||
b.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the end of the current name component.
|
||||
*/
|
||||
private void assertEndOfNode(IntHolder p, String[] t)
|
||||
throws InvalidName
|
||||
{
|
||||
if (t [ p.value ] != null)
|
||||
if (!t [ p.value ].equals("/"))
|
||||
throw new InvalidName("End of node expected at token " + p.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the named component node. After reading the current positon
|
||||
* advances to the beginning of the next node in an array.
|
||||
*
|
||||
* @param p the current position being wrapped inside the passed
|
||||
* IntHolder.
|
||||
*
|
||||
* @param t the text buffer.
|
||||
*
|
||||
* @return the created node.
|
||||
*/
|
||||
private NameComponent readNode(IntHolder p, String[] t)
|
||||
throws InvalidName
|
||||
{
|
||||
// End of stream has been reached.
|
||||
if (t [ p.value ] == null)
|
||||
return null;
|
||||
|
||||
NameComponent n = new NameComponent();
|
||||
|
||||
if (t [ p.value ].equals("."))
|
||||
{
|
||||
// The 'id' is missing, but the 'kind' may follow.
|
||||
n.id = "";
|
||||
p.value++;
|
||||
n.kind = readPart(p, t);
|
||||
assertEndOfNode(p, t);
|
||||
if (t [ p.value ] != null)
|
||||
p.value++;
|
||||
}
|
||||
else if (t [ p.value ].equals("/"))
|
||||
{
|
||||
// This is not allowed here and may happen only
|
||||
// on two subsequent slashes.
|
||||
throw new InvalidName("Unexpected '/' token " + p.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
n.id = readPart(p, t);
|
||||
|
||||
// If some chars follow the id.
|
||||
if (t [ p.value ] != null)
|
||||
{
|
||||
// Dot means that the kind part follows
|
||||
if (t [ p.value ].equals("."))
|
||||
{
|
||||
p.value++;
|
||||
n.kind = readPart(p, t);
|
||||
assertEndOfNode(p, t);
|
||||
if (t [ p.value ] != null)
|
||||
p.value++;
|
||||
}
|
||||
|
||||
// The next name component follows - advance to
|
||||
// the beginning of the next name component.
|
||||
else if (t [ p.value ].equals("/"))
|
||||
{
|
||||
n.kind = "";
|
||||
p.value++;
|
||||
}
|
||||
else
|
||||
throw new InvalidName("Unexpected '" + t [ p.value ] +
|
||||
"' at token " + p.value
|
||||
);
|
||||
}
|
||||
else
|
||||
|
||||
// Id, and then end of sequence.
|
||||
n.kind = "";
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the name part (id or kind).
|
||||
*
|
||||
* @param p the current position. After reading, advances
|
||||
* to the beginning of the next name fragment.
|
||||
*
|
||||
* @param t the string buffer.
|
||||
*
|
||||
* @return the name part with resolved escape sequences.
|
||||
*/
|
||||
private String readPart(IntHolder p, String[] t)
|
||||
{
|
||||
StringBuffer part = new StringBuffer();
|
||||
|
||||
while (t [ p.value ] != null && !t [ p.value ].equals(".") &&
|
||||
!t [ p.value ].equals("/")
|
||||
)
|
||||
{
|
||||
if (t [ p.value ].equals(ESCAPE))
|
||||
{
|
||||
p.value++;
|
||||
part.append(t [ p.value ]);
|
||||
}
|
||||
else
|
||||
part.append(t [ p.value ]);
|
||||
|
||||
p.value++;
|
||||
}
|
||||
|
||||
return part.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
NameComponent a = new NameComponent("a", "ak");
|
||||
NameComponent b = new NameComponent("b/z", "b.k");
|
||||
NameComponent c = new NameComponent("c", "");
|
||||
|
||||
NameTransformer sn = new NameTransformer();
|
||||
|
||||
try
|
||||
{
|
||||
String s = sn.toString(new NameComponent[] { a, b, c });
|
||||
System.out.println(s);
|
||||
|
||||
//NameComponent[] k = toName("a.k/b.k2/c/d/.");
|
||||
//NameComponent[] k = toName("a.bc/.b/c.x");
|
||||
|
||||
NameComponent[] k = sn.toName(s);
|
||||
System.out.println("ToString");
|
||||
|
||||
for (int i = 0; i < k.length; i++)
|
||||
{
|
||||
System.out.println(k [ i ].id + ":" + k [ i ].kind);
|
||||
}
|
||||
}
|
||||
catch (InvalidName ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user