| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
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));  | 
 | 
    }  | 
 | 
*/  | 
 | 
}  |