/*
 * Copyright 2003-2004 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.naming.ldap;

import javax.naming.Name;
import javax.naming.InvalidNameException;

import java.util.Enumeration;
import java.util.Collection;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Collections;

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;

/**
 * This class represents a distinguished name as specified by
 * <a href="http://ietf.org//rfc/rfc2253.txt">RFC 2253</a>.
 * A distinguished name, or DN, is composed of an ordered list of
 * components called <em>relative distinguished name</em>s, or RDNs.
 * Details of a DN's syntax are described in RFC 2253.
 *<p>
 * This class resolves a few ambiguities found in RFC 2253
 * as follows:
 * <ul>
 * <li> RFC 2253 leaves the term "whitespace" undefined. The
 *      ASCII space character 0x20 (" ") is used in its place.
 * <li> Whitespace is allowed on either side of ',', ';', '=', and '+'.
 *      Such whitespace is accepted but not generated by this code,
 *      and is ignored when comparing names.
 * <li> AttributeValue strings containing '=' or non-leading '#'
 *      characters (unescaped) are accepted.
 * </ul>
 *<p>
 * String names passed to <code>LdapName</code> or returned by it
 * use the full Unicode character set. They may also contain
 * characters encoded into UTF-8 with each octet represented by a
 * three-character substring such as "\\B4".
 * They may not, however, contain characters encoded into UTF-8 with
 * each octet represented by a single character in the string:  the
 * meaning would be ambiguous.
 *<p>
 * <code>LdapName</code> will properly parse all valid names, but
 * does not attempt to detect all possible violations when parsing
 * invalid names.  It is "generous" in accepting invalid names.
 * The "validity" of a name is determined ultimately when it
 * is supplied to an LDAP server, which may accept or
 * reject the name based on factors such as its schema information
 * and interoperability considerations.
 *<p>
 * When names are tested for equality, attribute types, both binary
 * and string values, are case-insensitive.
 * String values with different but equivalent usage of quoting,
 * escaping, or UTF8-hex-encoding are considered equal.  The order of
 * components in multi-valued RDNs (such as "ou=Sales+cn=Bob") is not
 * significant.
 * <p>
 * The components of a LDAP name, that is, RDNs, are numbered. The
 * indexes of a LDAP name with n RDNs range from 0 to n-1.
 * This range may be written as [0,n).
 * The right most RDN is at index 0, and the left most RDN is at
 * index n-1. For example, the distinguished name:
 * "CN=Steve Kille, O=Isode Limited, C=GB" is numbered in the following
 * sequence ranging from 0 to 2: {C=GB, O=Isode Limited, CN=Steve Kille}. An
 * empty LDAP name is represented by an empty RDN list.
 *<p>
 * Concurrent multithreaded read-only access of an instance of
 * <tt>LdapName</tt> need not be synchronized.
 *<p>
 * Unless otherwise noted, the behavior of passing a null argument
 * to a constructor or method in this class will cause a
 * NullPointerException to be thrown.
 *
 * @author Scott Seligman
 * @since 1.5
 */

public class LdapName implements Name {

    // private transient ArrayList<Rdn> rdns;   // parsed name components

    private transient ArrayList rdns;   // parsed name components
    private transient String unparsed;  // if non-null, the DN in unparsed form
    private static final long serialVersionUID = -1595520034788997356L;

    /**
     * Constructs an LDAP name from the given distinguished name.
     *
     * @param name  This is a non-null distinguished name formatted
     * according to the rules defined in
     * <a href="http://ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
     *
     * @throws InvalidNameException if a syntax violation is detected.
     * @see Rdn#escapeValue(Object value)
     */
    public LdapName(String name) throws InvalidNameException {
        unparsed = name;
        parse();
    }

