harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ndbe...@apache.org
Subject svn commit: r437433 [2/17] - in /incubator/harmony/enhanced/classlib/trunk/modules/jndi/src: main/java/javax/naming/ main/java/javax/naming/directory/ main/java/javax/naming/event/ main/java/javax/naming/ldap/ main/java/javax/naming/spi/ main/java/org/...
Date Sun, 27 Aug 2006 18:26:28 GMT
Modified: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/CompoundName.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/CompoundName.java?rev=437433&r1=437432&r2=437433&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/CompoundName.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/CompoundName.java Sun Aug 27 11:26:20 2006
@@ -1,1044 +1,1044 @@
-/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package javax.naming;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Properties;
-import java.util.Vector;
-
-/**
- * A <code>CompoundName</code> is a series of string elements, and it represents 
- * a name in a naming service within a single namespace. Typically these 
- * names have a structure which is hierarchical. 
- * <p>
- * A <code>CompoundName</code> has a sequence of zero or more elements delimited 
- * by the char specified in the property "jndi.syntax.separator". This property 
- * is required except when the direction of the name is "flat" 
- * (see jndi.syntax.direction). The property "jndi.syntax.separator2" allows for 
- * the specification of an additional separator. A separator string will be 
- * treated as normal characters if it is preceded by the escape string or is 
- * within quotes.</p>
- * <p>
- * The property "jndi.syntax.direction" specifies the direction in which the name
- * is read. Permitted values are "right_to_left", "left_to_right" and "flat". A 
- * flat name does not have a hierarchical structure. If this property is not 
- * specified then the default is "flat". If this property is specified with an 
- * invalid value then an <code>IllegalArgumentException</code> should be raised.</p>
- * <p>
- * Each element can be accessed using its position. The first element is at 
- * position 0. The direction of the name is important. When direction is 
- * "left_to_right" then the leftmost element is at position 0. Conversely when 
- * the direction is "right_to_left" then the rightmost element is at position 0.</p>
- * <p>
- * There are other properties which affect the syntax of a <code>CompoundName</code>. 
- * The following properties are all optional:
- * <ul>
- * <li>
- * jndi.syntax.escape -		Escape sequence,The escape sequence is used to escape 
- * 							a quote, separator or escape. When preceded itself by 
- * 							the escape sequence it is treated as ordinary characters.
- * 							When it is followed by chars which are not quote or 
- * 							separator strings then it is treated as ordinary characters</li>
- * <li>
- * jndi.syntax.beginquote -	Used as start of quoted string (Defaults to endquote)</li>
- * <li>
- * jndi.syntax.endquote - 	Used as end of quoted string (Defaults to beginquote)</li>
- * <li>
- * jndi.syntax.beginquote2 -	Additionally used as start of quoted string 
- * 							(Defaults to endquote2)</li>
- * <li>
- * jndi.syntax.endquote2 - 	Additionally used as end of quoted string 
- * 							(Defaults to beginquote2)</li>
- * </ul>
- * <p>
- * When a non-escaped quote appears at the start of an element it must be matched at the
- * end. That element can then be said to be quoted. When an escape sequence appears
- * within a quoted element then it is treated as normal characters unless it precedes
- * an occurrence of the quote in which case it is assumed that the quoted element
- * contains a quote which is escaped.</p>
- * <p>
- * If the element does not start with a quote, then any quote strings within that
- * element are just normal characters.</p>
- * <p>
- * <ul>
- * <li>
- * jndi.syntax.ignorecase -	If 'true' then ignore case when name elements are compared.
- *  						If false or not set then case is important.</li>
- * <li>
- * jndi.syntax.trimblanks -	If 'true' then ignore leading & trailing blanks when name elements are compared.
- * 							If false or not set then blanks are important.</li>
- * </ul></p>
- * <p>
- * These 2 properties relate to names where the syntax includes attribute/content 
- * pairs.
- * <ul>
- * <li>jndi.syntax.separator.ava</li>
- * <li>jndi.syntax.separator.typeval</li>
- * </ul>
- * For example the LDAP name, "CN=Mandy Jennings, O=Apache, C=UK".
- * In this example the pair separator jndi.syntax.separator.ava is ',', and the 
- * character that separates pairs jndi.syntax.separator.typeval is '='. See 
- * RFC1779 for LDAP naming conventions.</p>
- * <p>
- * The jndi.syntax.separator.ava is not used when manipulating <code>CompoundName</code>. 
- * The jndi.syntax.separator is still used to separate elements.</p>
- * <p>
- * The <code>CompoundName</code> needs to be aware of the jndi.syntax.separator.typeval
- * in case of the instance where a quoted string is used to provide the content
- * of a pair.</p>
- * <p>
- * Consider the string "CN=$Mandy Jennings, O=Apache, C=UK" with
- * <ul>
- * <li>
- * jndi.syntax.direction         set to "right_to_left"</li>
- * <li>
- * jndi.syntax.separator         set to ","</li>
- * <li>
- * jndi.syntax.separator.typeval set to "="</li>
- * </ul>
- * When no jndi.syntax.beginquote is set then this creates a valid <code>CompoundName</code>
- * with 3 elements.</p>
- * <p>
- * If jndi.syntax.beginquote is then set to "$" the name becomes invalid as the
- * content part of the pair CN=$Mandy Jennings has a mismatched quote.</p>
- * <p>
- * The string "CN=$Mandy Jennings$, O=Apache, C=UK" would be fine as the $ quotes
- * round Mandy Jennings now balance.</p>
- * <p>
- * A <code>CompoundName</code> may be empty. An empty <code>CompoundName</code> has no elements.
- * Elements may also be empty.</p> 
- * 
- * <pre>
- * Some Examples:
- * ==============
- * 
- * Consider the following compound name from the file system namespace:
- *     "home/jenningm-abc/.profile" 
- * 
- * jndi.syntax.separator is set to '/' as in the UNIX filesystem.
- * This name has 3 elements:
- *     home jenningm-abc and .profile
- * The direction should be left_to_right as in the UNIX filesystem
- * The element at position 0 would be home.
- * 
- * 
- * Consider if jndi.syntax.separator had been set to '-' then this name 
- * would have 2 elements:
- *     home/jenningm and abc/.profile
- * If the direction was right_to_left then the element at position 0
- * would be abc/.profile.
- * 
- * Consider the name "&lt;ab&lt;cd&gt;ef&gt;" where jndi.syntax.beginquote is &lt;
- * and jndi.syntax.endquote is &gt;. This will give rise to an 
- * InvalidNameException because a close quote was encountered before
- * the end of an element. The same is also true for "&lt;abcd&gt;ef&gt;".
- * If the name was "ab&lt;cd&gt;ef" then this would be valid and there would
- * be one element ab&lt;cd&gt;ef.
- * However if the name was "&lt;abcdef&gt;" there would be one element abcdef.
- * 
- * An empty <code>CompoundName</code> is the name "" and has no elements.
- * 
- * When jndi.syntax.beginquote is set to " and beginquote2 is set to '
- * the behaviour is simliar to CompositeName - 
- * The name "\"abcd" gives an InvalidNameException as there is no closing quote.
- * The name "'\"abcd'" gives one element of value "abcd.
- * The name "\\abcd" gives one element of value \abcd. 
- *  
- * Assuming:
- *     jndi.syntax.separator is "/"
- *     jndi.syntax.direction is "left_to_right"
- * then
- *     "" is empty. It has no elements.
- *     "/" has one empty element.
- *     "//" has 2 empty elements.
- *     "/a/" has 3 elements the middle one is set to a.
- *     "///" has 3 empty elements.
- *     "//a/" has 4 elements, the last but one is set to a.
- * 
- *
- * Assuming the only properties set are: 
- *     jndi.syntax.separator is "/"
- *     jndi.syntax.direction is "left_to_right"
- * then the String
- *     "\"" has one element with the value "
- *     "\\\"" has one element with the value \"
- *     "\\\"'" has one element with the value \"'
- * 
- * Assuming the only properties set are:
- *     jndi.syntax.separator is "/"
- *     jndi.syntax.direction is "left_to_right"
- *     jndi.syntax.beginquote is "\""
- * 
- * then the String
- *     "\"" is invalid because of no closing quote
- *     "\\\"" has one element with the value \"
- *     "\\\"'" has one element with the value \"'
- * 
- * 
- * Assuming the only properties set are:
- *     jndi.syntax.separator is "/"
- *     jndi.syntax.direction is "left_to_right"
- *     jndi.syntax.beginquote is "\""
- *     jndi.syntax.beginquote2 is "\'"
- * then the String
- *     "\"" is invalid because of no closing quote
- *     "\\\"" has one element with the value \"
- *     "\\\"'" has one element with the value \"'
- *     "'\\" is invalid because of no closing quote
- * </pre>
- * 
- * 
- */
-
-public class CompoundName implements Name {
-
-    /*
-     * -------------------------------------------------------------------
-     * Constants
-     * -------------------------------------------------------------------
-     */
-
-    /*
-     *=============
-     *Serialization
-     *=============
-     *
-     *Note: For serialization purposes, the specified serialVersionUID must be used.
-     *This class does not have serializable fields specified. Instead the readObject
-     *and writeObject methods are overidden.
-     */
-    static final long serialVersionUID = 3513100557083972036L; // J2SE 1.4.2
-
-    //const for property key
-    private static final String SEPARATOR = "jndi.syntax.separator"; //$NON-NLS-1$
-
-    private static final String SEPARATOR_AVA = "jndi.syntax.separator.ava"; //$NON-NLS-1$
-
-    private static final String SEPARATOR_TYPEVAL = "jndi.syntax.separator.typeval"; //$NON-NLS-1$
-
-    private static final String ESCAPE = "jndi.syntax.escape"; //$NON-NLS-1$
-
-    private static final String BEGIN_QUOTE = "jndi.syntax.beginquote"; //$NON-NLS-1$
-
-    private static final String END_QUOTE = "jndi.syntax.endquote"; //$NON-NLS-1$
-
-    private static final String BEGIN_QUOTE2 = "jndi.syntax.beginquote2"; //$NON-NLS-1$
-
-    private static final String END_QUOTE2 = "jndi.syntax.endquote2"; //$NON-NLS-1$
-
-    private static final String IGNORE_CASE = "jndi.syntax.ignorecase"; //$NON-NLS-1$
-
-    private static final String TRIM_BLANKS = "jndi.syntax.trimblanks"; //$NON-NLS-1$
-
-    private static final String DIRECTION = "jndi.syntax.direction"; //$NON-NLS-1$
-
-    private static final String SEPARATOR2 = "jndi.syntax.separator2"; //$NON-NLS-1$
-
-    //const for direction
-    private static final String LEFT_TO_RIGHT = "left_to_right"; //$NON-NLS-1$
-
-    private static final String RIGHT_TO_LEFT = "right_to_left"; //$NON-NLS-1$
-
-    private static final String FLAT = "flat"; //$NON-NLS-1$
-
-    // alphabets consts
-    private static final String NULL_STRING = ""; //$NON-NLS-1$
-
-    //states consts
-    private static final int NORMAL_STATUS = 0;
-
-    private static final int QUOTE1_STATUS = 1;
-
-    private static final int QUOTE2_STATUS = 2;
-
-    private static final int INIT_STATUS = 3;
-
-    private static final int QUOTEEND_STATUS = 4;
-
-    /*
-     * ============
-     * Variables
-     * ============ 
-     */
-    //properties variables
-    private transient String separatorString;
-
-    private transient String separatorString2;
-
-    private transient String escapeString;
-
-    private transient String endQuoteString;
-
-    private transient String endQuoteString2;
-
-    private transient String beginQuoteString;
-
-    private transient String beginQuoteString2;
-
-    private transient String sepAvaString;
-
-    private transient String sepTypeValString;
-
-    private transient String direction;
-
-    private transient boolean trimBlanks;
-
-    private transient boolean ignoreCase;
-
-    private transient boolean flat;
-
-    //elements of compound name
-    private transient Vector<String> elem;
-
-    //property setting
-    protected transient Properties mySyntax;
-    
-    /*
-     * The specification calls for a protected variable called 'impl' which is of a non-API
-     * type.  I believe this is an error in the spec, but to be compliant we have implemented
-     * this as a useless class (below).
-     */
-    protected transient javax.naming.NameImpl impl = new NameImpl();
-
-    /*
-     *============
-     *Constructors
-     *============ 
-     */
-
-    /**
-     * Constructs a <code>CompoundName</code> with supplied <code>Enumeration</code> 
-     * and <code>Properties</code>
-     * 
-     * @param elements		an enumeration of name elements, cannot be null
-     * @param props			the properties, cannot be null but may be empty. 
-     * 						If empty, the direction defaults to flat and no 
-     * 						other properties are required.
-     */
-    protected CompoundName(Enumeration<String> elements, Properties props) {
-        if (null == props || null == elements) {
-            throw new NullPointerException();
-        }
-        init(props);
-        this.elem = new Vector<String>();
-        while (elements.hasMoreElements()) {
-            this.elem.add(elements.nextElement());
-        }
-    }
-
-    /**
-     * Constructs a <code>CompoundName</code> with supplied <code>String</code> 
-     * and <code>Properties</code>,  taking the supplied <code>s</code> and 
-     * breaking it down into its elements. 
-     *
-     * @param s				a string containing the full compound name
-     * @param props			the properties, cannot be null but may be empty for a flat name
-     * @throws InvalidNameException 
-     * 						thrown if the supplied <code>String s</code> is invalid
-     * @throws NullPointerException 
-     * 						thrown if the supplied <code>String s</code> is null
-     */
-    public CompoundName(String s, Properties props) throws InvalidNameException {
-        if (null == s || null == props) {
-            throw new NullPointerException();
-        }
-        init(props);
-        parseName(s);
-    }
-
-    /*
-     * init instance variables
-     */
-    private void init(Properties props) {
-        trimBlanks = false;
-        ignoreCase = false;
-        this.mySyntax = (Properties) props.clone();
-        String property;
-
-        //read property settings
-        // direction's default value is FLAT
-        direction = null == (property = props.getProperty(DIRECTION)) ? FLAT
-                : property;
-        //if direction value must equals to one of FLAT, LEFT_TO_RIGHT and RIGHT_TO_LEFT, exception throwed 
-        if (!LEFT_TO_RIGHT.equals(direction)
-                && !RIGHT_TO_LEFT.equals(direction) && !FLAT.equals(direction)) {
-            throw new IllegalArgumentException(
-                    "Illegal direction property value, which must be one of right_to_left, left_to_right or flat"); //$NON-NLS-1$
-        }
-        flat = FLAT.equals(direction);
-
-        separatorString = flat ? NULL_STRING : props.getProperty(SEPARATOR);
-        //		if direction is not FLAT, separator must be set
-        if (null == separatorString && !flat) {
-            throw new IllegalArgumentException(
-                    "jndi.syntax.separator property must be set when jndi.syntax.direction is not flat"); //$NON-NLS-1$
-        }
-        separatorString2 = (flat || null == (property = props
-                .getProperty(SEPARATOR2))) ? NULL_STRING : property;
-
-        //ignorecase default value is false
-        ignoreCase = null == (property = props.getProperty(IGNORE_CASE)) ? false
-                : Boolean.valueOf(property).booleanValue();
-        //trimblanks default value is false
-        trimBlanks = null == (property = props.getProperty(TRIM_BLANKS)) ? false
-                : Boolean.valueOf(property).booleanValue();
-        escapeString = null == (property = props.getProperty(ESCAPE)) ? NULL_STRING
-                : property;
-        beginQuoteString = null == (property = props.getProperty(BEGIN_QUOTE)) ? NULL_STRING
-                : property;
-        beginQuoteString2 = null == (property = props.getProperty(BEGIN_QUOTE2)) ? NULL_STRING
-                : property;
-        //end quote string default value is begin quote string
-        endQuoteString = null == (property = props.getProperty(END_QUOTE)) ? beginQuoteString
-                : property;
-        //begin quote string default value is end quote string
-        if (NULL_STRING.equals(beginQuoteString)) {
-            beginQuoteString = endQuoteString;
-        }
-        //end quote string2 default value is begin quote string2
-        endQuoteString2 = null == (property = props.getProperty(END_QUOTE2)) ? beginQuoteString2
-                : property;
-        //begin quote string2 default value is end quote string2
-        if (NULL_STRING.equals(beginQuoteString2)) {
-            beginQuoteString2 = endQuoteString2;
-        }
-
-        sepTypeValString = null == (property = props
-                .getProperty(SEPARATOR_TYPEVAL)) ? NULL_STRING : property;
-        sepAvaString = null == (property = props.getProperty(SEPARATOR_AVA)) ? NULL_STRING
-                : property;
-    }
-
-    /*
-     * parse name from string to elements
-     */
-    private void parseName(String s) throws InvalidNameException {
-        this.elem = new Vector<String>();
-        if ("".equals(s)) { //$NON-NLS-1$
-            // if empty string, return empty vector
-            return;
-        }
-
-        //init variables
-        int status = INIT_STATUS;
-        StringBuffer element = new StringBuffer();
-        int pos = 0;
-        int length = s.length();
-        boolean hasNotNullElement = false;
-        boolean includeQuote = false;
-
-        //scan name
-        while (pos < length) {
-            if (startsWithFromPos(s, pos, endQuoteString)
-                    && status == QUOTE1_STATUS) {
-                status = QUOTEEND_STATUS;
-                pos += addBuffer(element, endQuoteString, includeQuote);
-            } else if (startsWithFromPos(s, pos, endQuoteString2)
-                    && status == QUOTE2_STATUS) {
-                status = QUOTEEND_STATUS;
-                pos += addBuffer(element, endQuoteString2, includeQuote);
-            } else if (startsWithFromPos(s, pos, beginQuoteString)
-                    && status == INIT_STATUS) {
-                hasNotNullElement = true;
-                status = QUOTE1_STATUS;
-                pos += addBuffer(element, beginQuoteString, includeQuote);
-            } else if (startsWithFromPos(s, pos, beginQuoteString2)
-                    && status == INIT_STATUS) {
-                hasNotNullElement = true;
-                status = QUOTE2_STATUS;
-                pos += addBuffer(element, beginQuoteString2, includeQuote);
-            } else if (startsWithFromPos(s, pos, separatorString)
-                    && (!flat)
-                    && (status == INIT_STATUS || status == QUOTEEND_STATUS || status == NORMAL_STATUS)) {
-                hasNotNullElement = hasNotNullElement || element.length() > 0;
-                addElement(element);
-                status = INIT_STATUS;
-                pos += separatorString.length();
-                includeQuote = false;
-            } else if (startsWithFromPos(s, pos, separatorString2)
-                    && (!flat)
-                    && (status == INIT_STATUS || status == QUOTEEND_STATUS || status == NORMAL_STATUS)) {
-                hasNotNullElement = hasNotNullElement || element.length() > 0;
-                addElement(element);
-                status = INIT_STATUS;
-                pos += separatorString2.length();
-                includeQuote = false;
-            } else if (startsWithFromPos(s, pos, escapeString)) {
-                pos += escapeString.length();
-                if (pos == s.length()) {
-                    //if this escape char is last character, throw exception
-                    throw new InvalidNameException(new StringBuffer(50).append(
-                            "The ") //$NON-NLS-1$
-                            .append(escapeString).append(
-                                    " cannot be at end of the component") //$NON-NLS-1$
-                            .toString());
-                }
-                //if one escape char followed by a special char, append the special char to current element
-                String str = extractEscapedString(s, pos, status);
-                if (null == str) {
-                    pos -= escapeString.length();
-                    element.append(s.charAt(pos++));
-                } else {
-                    pos += str.length();
-                    element.append(str);
-                }
-
-            } else if (startsWithFromPos(s, pos, sepTypeValString)
-                    && (status == INIT_STATUS || status == NORMAL_STATUS)) {
-                includeQuote = true;
-                pos += addBuffer(element, sepTypeValString, true);
-                status = INIT_STATUS;
-            } else if (startsWithFromPos(s, pos, sepAvaString)
-                    && (status == INIT_STATUS || status == NORMAL_STATUS)) {
-                includeQuote = true;
-                pos += addBuffer(element, sepAvaString, true);
-                status = INIT_STATUS;
-            } else if (status == QUOTEEND_STATUS) {
-                throw new InvalidNameException(
-                        s
-                                + ": close quote must appears at end of component in quoted string"); //$NON-NLS-1$
-            } else {
-                status = status == INIT_STATUS ? NORMAL_STATUS : status;
-                element.append(s.charAt(pos++));
-            }
-        }
-        if (QUOTE1_STATUS != status && QUOTE2_STATUS != status) {
-            hasNotNullElement = hasNotNullElement || element.length() > 0;
-            addElement(element);
-        } else {
-            throw new InvalidNameException(s
-                    + ": close quote is required for quoted string"); //$NON-NLS-1$
-        }
-        if (!hasNotNullElement) {
-            elem.remove(elem.size() - 1);
-        }
-    }
-
-    /*
-     * add des parameter to stringbuffer if include is true
-     */
-    private int addBuffer(StringBuffer buffer, String des, boolean include) {
-        if (include) {
-            buffer.append(des);
-        }
-        return des.length();
-    }
-
-    /*
-     * add current content of supplied string buffer as one element of this 
-     * CompoundName and reset the string buffer to empty
-     */
-    private void addElement(StringBuffer element) {
-        if (LEFT_TO_RIGHT == direction) {
-            elem.add(element.toString());
-        } else {
-            elem.add(0, element.toString());
-        }
-        element.setLength(0);
-    }
-
-    /*
-     * find string to be escaped, if cannot find special string(which means, 
-     * quote, separator and escape), return null 
-     */
-    private String extractEscapedString(String s, int pos, int status) {
-        String result = null;
-        if (status == QUOTE1_STATUS
-                && startsWithFromPos(s, pos, endQuoteString)) {
-            result = endQuoteString;
-        } else if (status == QUOTE2_STATUS
-                && startsWithFromPos(s, pos, endQuoteString2)) {
-            result = endQuoteString2;
-        } else if (status != QUOTE1_STATUS && status != QUOTE2_STATUS) {
-            if (startsWithFromPos(s, pos, beginQuoteString)) {
-                result = beginQuoteString;
-            } else if (startsWithFromPos(s, pos, beginQuoteString2)) {
-                result = beginQuoteString2;
-            } else if (startsWithFromPos(s, pos, endQuoteString)) {
-                result = endQuoteString;
-            } else if (startsWithFromPos(s, pos, endQuoteString2)) {
-                result = endQuoteString2;
-            } else if (startsWithFromPos(s, pos, separatorString)) {
-                result = separatorString;
-            } else if (startsWithFromPos(s, pos, separatorString2)) {
-                result = separatorString2;
-            } else if (startsWithFromPos(s, pos, escapeString)) {
-                result = escapeString;
-            }
-        }
-        return result;
-    }
-
-    /*
-     * justify if string src start with des from position pos
-     * @param src
-     * @param pos
-     * @param des
-     * @return
-     */
-    private boolean startsWithFromPos(String src, int pos, String des) {
-        if (null == src || null == des || NULL_STRING.equals(des)
-                || src.length() - pos < des.length()) {
-            return false;
-        }
-        int length = des.length();
-        int i = -1;
-        while (++i < length && src.charAt(pos + i) == des.charAt(i)) {
-            //empty body
-        }
-        return i == length;
-    }
-
-    /*
-     * -------------------------------------------------------------------
-     * Methods of interface Name
-     * -------------------------------------------------------------------
-     */
-    public Enumeration<String> getAll() {
-        return this.elem.elements();
-    }
-
-    public String get(int index) {
-        validateIndex(index, false);
-        return (String) elem.elementAt(index);
-    }
-
-    /*
-     * validate the index, if isInclude is true, index which equals to this.size() 
-     * is considered as valid, otherwise invalid
-     */
-    private void validateIndex(int index, boolean isInclude) {
-        if (0 > index || index > elem.size()
-                || (!isInclude && index == elem.size())) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-    }
-
-    public Name getPrefix(int index) {
-        validateIndex(index, true);
-        return new CompoundName(new Vector<String>(elem.subList(0, index)).elements(),
-                mySyntax);
-    }
-
-    public Name getSuffix(int index) {
-        validateIndex(index, false);
-        return new CompoundName(new Vector<String>(elem.subList(index, elem.size()))
-                .elements(), mySyntax);
-    }
-
-    public Name addAll(Name name) throws InvalidNameException {
-        return addAll(elem.size(), name);
-    }
-
-    public Name addAll(int index, Name name) throws InvalidNameException {
-        if (!(name instanceof CompoundName)) {
-            throw new InvalidNameException(name.toString()
-                    + " is not a compound name."); //$NON-NLS-1$
-        }
-        validateIndex(index, true);
-        Enumeration<String> enumeration = name.getAll();
-        while (enumeration.hasMoreElements()) {
-            elem.add(index++, enumeration.nextElement());
-        }
-        return this;
-    }
-
-    public Name add(String element) throws InvalidNameException {
-        if (element == null) {
-            throw new InvalidNameException("A flat name can only have a single component");
-        }
-        elem.add(element);
-        return this;
-    }
-
-    /**
-     * Insert an element within this CompoundName at the specified index.
-     * @return 				this <code>CompoundName</code>.
-     * @param element 		the String to insert
-     * @param index			the index of the element to insert - must be greater 
-     * 						than or equal to 0 and less than size().
-     * @throws ArrayIndexOutOfBoundsException 
-     * 						thrown when the index is invalid.
-     * @throws InvalidNameException 
-     * 						thrown if the insertion of the element results in 
-     * 						this <code>CompoundName</code> becoming invalid.
-     */
-    public Name add(int index, String element) throws InvalidNameException {
-        if (element == null) {
-            throw new InvalidNameException("A flat name can only zero or one component");
-        }
-        validateIndex(index, true);
-        elem.add(index, element);
-        return this;
-    }
-
-    /**
-     * Delete an element from this <code>CompoundName</code>.
-     * 
-     * @return 				the deleted element
-     * @param index			the index of the element to delete - must be greater 
-     * 						than or equal to 0 and less than size().
-     * @throws ArrayIndexOutOfBoundsException 
-     * 						thrown when the index is invalid.
-     * @throws InvalidNameException 
-     * 						thrown if the deletion of the element results in 
-     * 						this <code>CompoundName</code> becoming invalid.
-     */
-    public Object remove(int index) throws InvalidNameException {
-        validateIndex(index, false);
-        return elem.remove(index);
-    }
-
-    public Object clone() {
-        CompoundName newName = null;
-        try {
-            newName = (CompoundName) super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new Error("Failed to clone object of CompoundName class"); //$NON-NLS-1$
-        }
-        newName.mySyntax = (Properties) mySyntax.clone();
-        newName.elem = (Vector<String>) elem.clone();
-        return newName;
-    }
-
-    public int size() {
-        return elem.size();
-    }
-
-    public boolean isEmpty() {
-        return elem.isEmpty();
-    }
-
-    public boolean startsWith(Name name) {
-        if (!(name instanceof CompoundName)) {
-            return false;
-        }
-        return equals(name, 0, name.size());
-    }
-
-    public boolean endsWith(Name name) {
-        if (!(name instanceof CompoundName)) {
-            return false;
-        }
-        return equals(name, this.size() - name.size(), name
-                .size());
-    }
-
-    /*
-     * preprocess string according to trimblank and ignorecase properties
-     */
-    private String preProcess(String string, boolean caseInsensitive,
-            boolean removeBlanks) {
-        String result = string;
-        if (null != string && !"".equals(string)) { //$NON-NLS-1$
-            result = caseInsensitive ? result.toLowerCase() : result;
-            result = removeBlanks ? result.trim() : result;
-        }
-        return result;
-    }
-
-    /*
-     * Writes a serialized representation of the CompoundName. It starts with
-     * the properties, followed by an int which is the number of elements 
-     * in the name, and is followed by a String for each element. 
-     * @throws java.io.IOException if an error is encountered writing to the stream.
-     */
-    private void writeObject(ObjectOutputStream oos) throws IOException {
-        oos.defaultWriteObject();
-        oos.writeObject(mySyntax);
-        oos.writeInt(elem.size());
-        for (int i = 0; i < elem.size(); i++) {
-            String element = (String) elem.elementAt(i);
-            oos.writeObject(element);
-        }
-    }
-
-    /*
-     * Recreate a CompoundName from the data in the supplied stream.
-     * Additionally there are 2 protected fields which are not serializable.
-     * One of them is of a type which is a private class and cannot therefore
-     * be specified or implemented and so will be excluded from our deliverable.
-     * The one protected field which we can spec and implement is as follows:
-     * 		protected Properties mySyntax - The properties associated with a CompoundName.
-     
-     
-     * 
-     * @throws java.io.IOException if an error is encountered reading from the stream.
-     * @throws ClassNotFoundException.
-     */
-    private void readObject(ObjectInputStream ois)
-            throws ClassNotFoundException, IOException {
-        ois.defaultReadObject();
-        init(((Properties) ois.readObject()));
-        int size = ois.readInt();
-        elem = new Vector<String>();
-        for (int i = 0; i < size; i++) {
-            elem.add((String)ois.readObject());
-        }
-    }
-
-    /**
-     * Compare this <code>CompoundName</code> with the one supplied as a param.
-     * <p>
-     * See the definition of the <code>equals()</code> method to see how the 
-     * direction, ignorecase and trimblanks properties affect the comparison of 
-     * a <code>CompoundName</code>. Other than that the comparison is the same 
-     * as that for a <code>CompositeName</code>.</p>
-     * 
-     * @return  				a negative number means this is less than the 
-     *						supplied Object <code>o</code>. 
-     *						a positive number means this is greater than the 
-     *						supplied Object <code>o</code>.
-     *         				zero means the two objects are equal. 
-     * @param  o				the object to compare - cannot be null. 
-     * @throws ClassCastException 
-     *						when <code>o</code> is not a compatible class that 
-     *						can be compared or if the object to compare 
-     *						<code>o</code> is null.
-     */
-    public int compareTo(Object o) {
-        if (!(o instanceof CompoundName)) {
-            throw new ClassCastException();
-        }
-        int result = -1;
-        CompoundName otherName = (CompoundName) o;
-        Enumeration otherEnum = otherName.getAll();
-        String thisElement;
-        String otherElement;
-        int i;
-        for (i = 0; i < size() && otherEnum.hasMoreElements(); i++) {
-            thisElement = preProcess((String) elem.get(i), ignoreCase,
-                    trimBlanks);
-            otherElement = preProcess((String) otherEnum.nextElement(),
-                    ignoreCase, trimBlanks);
-            result = (null == thisElement ? (null == otherElement ? 0 : -1)
-                    : thisElement.compareTo(otherElement));
-            if (0 != result) {
-                return result;
-            }
-        }
-        if (i < size()) {
-            result = 1;
-        } else if (otherEnum.hasMoreElements()) {
-            result = -1;
-        }
-        return result;
-    }
-
-    /*
-     * -------------------------------------------------------------------
-     * Methods override parent class Object
-     * -------------------------------------------------------------------
-     */
-
-    /**
-     * Calculate the hashcode of this <code>CompoundName</code> by summing 
-     * the hashcodes of all of its elements. 
-     * <p>
-     * If jndi.syntax.trimblanks is set to true then remove any leading and 
-     * trailing blanks from the elements before calculating the hashcode. </p>
-     * <p>
-     * If jndi.syntax.ignorecase is set to true then use the lowercase version 
-     * of the element to calculate its hashcode.</p>
-     * 
-     * @return 				the hashcode of this object.
-     */
-    public int hashCode() {
-        int result = 0;
-        Enumeration enumeration = elem.elements();
-        while (enumeration.hasMoreElements()) {
-            result += preProcess((String) enumeration.nextElement(),
-                    ignoreCase, trimBlanks).hashCode();
-        }
-        return result;
-    }
-
-    /**
-     * Gets the string representation of this <code>CompoundName</code>.
-     * <p>
-     * This is generated by concatenating the elements together with the 
-     * separator string added as the separator between each of them. It may be 
-     * necessary to add quotes and escape string to preserve the meaning. 
-     * The resulting string should produce an equivalent <code>CompoundName</code> 
-     * when used to create a new instance.</p>
-     * 
-     * @return the string representation of this <code>CompoundName</code>. 
-     */
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        String begin = NULL_STRING.equals(beginQuoteString) ? beginQuoteString2
-                : beginQuoteString;
-        String end = NULL_STRING.equals(endQuoteString) ? endQuoteString2
-                : endQuoteString;
-        String separator = NULL_STRING.equals(separatorString) ? separatorString2
-                : separatorString;
-        if(RIGHT_TO_LEFT.equals(direction)){
-            for (int i = elem.size() - 1; i >= 0; i--) {
-                addElement(sb, i, separator, begin, end);
-            }
-        }else{
-            for (int i = 0; i < elem.size(); i++) {
-                addElement(sb, i, separator, begin, end);
-            }
-        }
-        if (size() * separator.length() < sb.length()) {
-            //if the name contains non-empty element, delete the last separator char, which is abundant
-            sb.setLength(sb.length() - separator.length());
-        }
-        return sb.toString();
-    }
-
-    private void addElement(StringBuffer sb, int index, String separator, String begin, String end) {
-        String elemString = elem.get(index);
-        if (0 == elemString.length()) {
-            // if empty element, append a separator and continue
-            sb.append(separator);
-            return;
-        }
-        int pos = sb.length();
-        sb.append(elemString);
-        if (!NULL_STRING.equals(begin) && !NULL_STRING.equals(end)
-                && !NULL_STRING.equals(separator)
-                && (0 <= elemString.indexOf(separator))) {
-            // if contains separator string, quoted it
-            sb.insert(pos, begin);
-            pos += begin.length();
-            // if quoted, then every endquote char must be escaped
-            for (int i = 0, j = 0; 0 <= (j = elemString.indexOf(end, i)); i = j
-                    + end.length()) {
-                sb.insert(pos + j, escapeString);
-                pos += escapeString.length();
-            }
-            sb.append(end);
-        } else {
-            if (startsWithFromPos(elemString, 0, beginQuoteString)
-                    || startsWithFromPos(elemString, 0, beginQuoteString2)) {
-                // if not quoted and start with begin quote string, escape it
-                sb.insert(pos, escapeString);
-                pos += escapeString.length();
-            }
-            // if not quoted, escape all separator string and all escape string
-            for (int i = 0; i < elemString.length();) {
-                if (startsWithFromPos(elemString, i, separatorString)) {
-                    sb.insert(pos + i, escapeString);
-                    pos += escapeString.length();
-                    i += separatorString.length();
-                } else if (startsWithFromPos(elemString, i, separatorString2)) {
-                    sb.insert(pos + i, escapeString);
-                    pos += escapeString.length();
-                    i += separatorString2.length();
-                } else if (startsWithFromPos(elemString, i, escapeString)) {
-                    sb.insert(pos + i, escapeString);
-                    pos += escapeString.length();
-                    i += escapeString.length();
-                } else {
-                    i++;
-                }
-            }
-        }
-        sb.append(separator);
-    }
-
-    /**
-     * Check if the supplied object <code>o</code> is equal to this
-     * <code>CompoundName</code>.
-     * <p>
-     * The supplied <code>Object o</code> may be null but that will cause
-     * false to be returned.
-     * </p>
-     * <p>
-     * The supplied <code>Object o</code> may be something other than a
-     * <code>CompoundName</code> but that will cause false to be returned.
-     * </p>
-     * <p>
-     * To be equal the supplied <code>CompoundName</code> must have the same
-     * number of elements and each element must match the corresponding element
-     * of this <code>CompoundName</code>. The properties
-     * jndi.syntax.ignorecase and jndi.syntax.trimblanks need to be considered
-     * if they have been set.
-     * </p>
-     * <p>
-     * The properties associated with the <code>CompoundName</code> must be
-     * taken into account but do not have to match. For example
-     * "home/jenningm-abc/.profile" with a direction of left to right is equal
-     * to ".profile/jenningm-abc/home" with a direction of right to left.
-     * </p>
-     * 
-     * @param o
-     *            the object to be compared
-     * @return true if supplied object <code>o</code> is equals to this
-     *         <code>CompoundName</code>, false otherwise
-     */
-    public boolean equals(Object o) {
-        if (!(o instanceof CompoundName)) {
-            return false;
-        }
-
-        //compare size
-        CompoundName otherName = (CompoundName) o;
-        final int size = otherName.size();
-        if (size != this.size()) {
-            return false;
-        }
-
-        //compare every element
-        return equals(otherName, 0, size);
-    }
-
-    /*
-     * compare this name to the supplied <code>name</code> from position 
-     * <code>start</code> to position <code>start</code>+
-     * <code>length</code>-1 
-     *
-     */
-    private boolean equals(Name name, int start, int length) {
-        if (length > this.size()) {
-            return false;
-        }
-        CompoundName otherName = (CompoundName) name;
-        Enumeration otherEnum = otherName.getAll();
-        String thisElement;
-        String otherElement;
-        for (int i = 0; i < length; i++) {
-            thisElement = preProcess((String) elem.get(i + start), ignoreCase,
-                    trimBlanks);
-            otherElement = preProcess((String) otherEnum.nextElement(),
-                    ignoreCase, trimBlanks);
-            if (!(null == thisElement ? null == otherElement : thisElement
-                    .equals(otherElement))) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
-
-/*
- * A useless class requied to satisfy the requirement for an 'impl'
- * field (see above).
- */
-class NameImpl {
-	protected NameImpl() {
-		super();
-	}
-}
-
-
+/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package javax.naming;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.Vector;
+
+/**
+ * A <code>CompoundName</code> is a series of string elements, and it represents 
+ * a name in a naming service within a single namespace. Typically these 
+ * names have a structure which is hierarchical. 
+ * <p>
+ * A <code>CompoundName</code> has a sequence of zero or more elements delimited 
+ * by the char specified in the property "jndi.syntax.separator". This property 
+ * is required except when the direction of the name is "flat" 
+ * (see jndi.syntax.direction). The property "jndi.syntax.separator2" allows for 
+ * the specification of an additional separator. A separator string will be 
+ * treated as normal characters if it is preceded by the escape string or is 
+ * within quotes.</p>
+ * <p>
+ * The property "jndi.syntax.direction" specifies the direction in which the name
+ * is read. Permitted values are "right_to_left", "left_to_right" and "flat". A 
+ * flat name does not have a hierarchical structure. If this property is not 
+ * specified then the default is "flat". If this property is specified with an 
+ * invalid value then an <code>IllegalArgumentException</code> should be raised.</p>
+ * <p>
+ * Each element can be accessed using its position. The first element is at 
+ * position 0. The direction of the name is important. When direction is 
+ * "left_to_right" then the leftmost element is at position 0. Conversely when 
+ * the direction is "right_to_left" then the rightmost element is at position 0.</p>
+ * <p>
+ * There are other properties which affect the syntax of a <code>CompoundName</code>. 
+ * The following properties are all optional:
+ * <ul>
+ * <li>
+ * jndi.syntax.escape -		Escape sequence,The escape sequence is used to escape 
+ * 							a quote, separator or escape. When preceded itself by 
+ * 							the escape sequence it is treated as ordinary characters.
+ * 							When it is followed by chars which are not quote or 
+ * 							separator strings then it is treated as ordinary characters</li>
+ * <li>
+ * jndi.syntax.beginquote -	Used as start of quoted string (Defaults to endquote)</li>
+ * <li>
+ * jndi.syntax.endquote - 	Used as end of quoted string (Defaults to beginquote)</li>
+ * <li>
+ * jndi.syntax.beginquote2 -	Additionally used as start of quoted string 
+ * 							(Defaults to endquote2)</li>
+ * <li>
+ * jndi.syntax.endquote2 - 	Additionally used as end of quoted string 
+ * 							(Defaults to beginquote2)</li>
+ * </ul>
+ * <p>
+ * When a non-escaped quote appears at the start of an element it must be matched at the
+ * end. That element can then be said to be quoted. When an escape sequence appears
+ * within a quoted element then it is treated as normal characters unless it precedes
+ * an occurrence of the quote in which case it is assumed that the quoted element
+ * contains a quote which is escaped.</p>
+ * <p>
+ * If the element does not start with a quote, then any quote strings within that
+ * element are just normal characters.</p>
+ * <p>
+ * <ul>
+ * <li>
+ * jndi.syntax.ignorecase -	If 'true' then ignore case when name elements are compared.
+ *  						If false or not set then case is important.</li>
+ * <li>
+ * jndi.syntax.trimblanks -	If 'true' then ignore leading & trailing blanks when name elements are compared.
+ * 							If false or not set then blanks are important.</li>
+ * </ul></p>
+ * <p>
+ * These 2 properties relate to names where the syntax includes attribute/content 
+ * pairs.
+ * <ul>
+ * <li>jndi.syntax.separator.ava</li>
+ * <li>jndi.syntax.separator.typeval</li>
+ * </ul>
+ * For example the LDAP name, "CN=Mandy Jennings, O=Apache, C=UK".
+ * In this example the pair separator jndi.syntax.separator.ava is ',', and the 
+ * character that separates pairs jndi.syntax.separator.typeval is '='. See 
+ * RFC1779 for LDAP naming conventions.</p>
+ * <p>
+ * The jndi.syntax.separator.ava is not used when manipulating <code>CompoundName</code>. 
+ * The jndi.syntax.separator is still used to separate elements.</p>
+ * <p>
+ * The <code>CompoundName</code> needs to be aware of the jndi.syntax.separator.typeval
+ * in case of the instance where a quoted string is used to provide the content
+ * of a pair.</p>
+ * <p>
+ * Consider the string "CN=$Mandy Jennings, O=Apache, C=UK" with
+ * <ul>
+ * <li>
+ * jndi.syntax.direction         set to "right_to_left"</li>
+ * <li>
+ * jndi.syntax.separator         set to ","</li>
+ * <li>
+ * jndi.syntax.separator.typeval set to "="</li>
+ * </ul>
+ * When no jndi.syntax.beginquote is set then this creates a valid <code>CompoundName</code>
+ * with 3 elements.</p>
+ * <p>
+ * If jndi.syntax.beginquote is then set to "$" the name becomes invalid as the
+ * content part of the pair CN=$Mandy Jennings has a mismatched quote.</p>
+ * <p>
+ * The string "CN=$Mandy Jennings$, O=Apache, C=UK" would be fine as the $ quotes
+ * round Mandy Jennings now balance.</p>
+ * <p>
+ * A <code>CompoundName</code> may be empty. An empty <code>CompoundName</code> has no elements.
+ * Elements may also be empty.</p> 
+ * 
+ * <pre>
+ * Some Examples:
+ * ==============
+ * 
+ * Consider the following compound name from the file system namespace:
+ *     "home/jenningm-abc/.profile" 
+ * 
+ * jndi.syntax.separator is set to '/' as in the UNIX filesystem.
+ * This name has 3 elements:
+ *     home jenningm-abc and .profile
+ * The direction should be left_to_right as in the UNIX filesystem
+ * The element at position 0 would be home.
+ * 
+ * 
+ * Consider if jndi.syntax.separator had been set to '-' then this name 
+ * would have 2 elements:
+ *     home/jenningm and abc/.profile
+ * If the direction was right_to_left then the element at position 0
+ * would be abc/.profile.
+ * 
+ * Consider the name "&lt;ab&lt;cd&gt;ef&gt;" where jndi.syntax.beginquote is &lt;
+ * and jndi.syntax.endquote is &gt;. This will give rise to an 
+ * InvalidNameException because a close quote was encountered before
+ * the end of an element. The same is also true for "&lt;abcd&gt;ef&gt;".
+ * If the name was "ab&lt;cd&gt;ef" then this would be valid and there would
+ * be one element ab&lt;cd&gt;ef.
+ * However if the name was "&lt;abcdef&gt;" there would be one element abcdef.
+ * 
+ * An empty <code>CompoundName</code> is the name "" and has no elements.
+ * 
+ * When jndi.syntax.beginquote is set to " and beginquote2 is set to '
+ * the behaviour is simliar to CompositeName - 
+ * The name "\"abcd" gives an InvalidNameException as there is no closing quote.
+ * The name "'\"abcd'" gives one element of value "abcd.
+ * The name "\\abcd" gives one element of value \abcd. 
+ *  
+ * Assuming:
+ *     jndi.syntax.separator is "/"
+ *     jndi.syntax.direction is "left_to_right"
+ * then
+ *     "" is empty. It has no elements.
+ *     "/" has one empty element.
+ *     "//" has 2 empty elements.
+ *     "/a/" has 3 elements the middle one is set to a.
+ *     "///" has 3 empty elements.
+ *     "//a/" has 4 elements, the last but one is set to a.
+ * 
+ *
+ * Assuming the only properties set are: 
+ *     jndi.syntax.separator is "/"
+ *     jndi.syntax.direction is "left_to_right"
+ * then the String
+ *     "\"" has one element with the value "
+ *     "\\\"" has one element with the value \"
+ *     "\\\"'" has one element with the value \"'
+ * 
+ * Assuming the only properties set are:
+ *     jndi.syntax.separator is "/"
+ *     jndi.syntax.direction is "left_to_right"
+ *     jndi.syntax.beginquote is "\""
+ * 
+ * then the String
+ *     "\"" is invalid because of no closing quote
+ *     "\\\"" has one element with the value \"
+ *     "\\\"'" has one element with the value \"'
+ * 
+ * 
+ * Assuming the only properties set are:
+ *     jndi.syntax.separator is "/"
+ *     jndi.syntax.direction is "left_to_right"
+ *     jndi.syntax.beginquote is "\""
+ *     jndi.syntax.beginquote2 is "\'"
+ * then the String
+ *     "\"" is invalid because of no closing quote
+ *     "\\\"" has one element with the value \"
+ *     "\\\"'" has one element with the value \"'
+ *     "'\\" is invalid because of no closing quote
+ * </pre>
+ * 
+ * 
+ */
+
+public class CompoundName implements Name {
+
+    /*
+     * -------------------------------------------------------------------
+     * Constants
+     * -------------------------------------------------------------------
+     */
+
+    /*
+     *=============
+     *Serialization
+     *=============
+     *
+     *Note: For serialization purposes, the specified serialVersionUID must be used.
+     *This class does not have serializable fields specified. Instead the readObject
+     *and writeObject methods are overidden.
+     */
+    static final long serialVersionUID = 3513100557083972036L; // J2SE 1.4.2
+
+    //const for property key
+    private static final String SEPARATOR = "jndi.syntax.separator"; //$NON-NLS-1$
+
+    private static final String SEPARATOR_AVA = "jndi.syntax.separator.ava"; //$NON-NLS-1$
+
+    private static final String SEPARATOR_TYPEVAL = "jndi.syntax.separator.typeval"; //$NON-NLS-1$
+
+    private static final String ESCAPE = "jndi.syntax.escape"; //$NON-NLS-1$
+
+    private static final String BEGIN_QUOTE = "jndi.syntax.beginquote"; //$NON-NLS-1$
+
+    private static final String END_QUOTE = "jndi.syntax.endquote"; //$NON-NLS-1$
+
+    private static final String BEGIN_QUOTE2 = "jndi.syntax.beginquote2"; //$NON-NLS-1$
+
+    private static final String END_QUOTE2 = "jndi.syntax.endquote2"; //$NON-NLS-1$
+
+    private static final String IGNORE_CASE = "jndi.syntax.ignorecase"; //$NON-NLS-1$
+
+    private static final String TRIM_BLANKS = "jndi.syntax.trimblanks"; //$NON-NLS-1$
+
+    private static final String DIRECTION = "jndi.syntax.direction"; //$NON-NLS-1$
+
+    private static final String SEPARATOR2 = "jndi.syntax.separator2"; //$NON-NLS-1$
+
+    //const for direction
+    private static final String LEFT_TO_RIGHT = "left_to_right"; //$NON-NLS-1$
+
+    private static final String RIGHT_TO_LEFT = "right_to_left"; //$NON-NLS-1$
+
+    private static final String FLAT = "flat"; //$NON-NLS-1$
+
+    // alphabets consts
+    private static final String NULL_STRING = ""; //$NON-NLS-1$
+
+    //states consts
+    private static final int NORMAL_STATUS = 0;
+
+    private static final int QUOTE1_STATUS = 1;
+
+    private static final int QUOTE2_STATUS = 2;
+
+    private static final int INIT_STATUS = 3;
+
+    private static final int QUOTEEND_STATUS = 4;
+
+    /*
+     * ============
+     * Variables
+     * ============ 
+     */
+    //properties variables
+    private transient String separatorString;
+
+    private transient String separatorString2;
+
+    private transient String escapeString;
+
+    private transient String endQuoteString;
+
+    private transient String endQuoteString2;
+
+    private transient String beginQuoteString;
+
+    private transient String beginQuoteString2;
+
+    private transient String sepAvaString;
+
+    private transient String sepTypeValString;
+
+    private transient String direction;
+
+    private transient boolean trimBlanks;
+
+    private transient boolean ignoreCase;
+
+    private transient boolean flat;
+
+    //elements of compound name
+    private transient Vector<String> elem;
+
+    //property setting
+    protected transient Properties mySyntax;
+    
+    /*
+     * The specification calls for a protected variable called 'impl' which is of a non-API
+     * type.  I believe this is an error in the spec, but to be compliant we have implemented
+     * this as a useless class (below).
+     */
+    protected transient javax.naming.NameImpl impl = new NameImpl();
+
+    /*
+     *============
+     *Constructors
+     *============ 
+     */
+
+    /**
+     * Constructs a <code>CompoundName</code> with supplied <code>Enumeration</code> 
+     * and <code>Properties</code>
+     * 
+     * @param elements		an enumeration of name elements, cannot be null
+     * @param props			the properties, cannot be null but may be empty. 
+     * 						If empty, the direction defaults to flat and no 
+     * 						other properties are required.
+     */
+    protected CompoundName(Enumeration<String> elements, Properties props) {
+        if (null == props || null == elements) {
+            throw new NullPointerException();
+        }
+        init(props);
+        this.elem = new Vector<String>();
+        while (elements.hasMoreElements()) {
+            this.elem.add(elements.nextElement());
+        }
+    }
+
+    /**
+     * Constructs a <code>CompoundName</code> with supplied <code>String</code> 
+     * and <code>Properties</code>,  taking the supplied <code>s</code> and 
+     * breaking it down into its elements. 
+     *
+     * @param s				a string containing the full compound name
+     * @param props			the properties, cannot be null but may be empty for a flat name
+     * @throws InvalidNameException 
+     * 						thrown if the supplied <code>String s</code> is invalid
+     * @throws NullPointerException 
+     * 						thrown if the supplied <code>String s</code> is null
+     */
+    public CompoundName(String s, Properties props) throws InvalidNameException {
+        if (null == s || null == props) {
+            throw new NullPointerException();
+        }
+        init(props);
+        parseName(s);
+    }
+
+    /*
+     * init instance variables
+     */
+    private void init(Properties props) {
+        trimBlanks = false;
+        ignoreCase = false;
+        this.mySyntax = (Properties) props.clone();
+        String property;
+
+        //read property settings
+        // direction's default value is FLAT
+        direction = null == (property = props.getProperty(DIRECTION)) ? FLAT
+                : property;
+        //if direction value must equals to one of FLAT, LEFT_TO_RIGHT and RIGHT_TO_LEFT, exception throwed 
+        if (!LEFT_TO_RIGHT.equals(direction)
+                && !RIGHT_TO_LEFT.equals(direction) && !FLAT.equals(direction)) {
+            throw new IllegalArgumentException(
+                    "Illegal direction property value, which must be one of right_to_left, left_to_right or flat"); //$NON-NLS-1$
+        }
+        flat = FLAT.equals(direction);
+
+        separatorString = flat ? NULL_STRING : props.getProperty(SEPARATOR);
+        //		if direction is not FLAT, separator must be set
+        if (null == separatorString && !flat) {
+            throw new IllegalArgumentException(
+                    "jndi.syntax.separator property must be set when jndi.syntax.direction is not flat"); //$NON-NLS-1$
+        }
+        separatorString2 = (flat || null == (property = props
+                .getProperty(SEPARATOR2))) ? NULL_STRING : property;
+
+        //ignorecase default value is false
+        ignoreCase = null == (property = props.getProperty(IGNORE_CASE)) ? false
+                : Boolean.valueOf(property).booleanValue();
+        //trimblanks default value is false
+        trimBlanks = null == (property = props.getProperty(TRIM_BLANKS)) ? false
+                : Boolean.valueOf(property).booleanValue();
+        escapeString = null == (property = props.getProperty(ESCAPE)) ? NULL_STRING
+                : property;
+        beginQuoteString = null == (property = props.getProperty(BEGIN_QUOTE)) ? NULL_STRING
+                : property;
+        beginQuoteString2 = null == (property = props.getProperty(BEGIN_QUOTE2)) ? NULL_STRING
+                : property;
+        //end quote string default value is begin quote string
+        endQuoteString = null == (property = props.getProperty(END_QUOTE)) ? beginQuoteString
+                : property;
+        //begin quote string default value is end quote string
+        if (NULL_STRING.equals(beginQuoteString)) {
+            beginQuoteString = endQuoteString;
+        }
+        //end quote string2 default value is begin quote string2
+        endQuoteString2 = null == (property = props.getProperty(END_QUOTE2)) ? beginQuoteString2
+                : property;
+        //begin quote string2 default value is end quote string2
+        if (NULL_STRING.equals(beginQuoteString2)) {
+            beginQuoteString2 = endQuoteString2;
+        }
+
+        sepTypeValString = null == (property = props
+                .getProperty(SEPARATOR_TYPEVAL)) ? NULL_STRING : property;
+        sepAvaString = null == (property = props.getProperty(SEPARATOR_AVA)) ? NULL_STRING
+                : property;
+    }
+
+    /*
+     * parse name from string to elements
+     */
+    private void parseName(String s) throws InvalidNameException {
+        this.elem = new Vector<String>();
+        if ("".equals(s)) { //$NON-NLS-1$
+            // if empty string, return empty vector
+            return;
+        }
+
+        //init variables
+        int status = INIT_STATUS;
+        StringBuffer element = new StringBuffer();
+        int pos = 0;
+        int length = s.length();
+        boolean hasNotNullElement = false;
+        boolean includeQuote = false;
+
+        //scan name
+        while (pos < length) {
+            if (startsWithFromPos(s, pos, endQuoteString)
+                    && status == QUOTE1_STATUS) {
+                status = QUOTEEND_STATUS;
+                pos += addBuffer(element, endQuoteString, includeQuote);
+            } else if (startsWithFromPos(s, pos, endQuoteString2)
+                    && status == QUOTE2_STATUS) {
+                status = QUOTEEND_STATUS;
+                pos += addBuffer(element, endQuoteString2, includeQuote);
+            } else if (startsWithFromPos(s, pos, beginQuoteString)
+                    && status == INIT_STATUS) {
+                hasNotNullElement = true;
+                status = QUOTE1_STATUS;
+                pos += addBuffer(element, beginQuoteString, includeQuote);
+            } else if (startsWithFromPos(s, pos, beginQuoteString2)
+                    && status == INIT_STATUS) {
+                hasNotNullElement = true;
+                status = QUOTE2_STATUS;
+                pos += addBuffer(element, beginQuoteString2, includeQuote);
+            } else if (startsWithFromPos(s, pos, separatorString)
+                    && (!flat)
+                    && (status == INIT_STATUS || status == QUOTEEND_STATUS || status == NORMAL_STATUS)) {
+                hasNotNullElement = hasNotNullElement || element.length() > 0;
+                addElement(element);
+                status = INIT_STATUS;
+                pos += separatorString.length();
+                includeQuote = false;
+            } else if (startsWithFromPos(s, pos, separatorString2)
+                    && (!flat)
+                    && (status == INIT_STATUS || status == QUOTEEND_STATUS || status == NORMAL_STATUS)) {
+                hasNotNullElement = hasNotNullElement || element.length() > 0;
+                addElement(element);
+                status = INIT_STATUS;
+                pos += separatorString2.length();
+                includeQuote = false;
+            } else if (startsWithFromPos(s, pos, escapeString)) {
+                pos += escapeString.length();
+                if (pos == s.length()) {
+                    //if this escape char is last character, throw exception
+                    throw new InvalidNameException(new StringBuffer(50).append(
+                            "The ") //$NON-NLS-1$
+                            .append(escapeString).append(
+                                    " cannot be at end of the component") //$NON-NLS-1$
+                            .toString());
+                }
+                //if one escape char followed by a special char, append the special char to current element
+                String str = extractEscapedString(s, pos, status);
+                if (null == str) {
+                    pos -= escapeString.length();
+                    element.append(s.charAt(pos++));
+                } else {
+                    pos += str.length();
+                    element.append(str);
+                }
+
+            } else if (startsWithFromPos(s, pos, sepTypeValString)
+                    && (status == INIT_STATUS || status == NORMAL_STATUS)) {
+                includeQuote = true;
+                pos += addBuffer(element, sepTypeValString, true);
+                status = INIT_STATUS;
+            } else if (startsWithFromPos(s, pos, sepAvaString)
+                    && (status == INIT_STATUS || status == NORMAL_STATUS)) {
+                includeQuote = true;
+                pos += addBuffer(element, sepAvaString, true);
+                status = INIT_STATUS;
+            } else if (status == QUOTEEND_STATUS) {
+                throw new InvalidNameException(
+                        s
+                                + ": close quote must appears at end of component in quoted string"); //$NON-NLS-1$
+            } else {
+                status = status == INIT_STATUS ? NORMAL_STATUS : status;
+                element.append(s.charAt(pos++));
+            }
+        }
+        if (QUOTE1_STATUS != status && QUOTE2_STATUS != status) {
+            hasNotNullElement = hasNotNullElement || element.length() > 0;
+            addElement(element);
+        } else {
+            throw new InvalidNameException(s
+                    + ": close quote is required for quoted string"); //$NON-NLS-1$
+        }
+        if (!hasNotNullElement) {
+            elem.remove(elem.size() - 1);
+        }
+    }
+
+    /*
+     * add des parameter to stringbuffer if include is true
+     */
+    private int addBuffer(StringBuffer buffer, String des, boolean include) {
+        if (include) {
+            buffer.append(des);
+        }
+        return des.length();
+    }
+
+    /*
+     * add current content of supplied string buffer as one element of this 
+     * CompoundName and reset the string buffer to empty
+     */
+    private void addElement(StringBuffer element) {
+        if (LEFT_TO_RIGHT == direction) {
+            elem.add(element.toString());
+        } else {
+            elem.add(0, element.toString());
+        }
+        element.setLength(0);
+    }
+
+    /*
+     * find string to be escaped, if cannot find special string(which means, 
+     * quote, separator and escape), return null 
+     */
+    private String extractEscapedString(String s, int pos, int status) {
+        String result = null;
+        if (status == QUOTE1_STATUS
+                && startsWithFromPos(s, pos, endQuoteString)) {
+            result = endQuoteString;
+        } else if (status == QUOTE2_STATUS
+                && startsWithFromPos(s, pos, endQuoteString2)) {
+            result = endQuoteString2;
+        } else if (status != QUOTE1_STATUS && status != QUOTE2_STATUS) {
+            if (startsWithFromPos(s, pos, beginQuoteString)) {
+                result = beginQuoteString;
+            } else if (startsWithFromPos(s, pos, beginQuoteString2)) {
+                result = beginQuoteString2;
+            } else if (startsWithFromPos(s, pos, endQuoteString)) {
+                result = endQuoteString;
+            } else if (startsWithFromPos(s, pos, endQuoteString2)) {
+                result = endQuoteString2;
+            } else if (startsWithFromPos(s, pos, separatorString)) {
+                result = separatorString;
+            } else if (startsWithFromPos(s, pos, separatorString2)) {
+                result = separatorString2;
+            } else if (startsWithFromPos(s, pos, escapeString)) {
+                result = escapeString;
+            }
+        }
+        return result;
+    }
+
+    /*
+     * justify if string src start with des from position pos
+     * @param src
+     * @param pos
+     * @param des
+     * @return
+     */
+    private boolean startsWithFromPos(String src, int pos, String des) {
+        if (null == src || null == des || NULL_STRING.equals(des)
+                || src.length() - pos < des.length()) {
+            return false;
+        }
+        int length = des.length();
+        int i = -1;
+        while (++i < length && src.charAt(pos + i) == des.charAt(i)) {
+            //empty body
+        }
+        return i == length;
+    }
+
+    /*
+     * -------------------------------------------------------------------
+     * Methods of interface Name
+     * -------------------------------------------------------------------
+     */
+    public Enumeration<String> getAll() {
+        return this.elem.elements();
+    }
+
+    public String get(int index) {
+        validateIndex(index, false);
+        return (String) elem.elementAt(index);
+    }
+
+    /*
+     * validate the index, if isInclude is true, index which equals to this.size() 
+     * is considered as valid, otherwise invalid
+     */
+    private void validateIndex(int index, boolean isInclude) {
+        if (0 > index || index > elem.size()
+                || (!isInclude && index == elem.size())) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+    }
+
+    public Name getPrefix(int index) {
+        validateIndex(index, true);
+        return new CompoundName(new Vector<String>(elem.subList(0, index)).elements(),
+                mySyntax);
+    }
+
+    public Name getSuffix(int index) {
+        validateIndex(index, false);
+        return new CompoundName(new Vector<String>(elem.subList(index, elem.size()))
+                .elements(), mySyntax);
+    }
+
+    public Name addAll(Name name) throws InvalidNameException {
+        return addAll(elem.size(), name);
+    }
+
+    public Name addAll(int index, Name name) throws InvalidNameException {
+        if (!(name instanceof CompoundName)) {
+            throw new InvalidNameException(name.toString()
+                    + " is not a compound name."); //$NON-NLS-1$
+        }
+        validateIndex(index, true);
+        Enumeration<String> enumeration = name.getAll();
+        while (enumeration.hasMoreElements()) {
+            elem.add(index++, enumeration.nextElement());
+        }
+        return this;
+    }
+
+    public Name add(String element) throws InvalidNameException {
+        if (element == null) {
+            throw new InvalidNameException("A flat name can only have a single component");
+        }
+        elem.add(element);
+        return this;
+    }
+
+    /**
+     * Insert an element within this CompoundName at the specified index.
+     * @return 				this <code>CompoundName</code>.
+     * @param element 		the String to insert
+     * @param index			the index of the element to insert - must be greater 
+     * 						than or equal to 0 and less than size().
+     * @throws ArrayIndexOutOfBoundsException 
+     * 						thrown when the index is invalid.
+     * @throws InvalidNameException 
+     * 						thrown if the insertion of the element results in 
+     * 						this <code>CompoundName</code> becoming invalid.
+     */
+    public Name add(int index, String element) throws InvalidNameException {
+        if (element == null) {
+            throw new InvalidNameException("A flat name can only zero or one component");
+        }
+        validateIndex(index, true);
+        elem.add(index, element);
+        return this;
+    }
+
+    /**
+     * Delete an element from this <code>CompoundName</code>.
+     * 
+     * @return 				the deleted element
+     * @param index			the index of the element to delete - must be greater 
+     * 						than or equal to 0 and less than size().
+     * @throws ArrayIndexOutOfBoundsException 
+     * 						thrown when the index is invalid.
+     * @throws InvalidNameException 
+     * 						thrown if the deletion of the element results in 
+     * 						this <code>CompoundName</code> becoming invalid.
+     */
+    public Object remove(int index) throws InvalidNameException {
+        validateIndex(index, false);
+        return elem.remove(index);
+    }
+
+    public Object clone() {
+        CompoundName newName = null;
+        try {
+            newName = (CompoundName) super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new Error("Failed to clone object of CompoundName class"); //$NON-NLS-1$
+        }
+        newName.mySyntax = (Properties) mySyntax.clone();
+        newName.elem = (Vector<String>) elem.clone();
+        return newName;
+    }
+
+    public int size() {
+        return elem.size();
+    }
+
+    public boolean isEmpty() {
+        return elem.isEmpty();
+    }
+
+    public boolean startsWith(Name name) {
+        if (!(name instanceof CompoundName)) {
+            return false;
+        }
+        return equals(name, 0, name.size());
+    }
+
+    public boolean endsWith(Name name) {
+        if (!(name instanceof CompoundName)) {
+            return false;
+        }
+        return equals(name, this.size() - name.size(), name
+                .size());
+    }
+
+    /*
+     * preprocess string according to trimblank and ignorecase properties
+     */
+    private String preProcess(String string, boolean caseInsensitive,
+            boolean removeBlanks) {
+        String result = string;
+        if (null != string && !"".equals(string)) { //$NON-NLS-1$
+            result = caseInsensitive ? result.toLowerCase() : result;
+            result = removeBlanks ? result.trim() : result;
+        }
+        return result;
+    }
+
+    /*
+     * Writes a serialized representation of the CompoundName. It starts with
+     * the properties, followed by an int which is the number of elements 
+     * in the name, and is followed by a String for each element. 
+     * @throws java.io.IOException if an error is encountered writing to the stream.
+     */
+    private void writeObject(ObjectOutputStream oos) throws IOException {
+        oos.defaultWriteObject();
+        oos.writeObject(mySyntax);
+        oos.writeInt(elem.size());
+        for (int i = 0; i < elem.size(); i++) {
+            String element = (String) elem.elementAt(i);
+            oos.writeObject(element);
+        }
+    }
+
+    /*
+     * Recreate a CompoundName from the data in the supplied stream.
+     * Additionally there are 2 protected fields which are not serializable.
+     * One of them is of a type which is a private class and cannot therefore
+     * be specified or implemented and so will be excluded from our deliverable.
+     * The one protected field which we can spec and implement is as follows:
+     * 		protected Properties mySyntax - The properties associated with a CompoundName.
+     
+     
+     * 
+     * @throws java.io.IOException if an error is encountered reading from the stream.
+     * @throws ClassNotFoundException.
+     */
+    private void readObject(ObjectInputStream ois)
+            throws ClassNotFoundException, IOException {
+        ois.defaultReadObject();
+        init(((Properties) ois.readObject()));
+        int size = ois.readInt();
+        elem = new Vector<String>();
+        for (int i = 0; i < size; i++) {
+            elem.add((String)ois.readObject());
+        }
+    }
+
+    /**
+     * Compare this <code>CompoundName</code> with the one supplied as a param.
+     * <p>
+     * See the definition of the <code>equals()</code> method to see how the 
+     * direction, ignorecase and trimblanks properties affect the comparison of 
+     * a <code>CompoundName</code>. Other than that the comparison is the same 
+     * as that for a <code>CompositeName</code>.</p>
+     * 
+     * @return  				a negative number means this is less than the 
+     *						supplied Object <code>o</code>. 
+     *						a positive number means this is greater than the 
+     *						supplied Object <code>o</code>.
+     *         				zero means the two objects are equal. 
+     * @param  o				the object to compare - cannot be null. 
+     * @throws ClassCastException 
+     *						when <code>o</code> is not a compatible class that 
+     *						can be compared or if the object to compare 
+     *						<code>o</code> is null.
+     */
+    public int compareTo(Object o) {
+        if (!(o instanceof CompoundName)) {
+            throw new ClassCastException();
+        }
+        int result = -1;
+        CompoundName otherName = (CompoundName) o;
+        Enumeration otherEnum = otherName.getAll();
+        String thisElement;
+        String otherElement;
+        int i;
+        for (i = 0; i < size() && otherEnum.hasMoreElements(); i++) {
+            thisElement = preProcess((String) elem.get(i), ignoreCase,
+                    trimBlanks);
+            otherElement = preProcess((String) otherEnum.nextElement(),
+                    ignoreCase, trimBlanks);
+            result = (null == thisElement ? (null == otherElement ? 0 : -1)
+                    : thisElement.compareTo(otherElement));
+            if (0 != result) {
+                return result;
+            }
+        }
+        if (i < size()) {
+            result = 1;
+        } else if (otherEnum.hasMoreElements()) {
+            result = -1;
+        }
+        return result;
+    }
+
+    /*
+     * -------------------------------------------------------------------
+     * Methods override parent class Object
+     * -------------------------------------------------------------------
+     */
+
+    /**
+     * Calculate the hashcode of this <code>CompoundName</code> by summing 
+     * the hashcodes of all of its elements. 
+     * <p>
+     * If jndi.syntax.trimblanks is set to true then remove any leading and 
+     * trailing blanks from the elements before calculating the hashcode. </p>
+     * <p>
+     * If jndi.syntax.ignorecase is set to true then use the lowercase version 
+     * of the element to calculate its hashcode.</p>
+     * 
+     * @return 				the hashcode of this object.
+     */
+    public int hashCode() {
+        int result = 0;
+        Enumeration enumeration = elem.elements();
+        while (enumeration.hasMoreElements()) {
+            result += preProcess((String) enumeration.nextElement(),
+                    ignoreCase, trimBlanks).hashCode();
+        }
+        return result;
+    }
+
+    /**
+     * Gets the string representation of this <code>CompoundName</code>.
+     * <p>
+     * This is generated by concatenating the elements together with the 
+     * separator string added as the separator between each of them. It may be 
+     * necessary to add quotes and escape string to preserve the meaning. 
+     * The resulting string should produce an equivalent <code>CompoundName</code> 
+     * when used to create a new instance.</p>
+     * 
+     * @return the string representation of this <code>CompoundName</code>. 
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        String begin = NULL_STRING.equals(beginQuoteString) ? beginQuoteString2
+                : beginQuoteString;
+        String end = NULL_STRING.equals(endQuoteString) ? endQuoteString2
+                : endQuoteString;
+        String separator = NULL_STRING.equals(separatorString) ? separatorString2
+                : separatorString;
+        if(RIGHT_TO_LEFT.equals(direction)){
+            for (int i = elem.size() - 1; i >= 0; i--) {
+                addElement(sb, i, separator, begin, end);
+            }
+        }else{
+            for (int i = 0; i < elem.size(); i++) {
+                addElement(sb, i, separator, begin, end);
+            }
+        }
+        if (size() * separator.length() < sb.length()) {
+            //if the name contains non-empty element, delete the last separator char, which is abundant
+            sb.setLength(sb.length() - separator.length());
+        }
+        return sb.toString();
+    }
+
+    private void addElement(StringBuffer sb, int index, String separator, String begin, String end) {
+        String elemString = elem.get(index);
+        if (0 == elemString.length()) {
+            // if empty element, append a separator and continue
+            sb.append(separator);
+            return;
+        }
+        int pos = sb.length();
+        sb.append(elemString);
+        if (!NULL_STRING.equals(begin) && !NULL_STRING.equals(end)
+                && !NULL_STRING.equals(separator)
+                && (0 <= elemString.indexOf(separator))) {
+            // if contains separator string, quoted it
+            sb.insert(pos, begin);
+            pos += begin.length();
+            // if quoted, then every endquote char must be escaped
+            for (int i = 0, j = 0; 0 <= (j = elemString.indexOf(end, i)); i = j
+                    + end.length()) {
+                sb.insert(pos + j, escapeString);
+                pos += escapeString.length();
+            }
+            sb.append(end);
+        } else {
+            if (startsWithFromPos(elemString, 0, beginQuoteString)
+                    || startsWithFromPos(elemString, 0, beginQuoteString2)) {
+                // if not quoted and start with begin quote string, escape it
+                sb.insert(pos, escapeString);
+                pos += escapeString.length();
+            }
+            // if not quoted, escape all separator string and all escape string
+            for (int i = 0; i < elemString.length();) {
+                if (startsWithFromPos(elemString, i, separatorString)) {
+                    sb.insert(pos + i, escapeString);
+                    pos += escapeString.length();
+                    i += separatorString.length();
+                } else if (startsWithFromPos(elemString, i, separatorString2)) {
+                    sb.insert(pos + i, escapeString);
+                    pos += escapeString.length();
+                    i += separatorString2.length();
+                } else if (startsWithFromPos(elemString, i, escapeString)) {
+                    sb.insert(pos + i, escapeString);
+                    pos += escapeString.length();
+                    i += escapeString.length();
+                } else {
+                    i++;
+                }
+            }
+        }
+        sb.append(separator);
+    }
+
+    /**
+     * Check if the supplied object <code>o</code> is equal to this
+     * <code>CompoundName</code>.
+     * <p>
+     * The supplied <code>Object o</code> may be null but that will cause
+     * false to be returned.
+     * </p>
+     * <p>
+     * The supplied <code>Object o</code> may be something other than a
+     * <code>CompoundName</code> but that will cause false to be returned.
+     * </p>
+     * <p>
+     * To be equal the supplied <code>CompoundName</code> must have the same
+     * number of elements and each element must match the corresponding element
+     * of this <code>CompoundName</code>. The properties
+     * jndi.syntax.ignorecase and jndi.syntax.trimblanks need to be considered
+     * if they have been set.
+     * </p>
+     * <p>
+     * The properties associated with the <code>CompoundName</code> must be
+     * taken into account but do not have to match. For example
+     * "home/jenningm-abc/.profile" with a direction of left to right is equal
+     * to ".profile/jenningm-abc/home" with a direction of right to left.
+     * </p>
+     * 
+     * @param o
+     *            the object to be compared
+     * @return true if supplied object <code>o</code> is equals to this
+     *         <code>CompoundName</code>, false otherwise
+     */
+    public boolean equals(Object o) {
+        if (!(o instanceof CompoundName)) {
+            return false;
+        }
+
+        //compare size
+        CompoundName otherName = (CompoundName) o;
+        final int size = otherName.size();
+        if (size != this.size()) {
+            return false;
+        }
+
+        //compare every element
+        return equals(otherName, 0, size);
+    }
+
+    /*
+     * compare this name to the supplied <code>name</code> from position 
+     * <code>start</code> to position <code>start</code>+
+     * <code>length</code>-1 
+     *
+     */
+    private boolean equals(Name name, int start, int length) {
+        if (length > this.size()) {
+            return false;
+        }
+        CompoundName otherName = (CompoundName) name;
+        Enumeration otherEnum = otherName.getAll();
+        String thisElement;
+        String otherElement;
+        for (int i = 0; i < length; i++) {
+            thisElement = preProcess((String) elem.get(i + start), ignoreCase,
+                    trimBlanks);
+            otherElement = preProcess((String) otherEnum.nextElement(),
+                    ignoreCase, trimBlanks);
+            if (!(null == thisElement ? null == otherElement : thisElement
+                    .equals(otherElement))) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+
+/*
+ * A useless class requied to satisfy the requirement for an 'impl'
+ * field (see above).
+ */
+class NameImpl {
+	protected NameImpl() {
+		super();
+	}
+}
+
+

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/CompoundName.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/ConfigurationException.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message