alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (CNNameParser.java)

This example Java source code file (CNNameParser.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

cncompoundname, cnnameparser, compositename, enumeration, invalidnameexception, name, namecomponent, naming, namingexception, object, properties, string, stringbuffer, util, vector

The CNNameParser.java Java example source code

/*
 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

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

  /**
    * Constructs a new name parser for parsing names in INS syntax.
    */
    public CNNameParser() {
    }

  /**
    * Returns a CompoundName given a string in INS syntax.
    * @param name The non-null string representation of the name.
    * @return a non-null CompoundName
    */
    public Name parse(String name) throws NamingException {
        Vector<String> comps = insStringToStringifiedComps(name);
        return new CNCompoundName(comps.elements());
    }

    /**
     * Creates a NameComponent[] from a Name structure.
     * Used by CNCtx to convert the input Name arg into a NameComponent[].
     * @param a CompoundName or a CompositeName;
     * each component must be the stringified form of a NameComponent.
     */
    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;
    }

    /**
     * Returns the INS stringified form of a NameComponent[].
     * Used by CNCtx.getNameInNamespace(), CNCompoundName.toString().
     */
    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();
    }

    /**
     * Creates a CompositeName from a NameComponent[].
     * Used by ExceptionMapper and CNBindingEnumeration to convert
     * a NameComponent[] into a composite name.
     */
    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;
    }

    /**
     * Converts an INS-syntax string name into a Vector in which
     * each element of the vector contains a stringified form of
     * a NameComponent.
     */
    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; // reset for new component
            idMode = true;           // always start off parsing id
            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; // skip escape and let meta through
                        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; // skip kind separator
                    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; // skip separator
            }
        }

        return components;
    }

    /**
     * Return a NameComponent given its stringified form.
     */
    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;

        // Find the kind separator
        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);
            }
        }

        // Set id
        comp.id = new String(newStr, 0, j);

        // Set kind
        if (kindSep < 0) {
            comp.kind = "";  // no kind separator
        } else {
            // unescape kind
            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;  // if neither id nor kind specified
        } else {
            return one.toString();
        }
    }

    /**
     * Returns a string with '.', '\', '/' escaped. Used when
     * stringifying the name into its INS stringified form.
     */
    private static String escape(String str) {
        if (str.indexOf(kindSeparator) < 0 &&
            str.indexOf(compSeparator) < 0 &&
            str.indexOf(escapeChar) < 0) {
            return str;                         // no meta characters to escape
        } 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;   // escape meta character
                }
                newStr[j++] = str.charAt(i);
            }
            return new String(newStr, 0, j);
        }
    }

    /**
     * In INS, there are three meta characters: '.', '/' and '\'.
     */
    private static boolean isMeta(char ch) {
        switch (ch) {
        case kindSeparator:
        case compSeparator:
        case escapeChar:
            return true;
        }
        return false;
    }

    /**
     * An implementation of CompoundName that bypasses the parsing
     * and stringifying code of the default CompoundName.
     */
    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 {
                // Convert Name to NameComponent[] then stringify
                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));
    }
*/
}

Other Java examples (source code examples)

Here is a short list of links related to this Java CNNameParser.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.