    /**
     * Constructs an LDAP name given its parsed RDN components.
     * <p>
     * The indexing of RDNs in the list follows the numbering of
     * RDNs described in the class description.
     *
     * @param rdns The non-null list of <tt>Rdn</tt>s forming this LDAP name.
     */
    public LdapName(List<Rdn> rdns) {

        // if (rdns instanceof ArrayList<Rdn>) {
        //      this.rdns = rdns.clone();
        // } else if (rdns instanceof List<Rdn>) {
        //      this.rdns = new ArrayList<Rdn>(rdns);
        // } else {
        //      throw IllegalArgumentException(
        //              "Invalid entries, list entries must be of type Rdn");
        //  }

        this.rdns = new ArrayList(rdns.size());
        for (int i = 0; i < rdns.size(); i++) {
            Object obj = rdns.get(i);
            if (!(obj instanceof Rdn)) {
                throw new IllegalArgumentException("Entry:" + obj +
                        "  not a valid type;list entries must be of type Rdn");
            }
            this.rdns.add(obj);
        }
    }

    /*
     * Constructs an LDAP name given its parsed components (the elements
     * of "rdns" in the range [beg,end)) and, optionally
     * (if "name" is not null), the unparsed DN.
     *
     */
    // private LdapName(String name, List<Rdn> rdns, int beg, int end) {

    private LdapName(String name, ArrayList rdns, int beg, int end) {
        unparsed = name;
        // this.rdns = rdns.subList(beg, end);

        List sList = rdns.subList(beg, end);
        this.rdns = new ArrayList(sList);
    }

    /**
     * Retrieves the number of components in this LDAP name.
     * @return The non-negative number of components in this LDAP name.
     */
    public int size() {
        return rdns.size();
    }

    /**
     * Determines whether this LDAP name is empty.
     * An empty name is one with zero components.
     * @return true if this LDAP name is empty, false otherwise.
     */
    public boolean isEmpty() {
        return rdns.isEmpty();
    }

    /**
     * Retrieves the components of this name as an enumeration
     * of strings. The effect of updates to this name on this enumeration
     * is undefined. If the name has zero components, an empty (non-null)
     * enumeration is returned.
     * The order of the components returned by the enumeration is same as
     * the order in which the components are numbered as described in the
     * class description.
     *
     * @return A non-null enumeration of the components of this LDAP name.
     * Each element of the enumeration is of class String.
     */
    public Enumeration<String> getAll() {
        final Iterator iter = rdns.iterator();

        return new Enumeration<String>() {
            public boolean hasMoreElements() {
                return iter.hasNext();
            }
            public String nextElement() {
                return iter.next().toString();
            }
        };
    }

    /**
     * Retrieves a component of this LDAP name as a string.
     * @param  posn The 0-based index of the component to retrieve.
     *              Must be in the range [0,size()).
     * @return The non-null component at index posn.
     * @exception IndexOutOfBoundsException if posn is outside the
     *          specified range.
     */
    public String get(int posn) {
        return rdns.get(posn).toString();
    }

    /**
     * Retrieves an RDN of this LDAP name as an Rdn.
     * @param   posn The 0-based index of the RDN to retrieve.
     *          Must be in the range [0,size()).
     * @return The non-null RDN at index posn.
     * @exception IndexOutOfBoundsException if posn is outside the
     *            specified range.
     */
    public Rdn getRdn(int posn) {
        return (Rdn) rdns.get(posn);
    }

    /**
     * Creates a name whose components consist of a prefix of the
     * components of this LDAP name.
     * Subsequent changes to this name will not affect the name
     * that is returned and vice versa.
     * @param  posn     The 0-based index of the component at which to stop.
     *                  Must be in the range [0,size()].
     * @return  An instance of <tt>LdapName</tt> consisting of the
     *          components at indexes in the range [0,posn).
     *          If posn is zero, an empty LDAP name is returned.
     * @exception   IndexOutOfBoundsException
     *              If posn is outside the specified range.
     */
    public Name getPrefix(int posn) {
        try {
            return new LdapName(null, rdns, 0, posn);
        } catch (IllegalArgumentException e) {
            throw new IndexOutOfBoundsException(
                "Posn: " + posn + ", Size: "+ rdns.size());
        }
    }

