You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2006/08/21 00:54:55 UTC
svn commit: r433074 [2/3] - in
/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name:
AttributeTypeAndValue.java LdapDN.java LdapDnParser.java Rdn.java
RdnParser.java
Modified: directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java
URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java?rev=433074&r1=433073&r2=433074&view=diff
==============================================================================
--- directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java (original)
+++ directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java Sun Aug 20 15:54:54 2006
@@ -30,6 +30,7 @@
import javax.naming.Name;
import javax.naming.NamingException;
+import org.apache.directory.shared.ldap.name.DefaultStringNormalizer;
import org.apache.directory.shared.ldap.schema.OidNormalizer;
import org.apache.directory.shared.ldap.util.StringTools;
import org.slf4j.Logger;
@@ -38,1393 +39,1393 @@
/**
* The LdapDN class contains a DN (Distinguished Name).
- *
- * Its specification can be found in RFC 2253,
- * "UTF-8 String Representation of Distinguished Names".
- *
- * We will store two representation of a DN :
- * - a user Provider represeentation, which is the parsed String given by a user
- * - an internal representation.
- *
- * A DN is formed of RDNs, in a specific order :
+ *
+ * Its specification can be found in RFC 2253,
+ * "UTF-8 String Representation of Distinguished Names".
+ *
+ * We will store two representation of a DN :
+ * - a user Provider represeentation, which is the parsed String given by a user
+ * - an internal representation.
+ *
+ * A DN is formed of RDNs, in a specific order :
* RDN[n], RDN[n-1], ... RDN[1], RDN[0]
- *
+ *
* It represents a tree, in which the root is the last RDN (RDN[0]) and the leaf
* is the first RDN (RDN[n]).
- *
+ *
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class LdapDN /* extends LdapString */implements Name
{
- /** The LoggerFactory used by this class */
- private static Logger log = LoggerFactory.getLogger( LdapDN.class );
+ /** The LoggerFactory used by this class */
+ private static Logger log = LoggerFactory.getLogger( LdapDN.class );
- /**
- * Declares the Serial Version Uid.
- *
- * @see <a
- * href="http://c2.com/cgi/wiki?AlwaysDeclareSerialVersionUid">Always
- * Declare Serial Version Uid</a>
- */
- private static final long serialVersionUID = 1L;
-
- /** Value returned by the compareTo method if values are not equals */
- public final static int NOT_EQUALS = -1;
-
- /** Value returned by the compareTo method if values are equals */
- public final static int EQUALS = 0;
-
- // ~ Static fields/initializers
- // -----------------------------------------------------------------
- /** The RDNs that are elements of the DN */
- private List rdns = new ArrayList( 5 );
-
- /** The user provided name */
- private String upName;
-
- /** The normalized name */
- private String normName;
-
- /** The bytes representation of the normName */
- private byte[] bytes;
-
- /** A null LdapDN */
- public static final LdapDN EMPTY_LDAPDN = new LdapDN();
-
- // ~ Methods
- // ------------------------------------------------------------------------------------
-
- /**
- * Construct an empty LdapDN object
- */
- public LdapDN()
- {
- super();
- upName = "";
- normName = "";
- }
-
-
- /**
- * Transduces, or copies a Name to an LdapDN.
- *
- * @param name composed of String name components.
- */
- public LdapDN( Name name ) throws InvalidNameException
- {
- if ( ( name != null ) && ( name.size() != 0 ) )
- {
- for ( int ii = 0; ii < name.size(); ii++ )
- {
- String nameComponent = ( String ) name.get( ii );
- add( nameComponent );
- }
- }
- }
-
-
- /**
- * Creates an ldap name using a list of NameComponents. Each NameComponent
- * is a String
- *
- * @param list of String name components.
- */
- LdapDN( List list ) throws InvalidNameException
- {
- if ( ( list != null ) && ( list.size() != 0 ) )
- {
- Iterator nameComponents = list.iterator();
-
- while ( nameComponents.hasNext() )
- {
- String nameComponent = ( String ) nameComponents.next();
- add( 0, nameComponent );
- }
- }
- }
-
-
- /**
- * Creates an ldap name using a list of name components.
- *
- * @param nameComponents
- * List of String name components.
- */
- LdapDN( Iterator nameComponents ) throws InvalidNameException
- {
- if ( nameComponents != null )
- {
- while ( nameComponents.hasNext() )
- {
- String nameComponent = ( String ) nameComponents.next();
- add( 0, nameComponent );
- }
- }
- }
-
-
- /**
- * Parse a String and checks that it is a valid DN <br>
- * <p>
- * <distinguishedName> ::= <name> | e <br>
- * <name> ::= <name-component> <name-components> <br>
- * <name-components> ::= <spaces> <separator>
- * <spaces> <name-component> <name-components> | e <br>
- * </p>
- *
- * @param bytes
- * The byte buffer that contains the DN
- * @exception A
- * InvalidNameException is thrown if the buffer does not
- * contains a valid DN.
- */
- public LdapDN( String upName ) throws InvalidNameException
- {
- if ( upName != null )
- {
- LdapDnParser.parseInternal( upName, rdns );
- }
-
- // Stores the representations of a DN : internal (as a string and as a
- // byte[]) and external.
- normalizeInternal();
- this.upName = upName;
- }
-
-
- /**
- * Parse a buffer and checks that it is a valid DN <br>
- * <p>
- * <distinguishedName> ::= <name> | e <br>
- * <name> ::= <name-component> <name-components> <br>
- * <name-components> ::= <spaces> <separator>
- * <spaces> <name-component> <name-components> | e <br>
- * </p>
- *
- * @param bytes
- * The byte buffer that contains the DN
- * @exception A
- * InvalidNameException is thrown if the buffer does not
- * contains a valid DN.
- */
- public LdapDN(byte[] bytes) throws InvalidNameException
- {
- try
- {
- upName = new String( bytes, "UTF-8" );
- LdapDnParser.parseInternal( upName, rdns );
- this.normName = toNormName();
- }
- catch ( UnsupportedEncodingException uee )
- {
- log.error( "The byte array is not an UTF-8 encoded Unicode String : " + uee.getMessage() );
- throw new InvalidNameException( "The byte array is not an UTF-8 encoded Unicode String : "
- + uee.getMessage() );
- }
- }
-
-
- /**
- * Normalize the DN by triming useless spaces and lowercasing names.
- *
- * @return a normalized form of the DN
- */
- private void normalizeInternal()
- {
- normName = toNormName();
- }
-
-
- /**
- * Build the normalized DN as a String,
- *
- * @return A String representing the normalized DN
- */
- public String toNormName()
- {
- if ( ( rdns == null ) || ( rdns.size() == 0 ) )
- {
- bytes = null;
- return "";
- }
- else
- {
- StringBuffer sb = new StringBuffer();
- boolean isFirst = true;
-
- for ( int i = 0; i < rdns.size(); i++ )
- {
- if ( isFirst )
- {
- isFirst = false;
- }
- else
- {
- sb.append( ',' );
- }
-
- sb.append( ( ( Rdn ) rdns.get( i ) ) );
- }
-
- String newNormName = sb.toString();
-
- if ( normName != newNormName )
- {
- bytes = StringTools.getBytesUtf8( newNormName );
- normName = newNormName;
- }
-
- return normName;
- }
- }
-
-
- /**
- * Return the normalized DN as a String. It returns the same value as the
- * getNormName method
- *
- * @return A String representing the normalized DN
- */
- public String toString()
- {
- return normName == null ? "" : normName;
- }
-
-
- /**
- * Return the User Provided DN as a String,
- *
- * @return A String representing the User Provided DN
- */
- private String toUpName()
- {
- if ( ( rdns == null ) || ( rdns.size() == 0 ) )
- {
- upName = "";
- }
- else
- {
- StringBuffer sb = new StringBuffer();
- boolean isFirst = true;
-
- for ( int i = 0; i < rdns.size(); i++ )
- {
- if ( isFirst )
- {
- isFirst = false;
- }
- else
- {
- sb.append( ',' );
- }
-
- sb.append( ( ( Rdn ) rdns.get( i ) ).getUpName() );
- }
-
- upName = sb.toString();
- }
-
- return upName;
- }
-
-
- /**
- * Return the User Provided prefix representation of the DN starting at the
- * posn position.
- *
- * If posn = 0, return an empty string.
- *
- * for DN : sn=smith, dc=apache, dc=org
- * getUpname(0) -> ""
- * getUpName(1) -> "dc=org"
- * getUpname(3) -> "sn=smith, dc=apache, dc=org"
- * getUpName(4) -> ArrayOutOfBoundException
- *
- * Warning ! The returned String is not exactly the
- * user provided DN, as spaces before and after each RDNs have been trimmed.
- *
- * @param posn
- * The starting position
- * @return The truncated DN
- */
- private String getUpNamePrefix( int posn )
- {
- if ( posn == 0 )
- {
- return "";
- }
-
- if ( posn > rdns.size() )
- {
- String message = "Impossible to get the position " + posn + ", the DN only has " + rdns.size() + " RDNs";
- log.error( message );
- throw new ArrayIndexOutOfBoundsException( message );
- }
-
- int start = rdns.size() - posn;
- StringBuffer sb = new StringBuffer();
- boolean isFirst = true;
-
- for ( int i = start; i < rdns.size(); i++ )
- {
- if ( isFirst )
- {
- isFirst = false;
- }
- else
- {
- sb.append( ',' );
- }
-
- sb.append( ( ( Rdn ) rdns.get( i ) ).getUpName() );
- }
-
- return sb.toString();
- }
-
-
- /**
- * Return the User Provided suffix representation of the DN starting at the
- * posn position.
- * If posn = 0, return an empty string.
- *
- * for DN : sn=smith, dc=apache, dc=org
- * getUpname(0) -> "sn=smith, dc=apache, dc=org"
- * getUpName(1) -> "sn=smith, dc=apache"
- * getUpname(3) -> "sn=smith"
- * getUpName(4) -> ""
- *
- * Warning ! The returned String is not exactly the user
- * provided DN, as spaces before and after each RDNs have been trimmed.
- *
- * @param posn The starting position
- * @return The truncated DN
- */
- private String getUpNameSuffix( int posn )
- {
- if ( posn > rdns.size() )
- {
- return "";
- }
-
- int end = rdns.size() - posn;
- StringBuffer sb = new StringBuffer();
- boolean isFirst = true;
-
- for ( int i = 0; i < end; i++ )
- {
- if ( isFirst )
- {
- isFirst = false;
- }
- else
- {
- sb.append( ',' );
- }
-
- sb.append( ( ( Rdn ) rdns.get( i ) ).getUpName() );
- }
-
- return sb.toString();
- }
-
-
- /**
- * Gets the hashcode of this name.
- *
- * @see java.lang.Object#hashCode()
- */
- public int hashCode()
- {
- int result = 17;
-
- if ( ( rdns != null ) || ( rdns.size() == 0 ) )
- {
- for ( Iterator rdnsIter = rdns.iterator(); rdnsIter.hasNext(); )
- {
- result = result * 37 + rdnsIter.next().hashCode();
- }
- }
-
- return result;
- }
-
-
- /**
- * Get the initial DN (without normalization)
- *
- * @return The DN as a String
- */
- public String getUpName()
- {
- return ( upName == null ? "" : upName );
- }
-
-
- /**
- * Get the initial DN (without normalization)
- *
- * @return The DN as a String
- */
- public String getNormName()
- {
- return ( normName == null ? "" : normName );
- }
-
- /**
- * Get the number of NameComponent conatained in this LdapDN
- *
- * @return The number of NameComponent conatained in this LdapDN
- */
- public int size()
- {
- return rdns.size();
- }
-
-
- /**
- * Get the number of bytes necessary to store this DN
- *
- * @return A integer, which is the size of the UTF-8 byte array
- */
- public static int getNbBytes( Name dn )
- {
- LdapDN ldapDn = ( LdapDN ) dn;
- return ldapDn.bytes == null ? 0 : ldapDn.bytes.length;
- }
-
-
- /**
- * Get an UTF-8 representation of the normalized form of the DN
- *
- * @return A byte[] representation of the DN
- */
- public static byte[] getBytes( LdapDN dn )
- {
- return dn == null ? null : dn.bytes;
- }
-
-
- /**
- * Determines whether this name starts with a specified prefix. A name
- * <tt>name</tt> is a prefix if it is equal to
- * <tt>getPrefix(name.size())</tt>.
- *
- * Be aware that for a specific DN like :
- * cn=xxx, ou=yyy
- * the startsWith method will return true with ou=yyy, and
- * false with cn=xxx
- *
- * @param name
- * the name to check
- * @return true if <tt>name</tt> is a prefix of this name, false otherwise
- */
- public boolean startsWith( Name name )
- {
- if ( name instanceof LdapDN )
- {
- LdapDN nameDN = ( LdapDN ) name;
-
- if ( nameDN.size() == 0 )
- {
- return true;
- }
-
- if ( nameDN.size() > size() )
- {
- // The name is longer than the current LdapDN.
- return false;
- }
-
- // Ok, iterate through all the RDN of the name,
- // starting a the end of the current list.
-
- for ( int i = nameDN.size() - 1; i >= 0; i-- )
- {
- Rdn nameRdn = ( Rdn ) ( nameDN.rdns.get( nameDN.rdns.size() - i - 1 ) );
- Rdn ldapRdn = ( Rdn ) rdns.get( rdns.size() - i - 1 );
-
- if ( nameRdn.compareTo( ldapRdn ) != 0 )
- {
- return false;
- }
- }
-
- return true;
- }
- else if ( name instanceof Name )
- {
- if ( name.size() == 0 )
- {
- return true;
- }
-
- if ( name.size() > size() )
- {
- // The name is longer than the current LdapDN.
- return false;
- }
-
- // Ok, iterate through all the RDN of the name,
- // starting a the end of the current list.
-
- for ( int i = name.size() - 1; i >= 0; i-- )
- {
- Rdn ldapRdn = ( Rdn ) rdns.get( rdns.size() - i - 1 );
- Rdn nameRdn = null;
- try
- {
- nameRdn = new Rdn( ( String ) name.get( name.size() - i - 1 ) );
- }
- catch ( InvalidNameException e )
- {
- e.printStackTrace();
- log.error( "Failed to parse RDN for name " + name.toString(), e );
- }
-
- if ( nameRdn.compareTo( ldapRdn ) != 0 )
- {
- return false;
- }
- }
-
- return true;
- }
- else
- {
- // We don't accept a Name which is not a LdapName
- return name == null;
- }
- }
-
-
- /**
- * Determines whether this name ends with a specified suffix. A name
- * <tt>name</tt> is a suffix if it is equal to
- * <tt>getSuffix(size()-name.size())</tt>.
- *
- * Be aware that for a specific
- * DN like : cn=xxx, ou=yyy the endsWith method will return true with
- * cn=xxx, and false with ou=yyy
- *
- * @param name
- * the name to check
- * @return true if <tt>name</tt> is a suffix of this name, false otherwise
- */
- public boolean endsWith( Name name )
- {
- if ( name instanceof LdapDN )
- {
- LdapDN nameDN = ( LdapDN ) name;
-
- if ( nameDN.size() == 0 )
- {
- return true;
- }
-
- if ( nameDN.size() > size() )
- {
- // The name is longer than the current LdapDN.
- return false;
- }
-
- // Ok, iterate through all the RDN of the name
- for ( int i = 0; i < nameDN.size(); i++ )
- {
- Rdn nameRdn = ( Rdn ) ( nameDN.rdns.get( i ) );
- Rdn ldapRdn = ( Rdn ) rdns.get( i );
-
- if ( nameRdn.compareTo( ldapRdn ) != 0 )
- {
- return false;
- }
- }
-
- return true;
- }
- else
- {
- // We don't accept a Name which is not a LdapName
- return name == null;
- }
- }
-
-
- /**
- * Determines whether this name is empty. An empty name is one with zero
- * components.
- *
- * @return true if this name is empty, false otherwise
- */
- public boolean isEmpty()
- {
- return ( rdns.size() == 0 );
- }
-
-
- /**
- * Retrieves a component of this name.
- *
- * @param posn
- * the 0-based index of the component to retrieve. Must be in the
- * range [0,size()).
- * @return the component at index posn
- * @throws ArrayIndexOutOfBoundsException
- * if posn is outside the specified range
- */
- public String get( int posn )
- {
- if ( rdns.size() == 0 )
- {
- return "";
- }
- else
- {
- Rdn rdn = ( Rdn ) rdns.get( rdns.size() - posn - 1 );
-
- return rdn.toString();
- }
- }
-
-
- /**
- * Retrieves a component of this name.
- *
- * @param posn
- * the 0-based index of the component to retrieve. Must be in the
- * range [0,size()).
- * @return the component at index posn
- * @throws ArrayIndexOutOfBoundsException
- * if posn is outside the specified range
- */
- public Rdn getRdn( int posn )
- {
- if ( rdns.size() == 0 )
- {
- return null;
- }
- else
- {
- Rdn rdn = ( Rdn ) rdns.get( rdns.size() - posn - 1 );
+ /**
+ * Declares the Serial Version Uid.
+ *
+ * @see <a
+ * href="http://c2.com/cgi/wiki?AlwaysDeclareSerialVersionUid">Always
+ * Declare Serial Version Uid</a>
+ */
+ private static final long serialVersionUID = 1L;
+
+ /** Value returned by the compareTo method if values are not equals */
+ public final static int NOT_EQUALS = -1;
+
+ /** Value returned by the compareTo method if values are equals */
+ public final static int EQUALS = 0;
+
+ // ~ Static fields/initializers
+ // -----------------------------------------------------------------
+ /** The RDNs that are elements of the DN */
+ private List rdns = new ArrayList( 5 );
+
+ /** The user provided name */
+ private String upName;
+
+ /** The normalized name */
+ private String normName;
+
+ /** The bytes representation of the normName */
+ private byte[] bytes;
+
+ /** A null LdapDN */
+ public static final LdapDN EMPTY_LDAPDN = new LdapDN();
+
+ // ~ Methods
+ // ------------------------------------------------------------------------------------
+
+ /**
+ * Construct an empty LdapDN object
+ */
+ public LdapDN()
+ {
+ super();
+ upName = "";
+ normName = "";
+ }
+
+
+ /**
+ * Transduces, or copies a Name to an LdapDN.
+ *
+ * @param name composed of String name components.
+ */
+ public LdapDN( Name name ) throws InvalidNameException
+ {
+ if ( ( name != null ) && ( name.size() != 0 ) )
+ {
+ for ( int ii = 0; ii < name.size(); ii++ )
+ {
+ String nameComponent = ( String ) name.get( ii );
+ add( nameComponent );
+ }
+ }
+ }
+
+
+ /**
+ * Creates an ldap name using a list of NameComponents. Each NameComponent
+ * is a String
+ *
+ * @param list of String name components.
+ */
+ LdapDN( List list ) throws InvalidNameException
+ {
+ if ( ( list != null ) && ( list.size() != 0 ) )
+ {
+ Iterator nameComponents = list.iterator();
+
+ while ( nameComponents.hasNext() )
+ {
+ String nameComponent = ( String ) nameComponents.next();
+ add( 0, nameComponent );
+ }
+ }
+ }
+
+
+ /**
+ * Creates an ldap name using a list of name components.
+ *
+ * @param nameComponents
+ * List of String name components.
+ */
+ LdapDN( Iterator nameComponents ) throws InvalidNameException
+ {
+ if ( nameComponents != null )
+ {
+ while ( nameComponents.hasNext() )
+ {
+ String nameComponent = ( String ) nameComponents.next();
+ add( 0, nameComponent );
+ }
+ }
+ }
+
+
+ /**
+ * Parse a String and checks that it is a valid DN <br>
+ * <p>
+ * <distinguishedName> ::= <name> | e <br>
+ * <name> ::= <name-component> <name-components> <br>
+ * <name-components> ::= <spaces> <separator>
+ * <spaces> <name-component> <name-components> | e <br>
+ * </p>
+ *
+ * @param bytes
+ * The byte buffer that contains the DN
+ * @exception A
+ * InvalidNameException is thrown if the buffer does not
+ * contains a valid DN.
+ */
+ public LdapDN( String upName ) throws InvalidNameException
+ {
+ if ( upName != null )
+ {
+ LdapDnParser.parseInternal( upName, rdns );
+ }
+
+ // Stores the representations of a DN : internal (as a string and as a
+ // byte[]) and external.
+ normalizeInternal();
+ this.upName = upName;
+ }
+
+
+ /**
+ * Parse a buffer and checks that it is a valid DN <br>
+ * <p>
+ * <distinguishedName> ::= <name> | e <br>
+ * <name> ::= <name-component> <name-components> <br>
+ * <name-components> ::= <spaces> <separator>
+ * <spaces> <name-component> <name-components> | e <br>
+ * </p>
+ *
+ * @param bytes
+ * The byte buffer that contains the DN
+ * @exception A
+ * InvalidNameException is thrown if the buffer does not
+ * contains a valid DN.
+ */
+ public LdapDN(byte[] bytes) throws InvalidNameException
+ {
+ try
+ {
+ upName = new String( bytes, "UTF-8" );
+ LdapDnParser.parseInternal( upName, rdns );
+ this.normName = toNormName();
+ }
+ catch ( UnsupportedEncodingException uee )
+ {
+ log.error( "The byte array is not an UTF-8 encoded Unicode String : " + uee.getMessage() );
+ throw new InvalidNameException( "The byte array is not an UTF-8 encoded Unicode String : "
+ + uee.getMessage() );
+ }
+ }
+
+
+ /**
+ * Normalize the DN by triming useless spaces and lowercasing names.
+ *
+ * @return a normalized form of the DN
+ */
+ private void normalizeInternal()
+ {
+ normName = toNormName();
+ }
+
+
+ /**
+ * Build the normalized DN as a String,
+ *
+ * @return A String representing the normalized DN
+ */
+ public String toNormName()
+ {
+ if ( ( rdns == null ) || ( rdns.size() == 0 ) )
+ {
+ bytes = null;
+ return "";
+ }
+ else
+ {
+ StringBuffer sb = new StringBuffer();
+ boolean isFirst = true;
+
+ for ( int i = 0; i < rdns.size(); i++ )
+ {
+ if ( isFirst )
+ {
+ isFirst = false;
+ }
+ else
+ {
+ sb.append( ',' );
+ }
+
+ sb.append( ( ( Rdn ) rdns.get( i ) ) );
+ }
+
+ String newNormName = sb.toString();
+
+ if ( normName != newNormName )
+ {
+ bytes = StringTools.getBytesUtf8( newNormName );
+ normName = newNormName;
+ }
+
+ return normName;
+ }
+ }
+
+
+ /**
+ * Return the normalized DN as a String. It returns the same value as the
+ * getNormName method
+ *
+ * @return A String representing the normalized DN
+ */
+ public String toString()
+ {
+ return normName == null ? "" : normName;
+ }
+
+
+ /**
+ * Return the User Provided DN as a String,
+ *
+ * @return A String representing the User Provided DN
+ */
+ private String toUpName()
+ {
+ if ( ( rdns == null ) || ( rdns.size() == 0 ) )
+ {
+ upName = "";
+ }
+ else
+ {
+ StringBuffer sb = new StringBuffer();
+ boolean isFirst = true;
+
+ for ( int i = 0; i < rdns.size(); i++ )
+ {
+ if ( isFirst )
+ {
+ isFirst = false;
+ }
+ else
+ {
+ sb.append( ',' );
+ }
+
+ sb.append( ( ( Rdn ) rdns.get( i ) ).getUpName() );
+ }
+
+ upName = sb.toString();
+ }
+
+ return upName;
+ }
+
+
+ /**
+ * Return the User Provided prefix representation of the DN starting at the
+ * posn position.
+ *
+ * If posn = 0, return an empty string.
+ *
+ * for DN : sn=smith, dc=apache, dc=org
+ * getUpname(0) -> ""
+ * getUpName(1) -> "dc=org"
+ * getUpname(3) -> "sn=smith, dc=apache, dc=org"
+ * getUpName(4) -> ArrayOutOfBoundException
+ *
+ * Warning ! The returned String is not exactly the
+ * user provided DN, as spaces before and after each RDNs have been trimmed.
+ *
+ * @param posn
+ * The starting position
+ * @return The truncated DN
+ */
+ private String getUpNamePrefix( int posn )
+ {
+ if ( posn == 0 )
+ {
+ return "";
+ }
+
+ if ( posn > rdns.size() )
+ {
+ String message = "Impossible to get the position " + posn + ", the DN only has " + rdns.size() + " RDNs";
+ log.error( message );
+ throw new ArrayIndexOutOfBoundsException( message );
+ }
+
+ int start = rdns.size() - posn;
+ StringBuffer sb = new StringBuffer();
+ boolean isFirst = true;
+
+ for ( int i = start; i < rdns.size(); i++ )
+ {
+ if ( isFirst )
+ {
+ isFirst = false;
+ }
+ else
+ {
+ sb.append( ',' );
+ }
+
+ sb.append( ( ( Rdn ) rdns.get( i ) ).getUpName() );
+ }
+
+ return sb.toString();
+ }
+
+
+ /**
+ * Return the User Provided suffix representation of the DN starting at the
+ * posn position.
+ * If posn = 0, return an empty string.
+ *
+ * for DN : sn=smith, dc=apache, dc=org
+ * getUpname(0) -> "sn=smith, dc=apache, dc=org"
+ * getUpName(1) -> "sn=smith, dc=apache"
+ * getUpname(3) -> "sn=smith"
+ * getUpName(4) -> ""
+ *
+ * Warning ! The returned String is not exactly the user
+ * provided DN, as spaces before and after each RDNs have been trimmed.
+ *
+ * @param posn The starting position
+ * @return The truncated DN
+ */
+ private String getUpNameSuffix( int posn )
+ {
+ if ( posn > rdns.size() )
+ {
+ return "";
+ }
+
+ int end = rdns.size() - posn;
+ StringBuffer sb = new StringBuffer();
+ boolean isFirst = true;
+
+ for ( int i = 0; i < end; i++ )
+ {
+ if ( isFirst )
+ {
+ isFirst = false;
+ }
+ else
+ {
+ sb.append( ',' );
+ }
+
+ sb.append( ( ( Rdn ) rdns.get( i ) ).getUpName() );
+ }
+
+ return sb.toString();
+ }
+
+
+ /**
+ * Gets the hashcode of this name.
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode()
+ {
+ int result = 17;
+
+ if ( ( rdns != null ) || ( rdns.size() == 0 ) )
+ {
+ for ( Iterator rdnsIter = rdns.iterator(); rdnsIter.hasNext(); )
+ {
+ result = result * 37 + rdnsIter.next().hashCode();
+ }
+ }
+
+ return result;
+ }
+
+
+ /**
+ * Get the initial DN (without normalization)
+ *
+ * @return The DN as a String
+ */
+ public String getUpName()
+ {
+ return ( upName == null ? "" : upName );
+ }
+
+
+ /**
+ * Get the initial DN (without normalization)
+ *
+ * @return The DN as a String
+ */
+ public String getNormName()
+ {
+ return ( normName == null ? "" : normName );
+ }
+
+ /**
+ * Get the number of NameComponent conatained in this LdapDN
+ *
+ * @return The number of NameComponent conatained in this LdapDN
+ */
+ public int size()
+ {
+ return rdns.size();
+ }
+
+
+ /**
+ * Get the number of bytes necessary to store this DN
+ *
+ * @return A integer, which is the size of the UTF-8 byte array
+ */
+ public static int getNbBytes( Name dn )
+ {
+ LdapDN ldapDn = ( LdapDN ) dn;
+ return ldapDn.bytes == null ? 0 : ldapDn.bytes.length;
+ }
+
+
+ /**
+ * Get an UTF-8 representation of the normalized form of the DN
+ *
+ * @return A byte[] representation of the DN
+ */
+ public static byte[] getBytes( LdapDN dn )
+ {
+ return dn == null ? null : dn.bytes;
+ }
+
+
+ /**
+ * Determines whether this name starts with a specified prefix. A name
+ * <tt>name</tt> is a prefix if it is equal to
+ * <tt>getPrefix(name.size())</tt>.
+ *
+ * Be aware that for a specific DN like :
+ * cn=xxx, ou=yyy
+ * the startsWith method will return true with ou=yyy, and
+ * false with cn=xxx
+ *
+ * @param name
+ * the name to check
+ * @return true if <tt>name</tt> is a prefix of this name, false otherwise
+ */
+ public boolean startsWith( Name name )
+ {
+ if ( name instanceof LdapDN )
+ {
+ LdapDN nameDN = ( LdapDN ) name;
+
+ if ( nameDN.size() == 0 )
+ {
+ return true;
+ }
+
+ if ( nameDN.size() > size() )
+ {
+ // The name is longer than the current LdapDN.
+ return false;
+ }
+
+ // Ok, iterate through all the RDN of the name,
+ // starting a the end of the current list.
+
+ for ( int i = nameDN.size() - 1; i >= 0; i-- )
+ {
+ Rdn nameRdn = ( Rdn ) ( nameDN.rdns.get( nameDN.rdns.size() - i - 1 ) );
+ Rdn ldapRdn = ( Rdn ) rdns.get( rdns.size() - i - 1 );
+
+ if ( nameRdn.compareTo( ldapRdn ) != 0 )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ else if ( name instanceof Name )
+ {
+ if ( name.size() == 0 )
+ {
+ return true;
+ }
+
+ if ( name.size() > size() )
+ {
+ // The name is longer than the current LdapDN.
+ return false;
+ }
+
+ // Ok, iterate through all the RDN of the name,
+ // starting a the end of the current list.
+
+ for ( int i = name.size() - 1; i >= 0; i-- )
+ {
+ Rdn ldapRdn = ( Rdn ) rdns.get( rdns.size() - i - 1 );
+ Rdn nameRdn = null;
+ try
+ {
+ nameRdn = new Rdn( ( String ) name.get( name.size() - i - 1 ) );
+ }
+ catch ( InvalidNameException e )
+ {
+ e.printStackTrace();
+ log.error( "Failed to parse RDN for name " + name.toString(), e );
+ }
+
+ if ( nameRdn.compareTo( ldapRdn ) != 0 )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ else
+ {
+ // We don't accept a Name which is not a LdapName
+ return name == null;
+ }
+ }
+
+
+ /**
+ * Determines whether this name ends with a specified suffix. A name
+ * <tt>name</tt> is a suffix if it is equal to
+ * <tt>getSuffix(size()-name.size())</tt>.
+ *
+ * Be aware that for a specific
+ * DN like : cn=xxx, ou=yyy the endsWith method will return true with
+ * cn=xxx, and false with ou=yyy
+ *
+ * @param name
+ * the name to check
+ * @return true if <tt>name</tt> is a suffix of this name, false otherwise
+ */
+ public boolean endsWith( Name name )
+ {
+ if ( name instanceof LdapDN )
+ {
+ LdapDN nameDN = ( LdapDN ) name;
+
+ if ( nameDN.size() == 0 )
+ {
+ return true;
+ }
+
+ if ( nameDN.size() > size() )
+ {
+ // The name is longer than the current LdapDN.
+ return false;
+ }
+
+ // Ok, iterate through all the RDN of the name
+ for ( int i = 0; i < nameDN.size(); i++ )
+ {
+ Rdn nameRdn = ( Rdn ) ( nameDN.rdns.get( i ) );
+ Rdn ldapRdn = ( Rdn ) rdns.get( i );
+
+ if ( nameRdn.compareTo( ldapRdn ) != 0 )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ else
+ {
+ // We don't accept a Name which is not a LdapName
+ return name == null;
+ }
+ }
+
+
+ /**
+ * Determines whether this name is empty. An empty name is one with zero
+ * components.
+ *
+ * @return true if this name is empty, false otherwise
+ */
+ public boolean isEmpty()
+ {
+ return ( rdns.size() == 0 );
+ }
+
+
+ /**
+ * Retrieves a component of this name.
+ *
+ * @param posn
+ * the 0-based index of the component to retrieve. Must be in the
+ * range [0,size()).
+ * @return the component at index posn
+ * @throws ArrayIndexOutOfBoundsException
+ * if posn is outside the specified range
+ */
+ public String get( int posn )
+ {
+ if ( rdns.size() == 0 )
+ {
+ return "";
+ }
+ else
+ {
+ Rdn rdn = ( Rdn ) rdns.get( rdns.size() - posn - 1 );
+
+ return rdn.toString();
+ }
+ }
+
+
+ /**
+ * Retrieves a component of this name.
+ *
+ * @param posn
+ * the 0-based index of the component to retrieve. Must be in the
+ * range [0,size()).
+ * @return the component at index posn
+ * @throws ArrayIndexOutOfBoundsException
+ * if posn is outside the specified range
+ */
+ public Rdn getRdn( int posn )
+ {
+ if ( rdns.size() == 0 )
+ {
+ return null;
+ }
+ else
+ {
+ Rdn rdn = ( Rdn ) rdns.get( rdns.size() - posn - 1 );
+
+ return rdn;
+ }
+ }
+
+ /**
+ * Retrieves the last component of this name.
+ *
+ * @return the last component of this DN
+ */
+ public Rdn getRdn()
+ {
+ if ( rdns.size() == 0 )
+ {
+ return null;
+ }
+ else
+ {
+ Rdn rdn = ( Rdn ) rdns.get( 0 );
+
+ return rdn;
+ }
+ }
+
+
+ /**
+ * Retrieves all the components of this name.
+ *
+ * @return All the components
+ */
+ public List getRdns()
+ {
+ List newRdns = new ArrayList();
+
+ // We will clone the list, to avoid user modifications
+ for ( int i = 0; i < rdns.size(); i++ )
+ {
+ newRdns.add( i, ( ( Rdn ) rdns.get( i ) ).clone() );
+ }
+
+ return newRdns;
+ }
+
+
+ /**
+ * Retrieves the components of this name as an enumeration of strings. The
+ * effect on the enumeration of updates to this name is undefined. If the
+ * name has zero components, an empty (non-null) enumeration is returned.
+ *
+ * @return an enumeration of the components of this name, each as string
+ */
+ public Enumeration getAll()
+ {
+ /*
+ * Note that by accessing the name component using the get() method on
+ * the name rather than get() on the list we are reading components from
+ * right to left with increasing index values. LdapName.get() does the
+ * index translation on m_list for us.
+ */
+ return new Enumeration()
+ {
+ private int pos;
+
+
+ public boolean hasMoreElements()
+ {
+ return pos < rdns.size();
+ }
+
+
+ public Object nextElement()
+ {
+ if ( pos >= rdns.size() )
+ {
+ log.error( "Exceeded number of elements in the current object" );
+ throw new NoSuchElementException();
+ }
+
+ Object obj = rdns.get( rdns.size() - pos - 1 );
+ pos++;
+ return obj.toString();
+ }
+ };
+ }
+
+
+ /**
+ * Retrieves the components of this name as an enumeration of strings. The
+ * effect on the enumeration of updates to this name is undefined. If the
+ * name has zero components, an empty (non-null) enumeration is returned.
+ *
+ * @return an enumeration of the components of this name, as Rdn
+ */
+ public Enumeration getAllRdn()
+ {
+ /*
+ * Note that by accessing the name component using the get() method on
+ * the name rather than get() on the list we are reading components from
+ * right to left with increasing index values. LdapName.get() does the
+ * index translation on m_list for us.
+ */
+ return new Enumeration()
+ {
+ private int pos;
+
+
+ public boolean hasMoreElements()
+ {
+ return pos < rdns.size();
+ }
+
+
+ public Object nextElement()
+ {
+ if ( pos >= rdns.size() )
+ {
+ log.error( "Exceeded number of elements in the current object" );
+ throw new NoSuchElementException();
+ }
+
+ Object obj = rdns.get( rdns.size() - pos - 1 );
+ pos++;
+ return obj;
+ }
+ };
+ }
+
+
+ /**
+ * Creates a name whose components consist of a prefix of the components of
+ * this 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 a name consisting of the components at indexes in the range
+ * [0,posn].
+ * @throws ArrayIndexOutOfBoundsException
+ * if posn is outside the specified range
+ */
+ public Name getPrefix( int posn )
+ {
+ if ( rdns.size() == 0 )
+ {
+ return EMPTY_LDAPDN;
+ }
+
+ if ( ( posn < 0 ) || ( posn > rdns.size() ) )
+ {
+ String message = "The posn(" + posn + ") should be in the range [0, " + rdns.size() + "]";
+ log.error( message );
+ throw new ArrayIndexOutOfBoundsException( message );
+ }
+
+ LdapDN newLdapDN = new LdapDN();
+
+ for ( int i = rdns.size() - posn; i < rdns.size(); i++ )
+ {
+ // Don't forget to clone the rdns !
+ newLdapDN.rdns.add( ( ( Rdn ) rdns.get( i ) ).clone() );
+ }
+
+ newLdapDN.normName = newLdapDN.toNormName();
+ newLdapDN.upName = getUpNamePrefix( posn );
+
+ return newLdapDN;
+ }
+
+
+ /**
+ * Creates a name whose components consist of a suffix of the components in
+ * this 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 a name consisting of the components at indexes in the range
+ * [posn,size()]. If posn is equal to size(), an empty name is
+ * returned.
+ * @throws ArrayIndexOutOfBoundsException
+ * if posn is outside the specified range
+ */
+ public Name getSuffix( int posn )
+ {
+ if ( rdns.size() == 0 )
+ {
+ return EMPTY_LDAPDN;
+ }
+
+ if ( ( posn < 0 ) || ( posn > rdns.size() ) )
+ {
+ String message = "The posn(" + posn + ") should be in the range [0, " + rdns.size() + "]";
+ log.error( message );
+ throw new ArrayIndexOutOfBoundsException( message );
+ }
+
+ LdapDN newLdapDN = new LdapDN();
+
+ for ( int i = 0; i < size() - posn; i++ )
+ {
+ // Don't forget to clone the rdns !
+ newLdapDN.rdns.add( ( ( Rdn ) rdns.get( i ) ).clone() );
+ }
+
+ newLdapDN.normName = newLdapDN.toNormName();
+ newLdapDN.upName = getUpNameSuffix( posn );
+
+ return newLdapDN;
+ }
+
+
+ /**
+ * Adds the components of a name -- in order -- to the end of this name.
+ *
+ * @param suffix
+ * the components to add
+ * @return the updated name (not a new one)
+ * @throws InvalidNameException
+ * if <tt>suffix</tt> is not a valid name, or if the addition
+ * of the components would violate the syntax rules of this name
+ */
+ public Name addAll( Name suffix ) throws InvalidNameException
+ {
+ addAll( rdns.size(), suffix );
+ normalizeInternal();
+ toUpName();
+
+ return this;
+ }
+
+
+ /**
+ * Adds the components of a name -- in order -- at a specified position
+ * within this name. Components of this name at or after the index of the
+ * first new component are shifted up (away from 0) to accommodate the new
+ * components.
+ *
+ * @param name
+ * the components to add
+ * @param posn
+ * the index in this name at which to add the new components.
+ * Must be in the range [0,size()].
+ * @return the updated name (not a new one)
+ * @throws ArrayIndexOutOfBoundsException
+ * if posn is outside the specified range
+ * @throws InvalidNameException
+ * if <tt>n</tt> is not a valid name, or if the addition of
+ * the components would violate the syntax rules of this name
+ */
+ public Name addAll( int posn, Name name ) throws InvalidNameException
+ {
+ if ( name instanceof LdapDN )
+ {
+ if ( ( name == null ) || ( name.size() == 0 ) )
+ {
+ return this;
+ }
+
+ // Concatenate the rdns
+ rdns.addAll( size() - posn, ( ( LdapDN ) name ).rdns );
+
+ // Regenerate the normalized name and the original string
+ normalizeInternal();
+ toUpName();
+
+ return this;
+ }
+ else
+ {
+ log.error( "Not a valid LdapDN suffix : " + name );
+ throw new InvalidNameException( "The suffix is not a LdapDN" );
+ }
+ }
+
+
+ /**
+ * Adds a single component to the end of this name.
+ *
+ * @param comp
+ * the component to add
+ * @return the updated name (not a new one)
+ * @throws InvalidNameException
+ * if adding <tt>comp</tt> would violate the syntax rules of
+ * this name
+ */
+ public Name add( String comp ) throws InvalidNameException
+ {
+ // We have to parse the nameComponent which is given as an argument
+ Rdn newRdn = new Rdn( comp );
+
+ rdns.add( 0, newRdn );
+ normalizeInternal();
+ toUpName();
+
+ return this;
+ }
+
+ /**
+ * Adds a single component to the end of this name.
+ *
+ * @param comp
+ * the component to add
+ * @return the updated name (not a new one)
+ * @throws InvalidNameException
+ * if adding <tt>comp</tt> would violate the syntax rules of
+ * this name
+ */
+ public Name add( Rdn newRdn ) throws InvalidNameException
+ {
+ rdns.add( 0, newRdn );
+ normalizeInternal();
+ toUpName();
+
+ return this;
+ }
+
+ /**
+ * Adds a single component at a specified position within this name.
+ * Components of this name at or after the index of the new component are
+ * shifted up by one (away from index 0) to accommodate the new component.
+ *
+ * @param comp
+ * the component 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 one)
+ * @throws ArrayIndexOutOfBoundsException
+ * if posn is outside the specified range
+ * @throws InvalidNameException
+ * if adding <tt>comp</tt> would violate the syntax rules of
+ * this name
+ */
+ public Name add( int posn, String comp ) throws InvalidNameException
+ {
+ if ( ( posn < 0 ) || ( posn > size() ) )
+ {
+ String message = "The posn(" + posn + ") should be in the range [0, " + rdns.size() + "]";
+ log.error( message );
+ throw new ArrayIndexOutOfBoundsException( message );
+ }
+
+ // We have to parse the nameComponent which is given as an argument
+ Rdn newRdn = new Rdn( comp );
+
+ int realPos = size() - posn;
+ rdns.add( realPos, newRdn );
+
+ normalizeInternal();
+ toUpName();
+
+ return this;
+ }
+
+
+ /**
+ * Removes a component from this name. The component of this name at the
+ * specified position is removed. Components with indexes greater than this
+ * position 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 ArrayIndexOutOfBoundsException
+ * 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
+ {
+ if ( rdns.size() == 0 )
+ {
+ return EMPTY_LDAPDN;
+ }
+
+ if ( ( posn < 0 ) || ( posn >= rdns.size() ) )
+ {
+ String message = "The posn(" + posn + ") should be in the range [0, " + rdns.size() + "]";
+ log.error( message );
+ throw new ArrayIndexOutOfBoundsException( message );
+ }
+
+ int realPos = size() - posn - 1;
+ Rdn rdn = ( Rdn ) rdns.remove( realPos );
+
+ normalizeInternal();
+ toUpName();
+
+ return rdn;
+ }
+
+
+ /**
+ * 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 this name
+ * @see Object#clone()
+ */
+ public Object clone()
+ {
+ try
+ {
+ LdapDN dn = ( LdapDN ) super.clone();
+ dn.rdns = new ArrayList();
+
+ for ( int i = 0; i < rdns.size(); i++ )
+ {
+ dn.rdns.add( i, ( ( Rdn ) rdns.get( i ) ).clone() );
+ }
+
+ return dn;
+ }
+ catch ( CloneNotSupportedException cnse )
+ {
+ log.error( "The clone operation has failed" );
+ throw new Error( "Assertion failure : cannot clone the object" );
+ }
+ }
+
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals( Object obj )
+ {
+ if ( obj instanceof String )
+ {
+ return normName.equals( obj );
+ }
+ else if ( obj instanceof LdapDN )
+ {
+ LdapDN name = ( LdapDN ) obj;
+
+ if ( name.size() != this.size() )
+ {
+ return false;
+ }
+
+ for ( int i = 0; i < size(); i++ )
+ {
+ if ( ( ( Rdn ) name.rdns.get( i ) ).compareTo( rdns.get( i ) ) != 0 )
+ {
+ return false;
+ }
+ }
+
+ // All components matched so we return true
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ /**
+ * Compares this name with another name for order. Returns a negative
+ * integer, zero, or a positive integer as this name is less than, equal to,
+ * or greater than the given name.
+ * <p>
+ * As with <tt>Object.equals()</tt>, the notion of ordering for names
+ * depends on the class that implements this interface. For example, the
+ * ordering may be based on lexicographical ordering of the name components.
+ * Specific attributes of the name, such as how it treats case, may affect
+ * the ordering. In general, two names of different classes may not be
+ * compared.
+ *
+ * @param obj
+ * the non-null object 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 name
+ * @throws ClassCastException
+ * if obj is not a <tt>Name</tt> of a type that may be
+ * compared with this name
+ * @see Comparable#compareTo(Object)
+ */
+ public int compareTo( Object obj )
+ {
+ if ( obj instanceof LdapDN )
+ {
+ LdapDN ldapDN = ( LdapDN ) obj;
+
+ if ( ldapDN.size() != size() )
+ {
+ return size() - ldapDN.size();
+ }
+
+ for ( int i = rdns.size(); i > 0; i-- )
+ {
+ Rdn rdn1 = ( Rdn ) rdns.get( i - 1 );
+ Rdn rdn2 = ( Rdn ) ldapDN.rdns.get( i - 1 );
+ int res = rdn1.compareTo( rdn2 );
+
+ if ( res != 0 )
+ {
+ return res;
+ }
+ }
+
+ return EQUALS;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+
+
+ private static AttributeTypeAndValue atavOidToName( AttributeTypeAndValue atav, Map oidsMap )
+ throws InvalidNameException, NamingException
+ {
+ String type = StringTools.trim( atav.getType() );
+
+ if ( ( type.startsWith( "oid." ) ) || ( type.startsWith( "OID." ) ) )
+ {
+ type = type.substring( 4 );
+ }
+
+ if ( StringTools.isNotEmpty( StringTools.lowerCase( type ) ) )
+ {
+ if ( oidsMap == null )
+ {
+ return atav;
+ }
+ else
+ {
+ OidNormalizer oidNormalizer = ( OidNormalizer ) oidsMap.get( type );
+
+ if ( oidNormalizer != null )
+ {
+ return new AttributeTypeAndValue( oidNormalizer.getAttributeTypeOid(), ( String ) oidNormalizer.getNormalizer()
+ .normalize( atav.getValue() ) );
+
+ }
+ else
+ {
+ // We don't have a normalizer for this OID : just do nothing.
+ return atav;
+ }
+ }
+ }
+ else
+ {
+ // The type is empty : this is not possible...
+ log.error( "Empty type not allowed in a DN" );
+ throw new InvalidNameException( "Empty type not allowed in a DN" );
+ }
+
+ }
+
+
+ /**
+ * Transform a RDN by changing the value to its OID counterpart and
+ * normalizing the value accordingly to its type.
+ *
+ * @param rdn
+ * The RDN to modify
+ * @param oids
+ * The map of all existing oids and normalizer
+ * @throws InvalidNameException
+ * If
+ * @throws NamingException
+ */
+ private static void rdnOidToName( Rdn rdn, Map oidsMap ) throws InvalidNameException, NamingException
+ {
+ if ( rdn.getNbAtavs() > 1 )
+ {
+ // We have more than one ATAV for this RDN. We will loop on all
+ // ATAVs
+ Rdn rdnCopy = ( Rdn ) rdn.clone();
+ rdn.clear();
+
+ Iterator atavs = rdnCopy.iterator();
+
+ while ( atavs.hasNext() )
+ {
+ Object val = atavs.next();
+ AttributeTypeAndValue newAtav = atavOidToName( ( AttributeTypeAndValue ) val, oidsMap );
+ rdn.addAttributeTypeAndValue( newAtav.getType(), newAtav.getValue() );
+ }
+
+ }
+ else
+ {
+ String type = StringTools.trim( rdn.getType() );
+
+ if ( ( type.startsWith( "oid." ) ) || ( type.startsWith( "OID." ) ) )
+ {
+ type = type.substring( 4 );
+ }
+
+ if ( StringTools.isNotEmpty( StringTools.lowerCase( type ) ) )
+ {
+ if ( oidsMap == null )
+ {
+ return;
+ }
+ else
+ {
+ OidNormalizer oidNormalizer = ( OidNormalizer ) oidsMap.get( type );
+
+ if ( oidNormalizer != null )
+ {
+ // Alex asks: Why clone here when we do not use the cloned copy?
+ Rdn rdnCopy = ( Rdn ) rdn.clone();
+ rdn.clear();
+ Object value = rdnCopy.getValue();
+ value = DefaultStringNormalizer.normalizeString( ( String ) value );
+
+ rdn.addAttributeTypeAndValue( oidNormalizer.getAttributeTypeOid(),
+ ( String ) oidNormalizer.getNormalizer()
+ .normalize( value ) );
+
+ }
+ else
+ {
+ // We don't have a normalizer for this OID : just do
+ // nothing.
+ return;
+ }
+ }
+ }
+ else
+ {
+ // The type is empty : this is not possible...
+ log.error( "We should not have an empty DN" );
+ throw new InvalidNameException( "Empty type not allowed in a DN" );
+ }
+ }
+ }
+
+
+ /**
+ * Change the internal DN, using the first alias instead of oids or other
+ * aliases. As we still have the UP name of each RDN, we will be able to
+ * provide both representation of the DN. example : dn: 2.5.4.3=People,
+ * dc=example, domainComponent=com will be transformed to : cn=People,
+ * dc=example, dc=com because 2.5.4.3 is the OID for cn and dc is the first
+ * alias of the couple of aliases (dc, domaincomponent). This is really
+ * important do have such a representation, as 'cn' and 'commonname' share
+ * the same OID.
+ *
+ * @param dn
+ * The DN to transform
+ * @param oids
+ * The mapping between names and oids.
+ * @return A normalized form of the DN
+ * @throws InvalidNameException
+ * If the DN is invalid
+ */
+ public static LdapDN normalize( LdapDN dn, Map oidsMap ) throws InvalidNameException, NamingException
+ {
+ if ( ( dn == null ) || ( dn.size() == 0 ) || ( oidsMap == null ) || ( oidsMap.size() == 0 ) )
+ {
+ return dn;
+ }
+
+ LdapDN newDn = ( LdapDN ) dn.clone();
+
+ Enumeration rdns = newDn.getAllRdn();
+
+ // Loop on all RDNs
+ while ( rdns.hasMoreElements() )
+ {
+ Rdn rdn = ( Rdn ) rdns.nextElement();
+ String upName = rdn.getUpName();
+ rdnOidToName( rdn, oidsMap );
+ rdn.normalizeString();
+ rdn.setUpName( upName );
+ }
+
+ newDn.normalizeInternal();
+
+ return newDn;
+ }
+
+ /**
+ * Change the internal DN, using the first alias instead of oids or other
+ * aliases. As we still have the UP name of each RDN, we will be able to
+ * provide both representation of the DN. example : dn: 2.5.4.3=People,
+ * dc=example, domainComponent=com will be transformed to : cn=People,
+ * dc=example, dc=com because 2.5.4.3 is the OID for cn and dc is the first
+ * alias of the couple of aliases (dc, domaincomponent). This is really
+ * important do have such a representation, as 'cn' and 'commonname' share
+ * the same OID.
+ *
+ * @param dn
+ * The DN to transform
+ * @param oids
+ * The mapping between names and oids.
+ * @return A normalized form of the DN
+ * @throws InvalidNameException
+ * If the DN is invalid
+ */
+ public void normalize( Map oidsMap ) throws InvalidNameException, NamingException
+ {
+ if ( ( oidsMap == null ) || ( oidsMap.size() == 0 ) )
+ {
+ return;
+ }
+
+ Enumeration rdns = getAllRdn();
+
+ // Loop on all RDNs
+ while ( rdns.hasMoreElements() )
+ {
+ Rdn rdn = ( Rdn ) rdns.nextElement();
+ String upName = rdn.getUpName();
+ rdnOidToName( rdn, oidsMap );
+ rdn.normalizeString();
+ rdn.setUpName( upName );
+ }
- return rdn;
- }
- }
-
- /**
- * Retrieves the last component of this name.
- *
- * @return the last component of this DN
- */
- public Rdn getRdn()
- {
- if ( rdns.size() == 0 )
- {
- return null;
- }
- else
- {
- Rdn rdn = ( Rdn ) rdns.get( 0 );
-
- return rdn;
- }
- }
-
-
- /**
- * Retrieves all the components of this name.
- *
- * @return All the components
- */
- public List getRdns()
- {
- List newRdns = new ArrayList();
-
- // We will clone the list, to avoid user modifications
- for ( int i = 0; i < rdns.size(); i++ )
- {
- newRdns.add( i, ( ( Rdn ) rdns.get( i ) ).clone() );
- }
-
- return newRdns;
- }
-
-
- /**
- * Retrieves the components of this name as an enumeration of strings. The
- * effect on the enumeration of updates to this name is undefined. If the
- * name has zero components, an empty (non-null) enumeration is returned.
- *
- * @return an enumeration of the components of this name, each as string
- */
- public Enumeration getAll()
- {
- /*
- * Note that by accessing the name component using the get() method on
- * the name rather than get() on the list we are reading components from
- * right to left with increasing index values. LdapName.get() does the
- * index translation on m_list for us.
- */
- return new Enumeration()
- {
- private int pos;
-
-
- public boolean hasMoreElements()
- {
- return pos < rdns.size();
- }
-
-
- public Object nextElement()
- {
- if ( pos >= rdns.size() )
- {
- log.error( "Exceeded number of elements in the current object" );
- throw new NoSuchElementException();
- }
-
- Object obj = rdns.get( rdns.size() - pos - 1 );
- pos++;
- return obj.toString();
- }
- };
- }
-
-
- /**
- * Retrieves the components of this name as an enumeration of strings. The
- * effect on the enumeration of updates to this name is undefined. If the
- * name has zero components, an empty (non-null) enumeration is returned.
- *
- * @return an enumeration of the components of this name, as Rdn
- */
- public Enumeration getAllRdn()
- {
- /*
- * Note that by accessing the name component using the get() method on
- * the name rather than get() on the list we are reading components from
- * right to left with increasing index values. LdapName.get() does the
- * index translation on m_list for us.
- */
- return new Enumeration()
- {
- private int pos;
-
-
- public boolean hasMoreElements()
- {
- return pos < rdns.size();
- }
-
-
- public Object nextElement()
- {
- if ( pos >= rdns.size() )
- {
- log.error( "Exceeded number of elements in the current object" );
- throw new NoSuchElementException();
- }
-
- Object obj = rdns.get( rdns.size() - pos - 1 );
- pos++;
- return obj;
- }
- };
- }
-
-
- /**
- * Creates a name whose components consist of a prefix of the components of
- * this 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 a name consisting of the components at indexes in the range
- * [0,posn].
- * @throws ArrayIndexOutOfBoundsException
- * if posn is outside the specified range
- */
- public Name getPrefix( int posn )
- {
- if ( rdns.size() == 0 )
- {
- return EMPTY_LDAPDN;
- }
-
- if ( ( posn < 0 ) || ( posn > rdns.size() ) )
- {
- String message = "The posn(" + posn + ") should be in the range [0, " + rdns.size() + "]";
- log.error( message );
- throw new ArrayIndexOutOfBoundsException( message );
- }
-
- LdapDN newLdapDN = new LdapDN();
-
- for ( int i = rdns.size() - posn; i < rdns.size(); i++ )
- {
- // Don't forget to clone the rdns !
- newLdapDN.rdns.add( ( ( Rdn ) rdns.get( i ) ).clone() );
- }
-
- newLdapDN.normName = newLdapDN.toNormName();
- newLdapDN.upName = getUpNamePrefix( posn );
-
- return newLdapDN;
- }
-
-
- /**
- * Creates a name whose components consist of a suffix of the components in
- * this 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 a name consisting of the components at indexes in the range
- * [posn,size()]. If posn is equal to size(), an empty name is
- * returned.
- * @throws ArrayIndexOutOfBoundsException
- * if posn is outside the specified range
- */
- public Name getSuffix( int posn )
- {
- if ( rdns.size() == 0 )
- {
- return EMPTY_LDAPDN;
- }
-
- if ( ( posn < 0 ) || ( posn > rdns.size() ) )
- {
- String message = "The posn(" + posn + ") should be in the range [0, " + rdns.size() + "]";
- log.error( message );
- throw new ArrayIndexOutOfBoundsException( message );
- }
-
- LdapDN newLdapDN = new LdapDN();
-
- for ( int i = 0; i < size() - posn; i++ )
- {
- // Don't forget to clone the rdns !
- newLdapDN.rdns.add( ( ( Rdn ) rdns.get( i ) ).clone() );
- }
-
- newLdapDN.normName = newLdapDN.toNormName();
- newLdapDN.upName = getUpNameSuffix( posn );
-
- return newLdapDN;
- }
-
-
- /**
- * Adds the components of a name -- in order -- to the end of this name.
- *
- * @param suffix
- * the components to add
- * @return the updated name (not a new one)
- * @throws InvalidNameException
- * if <tt>suffix</tt> is not a valid name, or if the addition
- * of the components would violate the syntax rules of this name
- */
- public Name addAll( Name suffix ) throws InvalidNameException
- {
- addAll( rdns.size(), suffix );
- normalizeInternal();
- toUpName();
-
- return this;
- }
-
-
- /**
- * Adds the components of a name -- in order -- at a specified position
- * within this name. Components of this name at or after the index of the
- * first new component are shifted up (away from 0) to accommodate the new
- * components.
- *
- * @param name
- * the components to add
- * @param posn
- * the index in this name at which to add the new components.
- * Must be in the range [0,size()].
- * @return the updated name (not a new one)
- * @throws ArrayIndexOutOfBoundsException
- * if posn is outside the specified range
- * @throws InvalidNameException
- * if <tt>n</tt> is not a valid name, or if the addition of
- * the components would violate the syntax rules of this name
- */
- public Name addAll( int posn, Name name ) throws InvalidNameException
- {
- if ( name instanceof LdapDN )
- {
- if ( ( name == null ) || ( name.size() == 0 ) )
- {
- return this;
- }
-
- // Concatenate the rdns
- rdns.addAll( size() - posn, ( ( LdapDN ) name ).rdns );
-
- // Regenerate the normalized name and the original string
- normalizeInternal();
- toUpName();
-
- return this;
- }
- else
- {
- log.error( "Not a valid LdapDN suffix : " + name );
- throw new InvalidNameException( "The suffix is not a LdapDN" );
- }
- }
-
-
- /**
- * Adds a single component to the end of this name.
- *
- * @param comp
- * the component to add
- * @return the updated name (not a new one)
- * @throws InvalidNameException
- * if adding <tt>comp</tt> would violate the syntax rules of
- * this name
- */
- public Name add( String comp ) throws InvalidNameException
- {
- // We have to parse the nameComponent which is given as an argument
- Rdn newRdn = new Rdn( comp );
-
- rdns.add( 0, newRdn );
- normalizeInternal();
- toUpName();
-
- return this;
- }
-
- /**
- * Adds a single component to the end of this name.
- *
- * @param comp
- * the component to add
- * @return the updated name (not a new one)
- * @throws InvalidNameException
- * if adding <tt>comp</tt> would violate the syntax rules of
- * this name
- */
- public Name add( Rdn newRdn ) throws InvalidNameException
- {
- rdns.add( 0, newRdn );
- normalizeInternal();
- toUpName();
-
- return this;
- }
-
- /**
- * Adds a single component at a specified position within this name.
- * Components of this name at or after the index of the new component are
- * shifted up by one (away from index 0) to accommodate the new component.
- *
- * @param comp
- * the component 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 one)
- * @throws ArrayIndexOutOfBoundsException
- * if posn is outside the specified range
- * @throws InvalidNameException
- * if adding <tt>comp</tt> would violate the syntax rules of
- * this name
- */
- public Name add( int posn, String comp ) throws InvalidNameException
- {
- if ( ( posn < 0 ) || ( posn > size() ) )
- {
- String message = "The posn(" + posn + ") should be in the range [0, " + rdns.size() + "]";
- log.error( message );
- throw new ArrayIndexOutOfBoundsException( message );
- }
-
- // We have to parse the nameComponent which is given as an argument
- Rdn newRdn = new Rdn( comp );
-
- int realPos = size() - posn;
- rdns.add( realPos, newRdn );
-
- normalizeInternal();
- toUpName();
-
- return this;
- }
-
-
- /**
- * Removes a component from this name. The component of this name at the
- * specified position is removed. Components with indexes greater than this
- * position 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 ArrayIndexOutOfBoundsException
- * 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
- {
- if ( rdns.size() == 0 )
- {
- return EMPTY_LDAPDN;
- }
-
- if ( ( posn < 0 ) || ( posn >= rdns.size() ) )
- {
- String message = "The posn(" + posn + ") should be in the range [0, " + rdns.size() + "]";
- log.error( message );
- throw new ArrayIndexOutOfBoundsException( message );
- }
-
- int realPos = size() - posn - 1;
- Rdn rdn = ( Rdn ) rdns.remove( realPos );
-
- normalizeInternal();
- toUpName();
-
- return rdn;
- }
-
-
- /**
- * 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 this name
- * @see Object#clone()
- */
- public Object clone()
- {
- try
- {
- LdapDN dn = ( LdapDN ) super.clone();
- dn.rdns = new ArrayList();
-
- for ( int i = 0; i < rdns.size(); i++ )
- {
- dn.rdns.add( i, ( ( Rdn ) rdns.get( i ) ).clone() );
- }
-
- return dn;
- }
- catch ( CloneNotSupportedException cnse )
- {
- log.error( "The clone operation has failed" );
- throw new Error( "Assertion failure : cannot clone the object" );
- }
- }
-
-
- /**
- * @see java.lang.Object#equals(java.lang.Object)
- */
- public boolean equals( Object obj )
- {
- if ( obj instanceof String )
- {
- return normName.equals( obj );
- }
- else if ( obj instanceof LdapDN )
- {
- LdapDN name = ( LdapDN ) obj;
-
- if ( name.size() != this.size() )
- {
- return false;
- }
-
- for ( int i = 0; i < size(); i++ )
- {
- if ( ( ( Rdn ) name.rdns.get( i ) ).compareTo( rdns.get( i ) ) != 0 )
- {
- return false;
- }
- }
-
- // All components matched so we return true
- return true;
- }
- else
- {
- return false;
- }
- }
-
-
- /**
- * Compares this name with another name for order. Returns a negative
- * integer, zero, or a positive integer as this name is less than, equal to,
- * or greater than the given name.
- * <p>
- * As with <tt>Object.equals()</tt>, the notion of ordering for names
- * depends on the class that implements this interface. For example, the
- * ordering may be based on lexicographical ordering of the name components.
- * Specific attributes of the name, such as how it treats case, may affect
- * the ordering. In general, two names of different classes may not be
- * compared.
- *
- * @param obj
- * the non-null object 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 name
- * @throws ClassCastException
- * if obj is not a <tt>Name</tt> of a type that may be
- * compared with this name
- * @see Comparable#compareTo(Object)
- */
- public int compareTo( Object obj )
- {
- if ( obj instanceof LdapDN )
- {
- LdapDN ldapDN = ( LdapDN ) obj;
-
- if ( ldapDN.size() != size() )
- {
- return size() - ldapDN.size();
- }
-
- for ( int i = rdns.size(); i > 0; i-- )
- {
- Rdn rdn1 = ( Rdn ) rdns.get( i - 1 );
- Rdn rdn2 = ( Rdn ) ldapDN.rdns.get( i - 1 );
- int res = rdn1.compareTo( rdn2 );
-
- if ( res != 0 )
- {
- return res;
- }
- }
-
- return EQUALS;
- }
- else
- {
- return 1;
- }
- }
-
-
- private static AttributeTypeAndValue atavOidToName( AttributeTypeAndValue atav, Map oidsMap )
- throws InvalidNameException, NamingException
- {
- String type = StringTools.trim( atav.getType() );
-
- if ( ( type.startsWith( "oid." ) ) || ( type.startsWith( "OID." ) ) )
- {
- type = type.substring( 4 );
- }
-
- if ( StringTools.isNotEmpty( StringTools.lowerCase( type ) ) )
- {
- if ( oidsMap == null )
- {
- return atav;
- }
- else
- {
- OidNormalizer oidNormalizer = ( OidNormalizer ) oidsMap.get( type );
-
- if ( oidNormalizer != null )
- {
- return new AttributeTypeAndValue( oidNormalizer.getAttributeTypeOid(), ( String ) oidNormalizer.getNormalizer()
- .normalize( atav.getValue() ) );
-
- }
- else
- {
- // We don't have a normalizer for this OID : just do nothing.
- return atav;
- }
- }
- }
- else
- {
- // The type is empty : this is not possible...
- log.error( "Empty type not allowed in a DN" );
- throw new InvalidNameException( "Empty type not allowed in a DN" );
- }
-
- }
-
-
- /**
- * Transform a RDN by changing the value to its OID counterpart and
- * normalizing the value accordingly to its type.
- *
- * @param rdn
- * The RDN to modify
- * @param oids
- * The map of all existing oids and normalizer
- * @throws InvalidNameException
- * If
- * @throws NamingException
- */
- private static void rdnOidToName( Rdn rdn, Map oidsMap ) throws InvalidNameException, NamingException
- {
- if ( rdn.getNbAtavs() > 1 )
- {
- // We have more than one ATAV for this RDN. We will loop on all
- // ATAVs
- Rdn rdnCopy = ( Rdn ) rdn.clone();
- rdn.clear();
-
- Iterator atavs = rdnCopy.iterator();
-
- while ( atavs.hasNext() )
- {
- Object val = atavs.next();
- AttributeTypeAndValue newAtav = atavOidToName( ( AttributeTypeAndValue ) val, oidsMap );
- rdn.addAttributeTypeAndValue( newAtav.getType(), newAtav.getValue() );
- }
-
- }
- else
- {
- String type = StringTools.trim( rdn.getType() );
-
- if ( ( type.startsWith( "oid." ) ) || ( type.startsWith( "OID." ) ) )
- {
- type = type.substring( 4 );
- }
-
- if ( StringTools.isNotEmpty( StringTools.lowerCase( type ) ) )
- {
- if ( oidsMap == null )
- {
- return;
- }
- else
- {
- OidNormalizer oidNormalizer = ( OidNormalizer ) oidsMap.get( type );
-
- if ( oidNormalizer != null )
- {
- // Alex asks: Why clone here when we do not use the cloned copy?
- Rdn rdnCopy = ( Rdn ) rdn.clone();
- rdn.clear();
- Object value = rdnCopy.getValue();
- value = DefaultStringNormalizer.normalizeString( ( String ) value );
-
- rdn.addAttributeTypeAndValue( oidNormalizer.getAttributeTypeOid(),
- ( String ) oidNormalizer.getNormalizer()
- .normalize( value ) );
-
- }
- else
- {
- // We don't have a normalizer for this OID : just do
- // nothing.
- return;
- }
- }
- }
- else
- {
- // The type is empty : this is not possible...
- log.error( "We should not have an empty DN" );
- throw new InvalidNameException( "Empty type not allowed in a DN" );
- }
- }
- }
-
-
- /**
- * Change the internal DN, using the first alias instead of oids or other
- * aliases. As we still have the UP name of each RDN, we will be able to
- * provide both representation of the DN. example : dn: 2.5.4.3=People,
- * dc=example, domainComponent=com will be transformed to : cn=People,
- * dc=example, dc=com because 2.5.4.3 is the OID for cn and dc is the first
- * alias of the couple of aliases (dc, domaincomponent). This is really
- * important do have such a representation, as 'cn' and 'commonname' share
- * the same OID.
- *
- * @param dn
- * The DN to transform
- * @param oids
- * The mapping between names and oids.
- * @return A normalized form of the DN
- * @throws InvalidNameException
- * If the DN is invalid
- */
- public static LdapDN normalize( LdapDN dn, Map oidsMap ) throws InvalidNameException, NamingException
- {
- if ( ( dn == null ) || ( dn.size() == 0 ) || ( oidsMap == null ) || ( oidsMap.size() == 0 ) )
- {
- return dn;
- }
-
- LdapDN newDn = ( LdapDN ) dn.clone();
-
- Enumeration rdns = newDn.getAllRdn();
-
- // Loop on all RDNs
- while ( rdns.hasMoreElements() )
- {
- Rdn rdn = ( Rdn ) rdns.nextElement();
- String upName = rdn.getUpName();
- rdnOidToName( rdn, oidsMap );
- rdn.normalizeString();
- rdn.setUpName( upName );
- }
-
- newDn.normalizeInternal();
-
- return newDn;
- }
-
- /**
- * Change the internal DN, using the first alias instead of oids or other
- * aliases. As we still have the UP name of each RDN, we will be able to
- * provide both representation of the DN. example : dn: 2.5.4.3=People,
- * dc=example, domainComponent=com will be transformed to : cn=People,
- * dc=example, dc=com because 2.5.4.3 is the OID for cn and dc is the first
- * alias of the couple of aliases (dc, domaincomponent). This is really
- * important do have such a representation, as 'cn' and 'commonname' share
- * the same OID.
- *
- * @param dn
- * The DN to transform
- * @param oids
- * The mapping between names and oids.
- * @return A normalized form of the DN
- * @throws InvalidNameException
- * If the DN is invalid
- */
- public void normalize( Map oidsMap ) throws InvalidNameException, NamingException
- {
- if ( ( oidsMap == null ) || ( oidsMap.size() == 0 ) )
- {
- return;
- }
-
- Enumeration rdns = getAllRdn();
-
- // Loop on all RDNs
- while ( rdns.hasMoreElements() )
- {
- Rdn rdn = ( Rdn ) rdns.nextElement();
- String upName = rdn.getUpName();
- rdnOidToName( rdn, oidsMap );
- rdn.normalizeString();
- rdn.setUpName( upName );
- }
-
- normalizeInternal();
- }
+ normalizeInternal();
+ }
}
Modified: directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDnParser.java
URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDnParser.java?rev=433074&r1=433073&r2=433074&view=diff
==============================================================================
--- directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDnParser.java (original)
+++ directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDnParser.java Sun Aug 20 15:54:54 2006
@@ -60,104 +60,106 @@
* [\"] <br> - <separator> ::= ',' | ';' <br> - <spaces> ::= ' '
* <spaces> | e <br>
* </p>
- *
+ *
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class LdapDnParser implements NameParser
{
- private static LdapDnParser instance = new LdapDnParser();
+ private static LdapDnParser instance = new LdapDnParser();
- /**
- * A private constructor. It's useless, as this object is totally stateless,
- * but we need to expose a NameParser.
- */
- private LdapDnParser()
- {
- }
-
-
- /**
- * Get a reference to the NameParser. Needed to be compliant with the JNDI
- * API
- *
- * @return An instance of the NameParser
- */
- public static NameParser getNameParser()
- {
- return instance;
- }
-
-
- /**
- * Parse a DN
- *
- * @param dn
- * The DN to be parsed
- * @param rdns
- * The list that will contain the RDNs
- * @throws InvalidNameException
- * If the DN is invalid
- */
- public static void parseInternal( String dn, List rdns ) throws InvalidNameException
- {
- if ( dn.length() == 0 )
- {
- // We have an empty DN, just get out of the function.
- return;
- }
-
- Position pos = new Position();
- pos.start = 0;
- Rdn rdn = new Rdn();
-
- // <name> ::= <name-component> <name-components>
- // <name-components> ::= <spaces> <separator> <spaces> <name-component>
- // <name-components> | e
- if ( RdnParser.parse( dn, pos, rdn ) != DNUtils.PARSING_ERROR )
- {
- // Now, parse the following nameComponents
- do
- {
- rdns.add( rdn );
- rdn = new Rdn();
-
- if ( ( StringTools.isCharASCII( dn, pos.start, ',' ) == false )
- && ( StringTools.isCharASCII( dn, pos.start, ';' ) == false ) )
- {
-
- if ( pos.start != dn.length() )
- {
- throw new InvalidNameException( "Bad DN : " + dn );
- }
- else
- {
- break;
- }
- }
-
- pos.start++;
- }
- while ( RdnParser.parse( dn, pos, rdn ) != DNUtils.PARSING_ERROR );
- }
- else
- {
- throw new InvalidNameException( "Bad DN : " + dn );
- }
- }
-
-
- /**
- * Parse a String and return a LdapDN if the String is a valid DN
- *
- * @param dn
- * The DN to parse
- * @return A LdapDN
- * @throws InvalidNameException
- * If the String is not a valid DN
- */
- public Name parse( String dn ) throws InvalidNameException
- {
- return new LdapDN( dn );
- }
+ /**
+ * A private constructor. It's useless, as this object is totally stateless,
+ * but we need to expose a NameParser.
+ */
+ private LdapDnParser()
+ {
+ }
+
+
+ /**
+ * Get a reference to the NameParser. Needed to be compliant with the JNDI
+ * API
+ *
+ * @return An instance of the NameParser
+ */
+ public static NameParser getNameParser()
+ {
+ return instance;
+ }
+
+
+ /**
+ * Parse a DN
+ *
+ * @param dn
+ * The DN to be parsed
+ * @param rdns
+ * The list that will contain the RDNs
+ * @throws InvalidNameException
+ * If the DN is invalid
+ */
+ public static void parseInternal( String dn, List rdns ) throws InvalidNameException
+ {
+ if ( dn.length() == 0 )
+ {
+ // We have an empty DN, just get out of the function.
+ return;
+ }
+
+ Position pos = new Position();
+ pos.start = 0;
+ Rdn rdn = new Rdn();
+
+ // <name> ::= <name-component> <name-components>
+ // <name-components> ::= <spaces> <separator> <spaces> <name-component>
+ // <name-components> | e
+ if ( RdnParser.parse( dn, pos, rdn ) != DNUtils.PARSING_ERROR )
+ {
+ // Now, parse the following nameComponents
+ do
+ {
+ rdns.add( rdn );
+ rdn = new Rdn();
+
+ if ( ( StringTools.isCharASCII( dn, pos.start, ',' ) == false )
+ && ( StringTools.isCharASCII( dn, pos.start, ';' ) == false ) )
+ {
+
+ if ( pos.start != dn.length() )
+ {
+ throw new InvalidNameException( "Bad DN : " + dn );
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ pos.start++;
+ }
+ while ( RdnParser.parse( dn, pos, rdn ) != DNUtils.PARSING_ERROR );
+ }
+ else
+ {
+ throw new InvalidNameException( "Bad DN : " + dn );
+ }
+ }
+
+
+ /**
+ * Parse a String and return a LdapDN if the String is a valid DN
+ *
+ * @param dn
+ * The DN to parse
+ * @return A LdapDN
+ * @throws InvalidNameException
+ * If the String is not a valid DN
+ */
+ public Name parse( String dn ) throws InvalidNameException
+ {
+ return new LdapDN( dn );
+ }
}
+
+