|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package com.sun.jndi.cosnaming; |
|
|
|
import javax.naming.*; |
|
import java.util.Properties; |
|
import java.util.Vector; |
|
import java.util.Enumeration; |
|
|
|
import org.omg.CosNaming.NameComponent; |
|
|
|
/** |
|
* Parsing routines for NameParser as well as COS Naming stringified names. |
|
* This is used by CNCtx to create a NameComponent[] object and vice versa. |
|
* It follows Section 4.5 of Interoperable Naming Service (INS) 98-10-11. |
|
* In summary, the stringified form is a left-to-right, forward-slash |
|
* separated name. id and kinds are separated by '.'. backslash is the |
|
* escape character. |
|
* |
|
* @author Rosanna Lee |
|
*/ |
|
|
|
final public class CNNameParser implements NameParser { |
|
|
|
private static final Properties mySyntax = new Properties(); |
|
private static final char kindSeparator = '.'; |
|
private static final char compSeparator = '/'; |
|
private static final char escapeChar = '\\'; |
|
static { |
|
mySyntax.put("jndi.syntax.direction", "left_to_right"); |
|
mySyntax.put("jndi.syntax.separator", ""+compSeparator); |
|
mySyntax.put("jndi.syntax.escape", ""+escapeChar); |
|
}; |
|
|
|
|
|
|
|
*/ |
|
public CNNameParser() { |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Name parse(String name) throws NamingException { |
|
Vector<String> comps = insStringToStringifiedComps(name); |
|
return new CNCompoundName(comps.elements()); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
static NameComponent[] nameToCosName(Name name) |
|
throws InvalidNameException { |
|
int len = name.size(); |
|
if (len == 0) { |
|
return new NameComponent[0]; |
|
} |
|
|
|
NameComponent[] answer = new NameComponent[len]; |
|
for (int i = 0; i < len; i++) { |
|
answer[i] = parseComponent(name.get(i)); |
|
} |
|
return answer; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
static String cosNameToInsString(NameComponent[] cname) { |
|
StringBuffer str = new StringBuffer(); |
|
for ( int i = 0; i < cname.length; i++) { |
|
if ( i > 0) { |
|
str.append(compSeparator); |
|
} |
|
str.append(stringifyComponent(cname[i])); |
|
} |
|
return str.toString(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
static Name cosNameToName(NameComponent[] cname) { |
|
Name nm = new CompositeName(); |
|
for ( int i = 0; cname != null && i < cname.length; i++) { |
|
try { |
|
nm.add(stringifyComponent(cname[i])); |
|
} catch (InvalidNameException e) { |
|
// ignore |
|
} |
|
} |
|
return nm; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private static Vector<String> insStringToStringifiedComps(String str) |
|
throws InvalidNameException { |
|
|
|
int len = str.length(); |
|
Vector<String> components = new Vector<>(10); |
|
char[] id = new char[len]; |
|
char[] kind = new char[len]; |
|
int idCount, kindCount; |
|
boolean idMode; |
|
for (int i = 0; i < len; ) { |
|
idCount = kindCount = 0; |
|
idMode = true; |
|
while (i < len) { |
|
if (str.charAt(i) == compSeparator) { |
|
break; |
|
|
|
} else if (str.charAt(i) == escapeChar) { |
|
if (i + 1 >= len) { |
|
throw new InvalidNameException(str + |
|
": unescaped \\ at end of component"); |
|
} else if (isMeta(str.charAt(i+1))) { |
|
++i; |
|
if (idMode) { |
|
id[idCount++] = str.charAt(i++); |
|
} else { |
|
kind[kindCount++] = str.charAt(i++); |
|
} |
|
} else { |
|
throw new InvalidNameException(str + |
|
": invalid character being escaped"); |
|
} |
|
|
|
} else if (idMode && str.charAt(i) == kindSeparator) { |
|
// just look for the first kindSeparator |
|
++i; |
|
idMode = false; |
|
|
|
} else { |
|
if (idMode) { |
|
id[idCount++] = str.charAt(i++); |
|
} else { |
|
kind[kindCount++] = str.charAt(i++); |
|
} |
|
} |
|
} |
|
components.addElement(stringifyComponent( |
|
new NameComponent(new String(id, 0, idCount), |
|
new String(kind, 0, kindCount)))); |
|
|
|
if (i < len) { |
|
++i; |
|
} |
|
} |
|
|
|
return components; |
|
} |
|
|
|
|
|
|
|
*/ |
|
private static NameComponent parseComponent(String compStr) |
|
throws InvalidNameException { |
|
NameComponent comp = new NameComponent(); |
|
int kindSep = -1; |
|
int len = compStr.length(); |
|
|
|
int j = 0; |
|
char[] newStr = new char[len]; |
|
boolean escaped = false; |
|
|
|
|
|
for (int i = 0; i < len && kindSep < 0; i++) { |
|
if (escaped) { |
|
newStr[j++] = compStr.charAt(i); |
|
escaped = false; |
|
} else if (compStr.charAt(i) == escapeChar) { |
|
if (i + 1 >= len) { |
|
throw new InvalidNameException(compStr + |
|
": unescaped \\ at end of component"); |
|
} else if (isMeta(compStr.charAt(i+1))) { |
|
escaped = true; |
|
} else { |
|
throw new InvalidNameException(compStr + |
|
": invalid character being escaped"); |
|
} |
|
} else if (compStr.charAt(i) == kindSeparator) { |
|
kindSep = i; |
|
} else { |
|
newStr[j++] = compStr.charAt(i); |
|
} |
|
} |
|
|
|
|
|
comp.id = new String(newStr, 0, j); |
|
|
|
|
|
if (kindSep < 0) { |
|
comp.kind = ""; |
|
} else { |
|
|
|
j = 0; |
|
escaped = false; |
|
for (int i = kindSep+1; i < len; i++) { |
|
if (escaped) { |
|
newStr[j++] = compStr.charAt(i); |
|
escaped = false; |
|
} else if (compStr.charAt(i) == escapeChar) { |
|
if (i + 1 >= len) { |
|
throw new InvalidNameException(compStr + |
|
": unescaped \\ at end of component"); |
|
} else if (isMeta(compStr.charAt(i+1))) { |
|
escaped = true; |
|
} else { |
|
throw new InvalidNameException(compStr + |
|
": invalid character being escaped"); |
|
} |
|
} else { |
|
newStr[j++] = compStr.charAt(i); |
|
} |
|
} |
|
comp.kind = new String(newStr, 0, j); |
|
} |
|
return comp; |
|
} |
|
|
|
private static String stringifyComponent(NameComponent comp) { |
|
StringBuffer one = new StringBuffer(escape(comp.id)); |
|
if (comp.kind != null && !comp.kind.equals("")) { |
|
one.append(kindSeparator + escape(comp.kind)); |
|
} |
|
if (one.length() == 0) { |
|
return ""+kindSeparator; |
|
} else { |
|
return one.toString(); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static String escape(String str) { |
|
if (str.indexOf(kindSeparator) < 0 && |
|
str.indexOf(compSeparator) < 0 && |
|
str.indexOf(escapeChar) < 0) { |
|
return str; |
|
} else { |
|
int len = str.length(); |
|
int j = 0; |
|
char[] newStr = new char[len+len]; |
|
for (int i = 0; i < len; i++) { |
|
if (isMeta(str.charAt(i))) { |
|
newStr[j++] = escapeChar; |
|
} |
|
newStr[j++] = str.charAt(i); |
|
} |
|
return new String(newStr, 0, j); |
|
} |
|
} |
|
|
|
|
|
|
|
*/ |
|
private static boolean isMeta(char ch) { |
|
switch (ch) { |
|
case kindSeparator: |
|
case compSeparator: |
|
case escapeChar: |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
static final class CNCompoundName extends CompoundName { |
|
CNCompoundName(Enumeration<String> enum_) { |
|
super(enum_, CNNameParser.mySyntax); |
|
} |
|
|
|
public Object clone() { |
|
return new CNCompoundName(getAll()); |
|
} |
|
|
|
public Name getPrefix(int posn) { |
|
Enumeration<String> comps = super.getPrefix(posn).getAll(); |
|
return new CNCompoundName(comps); |
|
} |
|
|
|
public Name getSuffix(int posn) { |
|
Enumeration<String> comps = super.getSuffix(posn).getAll(); |
|
return new CNCompoundName(comps); |
|
} |
|
|
|
public String toString() { |
|
try { |
|
|
|
return cosNameToInsString(nameToCosName(this)); |
|
} catch (InvalidNameException e) { |
|
return super.toString(); |
|
} |
|
} |
|
|
|
private static final long serialVersionUID = -6599252802678482317L; |
|
} |
|
|
|
// for testing only |
|
/* |
|
private static void print(String input) { |
|
try { |
|
System.out.println("\n >>>>>> input: " + input); |
|
|
|
System.out.println("--Compound Name: "); |
|
NameParser parser = new CNNameParser(); |
|
Name name = parser.parse(input); |
|
for (int i = 0; i < name.size(); i++) { |
|
System.out.println("\t" + i + ": " + name.get(i)); |
|
NameComponent cp = parseComponent(name.get(i)); |
|
System.out.println("\t\t" + "id: " + cp.id + ";kind: " + cp.kind); |
|
} |
|
System.out.println("\t" + name.toString()); |
|
|
|
System.out.println("--Composite Name: "); |
|
Name composite = new CompositeName(input); |
|
for (int i = 0; i < composite.size(); i++) { |
|
System.out.println("\t" + i+": " + composite.get(i)); |
|
} |
|
System.out.println("\t" + composite.toString()); |
|
|
|
System.out.println("--Composite To NameComponent"); |
|
NameComponent[] names = nameToCosName(composite); |
|
for (int i = 0; i < composite.size(); i++) { |
|
System.out.println("\t" + i+": id: " + names[i].id + "; kind: " + names[i].kind); |
|
} |
|
System.out.println("\t" + cosNameToInsString(names)); |
|
} catch (NamingException e) { |
|
System.out.println(e); |
|
} |
|
} |
|
|
|
private static void checkName(Name name, String[] comps) throws Exception { |
|
if (name.size() != comps.length) { |
|
throw new Exception( |
|
"test failed; incorrect component count in " + name + "; " + |
|
"expecting " + comps.length + " got " + name.size()); |
|
} |
|
for (int i = 0; i < name.size(); i++) { |
|
if (!comps[i].equals(name.get(i))) { |
|
throw new Exception ( |
|
"test failed; invalid component in " + name + "; " + |
|
"expecting '" + comps[i] + "' got '" + name.get(i) + "'"); |
|
} |
|
} |
|
} |
|
|
|
private static void checkCompound(NameParser parser, |
|
String input, String[] comps) throws Exception { |
|
checkName(parser.parse(input), comps); |
|
} |
|
|
|
private static void checkComposite(String input, String[] comps) |
|
throws Exception { |
|
checkName(new CompositeName(input), comps); |
|
} |
|
|
|
private static String[] compounds = { |
|
"a/b/c", |
|
"a.b/c.d", |
|
"a", |
|
".", |
|
"a.", |
|
"c.d", |
|
".e", |
|
"a/x\\/y\\/z/b", |
|
"a\\.b.c\\.d/e.f", |
|
"a/b\\\\/c", |
|
"x\\\\.y", |
|
"x\\.y", |
|
"x.\\\\y", |
|
"x.y\\\\", |
|
"\\\\x.y", |
|
"a.b\\.c/d" |
|
}; |
|
private static String[][] compoundComps = { |
|
{"a", "b", "c"}, |
|
{"a.b", "c.d"}, |
|
{"a"}, |
|
{"."}, |
|
{"a"}, |
|
{"c.d"}, |
|
{".e"}, |
|
{"a", "x\\/y\\/z", "b"}, |
|
{"a\\.b.c\\.d", "e.f"}, |
|
{"a", "b\\\\", "c"}, |
|
{"x\\\\.y"}, |
|
{"x\\.y"}, |
|
{"x.\\\\y"}, |
|
{"x.y\\\\"}, |
|
{"\\\\x.y"}, |
|
{"a.b\\.c", "d"}, |
|
}; |
|
|
|
private static String[] composites = { |
|
"a/b/c", |
|
"a.b/c.d", |
|
"a", |
|
".", |
|
"a.", |
|
"c.d", |
|
".e", |
|
"a/x\\\\\\/y\\\\\\/z/b", |
|
"a\\\\.b.c\\\\.d/e.f", |
|
"a/b\\\\\\\\/c", |
|
"x\\\\\\.y", |
|
"x\\\\.y", |
|
"x.\\\\\\\\y", |
|
"x.y\\\\\\\\", |
|
"\\\\\\\\x.y" |
|
}; |
|
|
|
private static String[][] compositeComps = { |
|
{"a", "b", "c"}, |
|
{"a.b", "c.d"}, |
|
{"a"}, |
|
{"."}, |
|
{"a."}, // unlike compound, kind sep is not consumed |
|
{"c.d"}, |
|
{".e"}, |
|
{"a", "x\\/y\\/z", "b"}, |
|
{"a\\.b.c\\.d", "e.f"}, |
|
{"a", "b\\\\", "c"}, |
|
{"x\\\\.y"}, |
|
{"x\\.y"}, |
|
{"x.\\\\y"}, |
|
{"x.y\\\\"}, |
|
{"\\\\x.y"} |
|
}; |
|
|
|
public static void main(String[] args) throws Exception { |
|
if (args.length > 0) { |
|
for (int i = 0; i < args.length; i++) { |
|
print(args[0]); |
|
} |
|
} else { |
|
print("x\\\\.y"); |
|
print("x\\.y"); |
|
print("x.\\\\y"); |
|
print("x.y\\\\"); |
|
print("\\\\x.y"); |
|
} |
|
|
|
NameParser parser = new com.sun.jndi.cosnaming.CNNameParser(); |
|
for (int i = 0; i < compounds.length; i++) { |
|
checkCompound(parser, compounds[i], compoundComps[i]); |
|
} |
|
for (int i = 0; i < composites.length; i++) { |
|
checkComposite(composites[i], compositeComps[i]); |
|
} |
|
|
|
System.out.println("hardwire"); |
|
NameComponent[] foo = new NameComponent[1]; |
|
foo[0] = new NameComponent("foo\\", "bar"); |
|
|
|
System.out.println(cosNameToInsString(foo)); |
|
System.out.println(cosNameToName(foo)); |
|
} |
|
*/ |
|
} |