    /**
     * Creates a name whose components consist of a suffix of the
     * components in this LDAP name.
     * Subsequent changes to this name do not affect the name that is
     * returned and vice versa.
     *
     * @param  posn     The 0-based index of the component at which to start.
     *                  Must be in the range [0,size()].
     * @return  An instance of <tt>LdapName</tt> consisting of the
     *          components at indexes in the range [posn,size()).
     *          If posn is equal to size(), an empty LDAP name is
     *          returned.
     * @exception IndexOutOfBoundsException
     *          If posn is outside the specified range.
     */
    public Name getSuffix(int posn) {
        try {
            return new LdapName(null, rdns, posn, rdns.size());
        } catch (IllegalArgumentException e) {
            throw new IndexOutOfBoundsException(
                "Posn: " + posn + ", Size: "+ rdns.size());
        }
    }

    /**
     * Determines whether this LDAP name starts with a specified LDAP name
     * prefix.
     * A name <tt>n</tt> is a prefix if it is equal to
     * <tt>getPrefix(n.size())</tt>--in other words this LDAP
     * name starts with 'n'. If n is null or not a RFC2253 formatted name
     * as described in the class description, false is returned.
     *
     * @param n The LDAP name to check.
     * @return  true if <tt>n</tt> is a prefix of this LDAP name,
     * false otherwise.
     * @see #getPrefix(int posn)
     */
    public boolean startsWith(Name n) {
        if (n == null) {
            return false;
        }
        int len1 = rdns.size();
        int len2 = n.size();
        return (len1 >= len2 &&
                matches(0, len2, n));
    }

    /**
     * Determines whether the specified RDN sequence forms a prefix of this
     * LDAP name.  Returns true if this LdapName is at least as long as rdns,
     * and for every position p in the range [0, rdns.size()) the component
     * getRdn(p) matches rdns.get(p). Returns false otherwise. If rdns is
     * null, false is returned.
     *
     * @param rdns The sequence of <tt>Rdn</tt>s to check.
     * @return  true if <tt>rdns</tt> form a prefix of this LDAP name,
     *          false otherwise.
     */
    public boolean startsWith(List<Rdn> rdns) {
        if (rdns == null) {
            return false;
        }
        int len1 = this.rdns.size();
        int len2 = rdns.size();
        return (len1 >= len2 &&
                doesListMatch(0, len2, rdns));
    }

    /**
     * Determines whether this LDAP name ends with a specified
     * LDAP name suffix.
     * A name <tt>n</tt> is a suffix if it is equal to
     * <tt>getSuffix(size()-n.size())</tt>--in other words this LDAP
     * name ends with 'n'. If n is null or not a RFC2253 formatted name
     * as described in the class description, false is returned.
     *
     * @param n The LDAP name to check.
     * @return true if <tt>n</tt> is a suffix of this name, false otherwise.
     * @see #getSuffix(int posn)
     */
    public boolean endsWith(Name n) {
        if (n == null) {
            return false;
        }
        int len1 = rdns.size();
        int len2 = n.size();
        return (len1 >= len2 &&
                matches(len1 - len2, len1, n));
    }

    /**
     * Determines whether the specified RDN sequence forms a suffix of this
     * LDAP name.  Returns true if this LdapName is at least as long as rdns,
     * and for every position p in the range [size() - rdns.size(), size())
     * the component getRdn(p) matches rdns.get(p). Returns false otherwise.
     * If rdns is null, false is returned.
     *
     * @param rdns The sequence of <tt>Rdn</tt>s to check.
     * @return  true if <tt>rdns</tt> form a suffix of this LDAP name,
     *          false otherwise.
     */
    public boolean endsWith(List<Rdn> rdns) {
        if (rdns == null) {
            return false;
        }
        int len1 = this.rdns.size();
        int len2 = rdns.size();
        return (len1 >= len2 &&
                doesListMatch(len1 - len2, len1, rdns));
    }

    private boolean doesListMatch(int beg, int end, List rdns) {
        for (int i = beg; i < end; i++) {
            if (!this.rdns.get(i).equals(rdns.get(i - beg))) {
                return false;
            }
        }
        return true;
    }

    /*
     * Helper method for startsWith() and endsWith().
     * Returns true if components [beg,end) match the components of "n".
     * If "n" is not an LdapName, each of its components is parsed as
     * the string form of an RDN.
     * The following must hold:  end - beg == n.size().
     */
    private boolean matches(int beg, int end, Name n) {
        if (n instanceof LdapName) {
            LdapName ln = (LdapName) n;
            return doesListMatch(beg, end, ln.rdns);
        } else {
            for (int i = beg; i < end; i++) {
                Rdn rdn;
                String rdnString = n.get(i - beg);
                try {
                    rdn = (new Rfc2253Parser(rdnString)).parseRdn();
                } catch (InvalidNameException e) {
                    return false;
                }
                if (!rdn.equals(rdns.get(i))) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * Adds the components of a name -- in order -- to the end of this name.
     *
     * @param   suffix The non-null components to add.
     * @return  The updated name (not a new instance).
     *
     * @throws  InvalidNameException if <tt>suffix</tt> is not a valid LDAP
     *          name, or if the addition of the components would violate the
     *          syntax rules of this LDAP name.
     */
    public Name addAll(Name suffix) throws InvalidNameException {
         return addAll(size(), suffix);
    }


    /**
     * Adds the RDNs of a name -- in order -- to the end of this name.
     *
     * @param   suffixRdns The non-null suffix <tt>Rdn</tt>s to add.
     * @return  The updated name (not a new instance).
     */
    public Name addAll(List<Rdn> suffixRdns) {
        return addAll(size(), suffixRdns);
    }

    /**
     * Adds the components of a name -- in order -- at a specified position
     * within this name. Components of this LDAP name at or after the
     * index (if any) of the first new component are shifted up
     * (away from index 0) to accomodate the new components.
     *
     * @param suffix    The non-null components to add.
     * @param posn      The index at which to add the new component.
     *                  Must be in the range [0,size()].
     *
     * @return  The updated name (not a new instance).
     *
     * @throws  InvalidNameException if <tt>suffix</tt> is not a valid LDAP
     *          name, or if the addition of the components would violate the
     *          syntax rules of this LDAP name.
     * @throws  IndexOutOfBoundsException.
     *          If posn is outside the specified range.
     */
    public Name addAll(int posn, Name suffix)
        throws InvalidNameException {
        unparsed = null;        // no longer valid
        if (suffix instanceof LdapName) {
            LdapName s = (LdapName) suffix;
            rdns.addAll(posn, s.rdns);
        } else {
            Enumeration comps = suffix.getAll();
            while (comps.hasMoreElements()) {
                rdns.add(posn++,
                    (new Rfc2253Parser((String) comps.nextElement()).
                    parseRdn()));
            }
        }
        return this;
    }

    /**
     * Adds the RDNs of a name -- in order -- at a specified position
     * within this name. RDNs of this LDAP name at or after the
     * index (if any) of the first new RDN are shifted up (away from index 0) to
     * accomodate the new RDNs.
     *
     * @param suffixRdns        The non-null suffix <tt>Rdn</tt>s to add.
     * @param posn              The index at which to add the suffix RDNs.
     *                          Must be in the range [0,size()].
     *
     * @return  The updated name (not a new instance).
     * @throws  IndexOutOfBoundsException.
     *          If posn is outside the specified range.
     */
    public Name addAll(int posn, List<Rdn> suffixRdns) {
        unparsed = null;
        for (int i = 0; i < suffixRdns.size(); i++) {
            Object obj = suffixRdns.get(i);
            if (!(obj instanceof Rdn)) {
                throw new IllegalArgumentException("Entry:" + obj +
                "  not a valid type;suffix list entries must be of type Rdn");
            }
            rdns.add(i + posn, obj);
        }
        return this;
    }

    /**
     * Adds a single component to the end of this LDAP name.
     *
     * @param comp      The non-null component to add.
     * @return          The updated LdapName, not a new instance.
     *                  Cannot be null.
     * @exception       InvalidNameException If adding comp at end of the name
     *                  would violate the name's syntax.
     */
    public Name add(String comp) throws InvalidNameException {
        return add(size(), comp);
    }

    /**
     * Adds a single RDN to the end of this LDAP name.
     *
     * @param comp      The non-null RDN to add.
     *
     * @return          The updated LdapName, not a new instance.
     *                  Cannot be null.
     */
    public Name add(Rdn comp) {
        return add(size(), comp);
    }

    /**
     * Adds a single component at a specified position within this
     * LDAP name.
     * Components of this LDAP name at or after the index (if any) of the new
     * component are shifted up by one (away from index 0) to accommodate
     * the new component.
     *
     * @param  comp     The non-null component to add.
     * @param  posn     The index at which to add the new component.
     *                  Must be in the range [0,size()].
     * @return          The updated LdapName, not a new instance.
     *                  Cannot be null.
     * @exception       IndexOutOfBoundsException.
     *                  If posn is outside the specified range.
     * @exception       InvalidNameException If adding comp at the
     *                  specified position would violate the name's syntax.
     */
    public Name add(int posn, String comp) throws InvalidNameException {
        Rdn rdn = (new Rfc2253Parser(comp)).parseRdn();
        rdns.add(posn, rdn);
        unparsed = null;        // no longer valid
        return this;
    }

    /**
     * Adds a single RDN at a specified position within this
     * LDAP name.
     * RDNs of this LDAP name at or after the index (if any) of the new
     * RDN are shifted up by one (away from index 0) to accommodate
     * the new RDN.
     *
     * @param  comp     The non-null RDN to add.
     * @param  posn     The index at which to add the new RDN.
     *                  Must be in the range [0,size()].
     * @return          The updated LdapName, not a new instance.
     *                  Cannot be null.
     * @exception       IndexOutOfBoundsException
     *                  If posn is outside the specified range.
     */
    public Name add(int posn, Rdn comp) {
        if (comp == null) {
            throw new NullPointerException("Cannot set comp to null");
        }
        rdns.add(posn, comp);
        unparsed = null;        // no longer valid
        return this;
    }

    /**
     * Removes a component from this LDAP name.
     * The component of this name at the specified position is removed.
     * Components with indexes greater than this position (if any)
     * are shifted down (toward index 0) by one.
     *
     * @param posn      The index of the component to remove.
     *                  Must be in the range [0,size()).
     * @return          The component removed (a String).
     *
     * @throws          IndexOutOfBoundsException
     *                  if posn is outside the specified range.
     * @throws          InvalidNameException if deleting the component
     *                  would violate the syntax rules of the name.
     */
    public Object remove(int posn) throws InvalidNameException {
        unparsed = null;        // no longer valid
        return rdns.remove(posn).toString();
    }

    /**
     * Retrieves the list of relative distinguished names.
     * The contents of the list are unmodifiable.
     * The indexing of RDNs in the returned list follows the numbering of
     * RDNs as described in the class description.
     * If the name has zero components, an empty list is returned.
     *
     * @return  The name as a list of RDNs which are instances of
     *          the class {@link Rdn Rdn}.
     */
    public List<Rdn> getRdns() {
        return Collections.unmodifiableList(rdns);
    }

    /**
     * Generates a new copy of this name.
     * Subsequent changes to the components of this name will not
     * affect the new copy, and vice versa.
     *
     * @return A copy of the this LDAP name.
     */
    public Object clone() {
        return new LdapName(unparsed, rdns, 0, rdns.size());
    }

    /**
     * Returns a string representation of this LDAP name in a format
     * defined by <a href="http://ietf.org/rfc/rfc2253.txt">RFC 2253</a>
     * and described in the class description. If the name has zero
     * components an empty string is returned.
     *
     * @return The string representation of the LdapName.
     */
    public String toString() {
        if (unparsed != null) {
            return unparsed;
        }
        StringBuilder builder = new StringBuilder();
        int size = rdns.size();
        if ((size - 1) >= 0) {
            builder.append((Rdn) rdns.get(size - 1));
        }
        for (int next = size - 2; next >= 0; next--) {
            builder.append(',');
            builder.append((Rdn) rdns.get(next));
        }
        unparsed = builder.toString();
        return unparsed;
    }

    /**
     * Determines whether two LDAP names are equal.
     * If obj is null or not an LDAP name, false is returned.
     * <p>
     * Two LDAP names are equal if each RDN in one is equal
     * to the corresponding RDN in the other. This implies
     * both have the same number of RDNs, and each RDN's
     * equals() test against the corresponding RDN in the other
     * name returns true. See {@link Rdn#equals(Object obj)}
     * for a definition of RDN equality.
     *
     * @param  obj      The possibly null object to compare against.
     * @return          true if obj is equal to this LDAP name,
     *                  false otherwise.
     * @see #hashCode
     */
    public boolean equals(Object obj) {
        // check possible shortcuts
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof LdapName)) {
            return false;
        }
        LdapName that = (LdapName) obj;
        if (rdns.size() != that.rdns.size()) {
            return false;
        }
        if (unparsed != null && unparsed.equalsIgnoreCase(
                that.unparsed)) {
            return true;
        }
        // Compare RDNs one by one for equality
        for (int i = 0; i < rdns.size(); i++) {
            // Compare a single pair of RDNs.
            Rdn rdn1 = (Rdn) rdns.get(i);
            Rdn rdn2 = (Rdn) that.rdns.get(i);
            if (!rdn1.equals(rdn2)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Compares this LdapName with the specified Object for order.
     * Returns a negative integer, zero, or a positive integer as this
     * Name is less than, equal to, or greater than the given Object.
     * <p>
     * If obj is null or not an instance of LdapName, ClassCastException
     * is thrown.
     * <p>
     * Ordering of LDAP names follows the lexicographical rules for
     * string comparison, with the extension that this applies to all
     * the RDNs in the LDAP name. All the RDNs are lined up in their
     * specified order and compared lexicographically.
     * See {@link Rdn#compareTo(Object obj) Rdn.compareTo(Object obj)}
     * for RDN comparison rules.
     * <p>
     * If this LDAP name is lexicographically lesser than obj,
     * a negative number is returned.
     * If this LDAP name is lexicographically greater than obj,
     * a positive number is returned.
     * @param obj The non-null LdapName instance to compare against.
     *
     * @return  A negative integer, zero, or a positive integer as this Name
     *          is less than, equal to, or greater than the given obj.
     * @exception ClassCastException if obj is null or not a LdapName.
     */
    public int compareTo(Object obj) {

        if (!(obj instanceof LdapName)) {
            throw new ClassCastException("The obj is not a LdapName");
        }

        // check possible shortcuts
        if (obj == this) {
            return 0;
        }
        LdapName that = (LdapName) obj;

        if (unparsed != null && unparsed.equalsIgnoreCase(
                        that.unparsed)) {
            return 0;
        }

        // Compare RDNs one by one, lexicographically.
        int minSize = Math.min(rdns.size(), that.rdns.size());
        for (int i = 0; i < minSize; i++) {
            // Compare a single pair of RDNs.
            Rdn rdn1 = (Rdn)rdns.get(i);
            Rdn rdn2 = (Rdn)that.rdns.get(i);

            int diff = rdn1.compareTo(rdn2);
            if (diff != 0) {
                return diff;
            }
        }
        return (rdns.size() - that.rdns.size());        // longer DN wins
    }

    /**
     * Computes the hash code of this LDAP name.
     * The hash code is the sum of the hash codes of individual RDNs
     * of this  name.
     *
     * @return An int representing the hash code of this name.
     * @see #equals
     */
    public int hashCode() {
        // Sum up the hash codes of the components.
        int hash = 0;

        // For each RDN...
        for (int i = 0; i < rdns.size(); i++) {
            Rdn rdn = (Rdn) rdns.get(i);
            hash += rdn.hashCode();
        }
        return hash;
    }

    /**
     * Serializes only the unparsed DN, for compactness and to avoid
     * any implementation dependency.
     *
     * @serialData      The DN string
     */
    private void writeObject(ObjectOutputStream s)
            throws java.io.IOException {
        s.defaultWriteObject();
        s.writeObject(toString());
    }

    private void readObject(ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
        s.defaultReadObject();
        unparsed = (String)s.readObject();
        try {
            parse();
        } catch (InvalidNameException e) {
            // shouldn't happen
            throw new java.io.StreamCorruptedException(
                    "Invalid name: " + unparsed);
        }
    }

    private void parse() throws InvalidNameException {
        // rdns = (ArrayList<Rdn>) (new RFC2253Parser(unparsed)).getDN();

        rdns = (ArrayList) (new Rfc2253Parser(unparsed)).parseDn();
    }
}
