directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r367149 [3/4] - in /directory/trunk/ldap-common/src: main/java/org/apache/ldap/common/codec/ main/java/org/apache/ldap/common/codec/add/ main/java/org/apache/ldap/common/codec/bind/ main/java/org/apache/ldap/common/codec/compare/ main/java/...
Date Mon, 09 Jan 2006 01:03:39 GMT
Added: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/name/RdnParser.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/name/RdnParser.java?rev=367149&view=auto
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/name/RdnParser.java (added)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/name/RdnParser.java Sun Jan  8 17:02:49 2006
@@ -0,0 +1,615 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.ldap.common.name;
+
+import javax.naming.InvalidNameException;
+
+import org.apache.ldap.common.util.DNUtils;
+import org.apache.ldap.common.util.StringTools;
+
+/**
+ * This class parse the name-component part or the following BNF grammar (as of RFC2253, par. 3, 
+ * and RFC1779, fig. 1) : <br>
+ * -    &lt;name-component&gt;         ::= &lt;attributeType&gt; &lt;spaces&gt; '=' &lt;spaces&gt; &lt;attributeValue&gt; &lt;attributeTypeAndValues&gt; <br>
+ * -    &lt;attributeTypeAndValues&gt; ::= &lt;spaces&gt; '+' &lt;spaces&gt; &lt;attributeType&gt; &lt;spaces&gt; '=' &lt;spaces&gt; &lt;attributeValue&gt; &lt;attributeTypeAndValues&gt; | e <br>
+ * -    &lt;attributeType&gt;          ::= [a-zA-Z] &lt;keychars&gt; | &lt;oidPrefix&gt; [0-9] &lt;digits&gt; &lt;oids&gt; | [0-9] &lt;digits&gt; &lt;oids&gt; <br>
+ * -    &lt;keychars&gt;               ::= [a-zA-Z] &lt;keychars&gt; | [0-9] &lt;keychars&gt; | '-' &lt;keychars&gt; | e <br>
+ * -    &lt;oidPrefix&gt;              ::= 'OID.' | 'oid.' | e <br>
+ * -    &lt;oids&gt;                   ::= '.' [0-9] &lt;digits&gt; &lt;oids&gt; | e <br>
+ * -    &lt;attributeValue&gt;         ::= &lt;pairs-or-strings&gt; | '#' &lt;hexstring&gt; |'"' &lt;quotechar-or-pairs&gt; '"' <br>
+ * -    &lt;pairs-or-strings&gt;       ::= '\' &lt;pairchar&gt; &lt;pairs-or-strings&gt; | &lt;stringchar&gt; &lt;pairs-or-strings&gt; | e <br>
+ * -    &lt;quotechar-or-pairs&gt;     ::= &lt;quotechar&gt; &lt;quotechar-or-pairs&gt; | '\' &lt;pairchar&gt; &lt;quotechar-or-pairs&gt; | e <br>
+ * -    &lt;pairchar&gt;               ::= ',' | '=' | '+' | '&lt;' | '&gt;' | '#' | ';' | '\' | '"' | [0-9a-fA-F] [0-9a-fA-F]  <br>
+ * -    &lt;hexstring&gt;              ::= [0-9a-fA-F] [0-9a-fA-F] &lt;hexpairs&gt; <br>
+ * -    &lt;hexpairs&gt;               ::= [0-9a-fA-F] [0-9a-fA-F] &lt;hexpairs&gt; | e <br>
+ * -    &lt;digits&gt;                 ::= [0-9] &lt;digits&gt; | e <br>
+ * -    &lt;stringchar&gt;             ::= [0x00-0xFF] - [,=+&lt;&gt;#;\"\n\r] <br>
+ * -    &lt;quotechar&gt;              ::= [0x00-0xFF] - [\"] <br>
+ * -    &lt;separator&gt;              ::= ',' | ';' <br>
+ * -    &lt;spaces&gt;                 ::= ' ' &lt;spaces&gt; | e <br>
+ *<br>
+ * A RDN is a part of a DN. It can be composed of many types, as in the RDN 
+ * following RDN :<br>
+ *   ou=value + cn=other value<br>
+ * <br>  
+ * In this case, we have to store an 'ou' and a 'cn' in the RDN.<br>
+ * <br>
+ * The types are case insensitive. <br>
+ * Spaces before and after types and values are not stored.<br>  
+ * Spaces before and after '+' are not stored.<br>
+ * <br>
+ * Thus, we can consider that the following RDNs are equals :<br>
+ * <br>
+ * 'ou=test 1'<br>
+ * '  ou=test 1'<br>
+ * 'ou  =test 1'<br>
+ * 'ou=  test 1'<br>
+ * 'ou=test 1 '<br>
+ * '  ou  =  test 1 '<br>
+ * <br>
+ * So are the following :<br>
+ * <br>
+ * 'ou=test 1+cn=test 2'<br>
+ * 'ou = test 1 + cn = test 2'<br>
+ * '  ou =test 1+  cn =test 2  ' <br>
+ * 'cn = test 2   +ou = test 1'<br>
+ * <br>
+ * but the following are not equal :<br>
+ * 'ou=test  1' <br>
+ * 'ou=test    1'<br> 
+ * because we have more than one spaces inside the value.<br>
+ * <br>
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class RdnParser
+{
+    /**
+     * Parse this rule : <br>
+     * <p>
+     * &lt;oidValue&gt; ::= [0-9] &lt;digits&gt; &lt;oids&gt; 
+     * </p>
+     * 
+     * @param chars The char array to parse
+     * @param pos The current position in the byte buffer
+     * @return The new position in the char array, or PARSING_ERROR if the rule does not apply to the char array
+     */
+    private static int parseOidValue(char[] chars, int pos)
+    {
+        // <attributType> ::= [0-9] <digits> <oids>
+        if ( StringTools.isDigit( chars, pos ) == false )
+        {
+            // Nope... An error
+            return DNUtils.PARSING_ERROR;
+        }
+        else
+        {
+            // Let's process an oid
+            pos++;
+
+            while ( StringTools.isDigit( chars, pos ) )
+            {
+                pos++;
+            }
+
+            // <oids> ::= '.' [0-9] <digits> <oids> | e
+            if ( StringTools.isCharASCII( chars, pos, '.' ) == false )
+            {
+                return pos;
+            }
+            else
+            {
+                do
+                {
+                    pos++;
+
+                    if ( StringTools.isDigit( chars, pos ) == false )
+                    {
+                        return DNUtils.PARSING_ERROR;
+                    }
+                    else
+                    {
+                        pos++;
+
+                        while ( StringTools.isDigit( chars, pos ) )
+                        {
+                            pos++;
+                        }
+                    }
+                }
+                while ( StringTools.isCharASCII( chars, pos, '.' ) );
+
+                return pos;
+            }
+        }
+    }
+
+    /**
+     * Parse this rule : <br>
+     * <p>
+     * &lt;oidPrefix&gt; ::= 'OID.' | 'oid.' | e
+     * </p>
+     * 
+     * @param bytes The buffer to parse
+     * @param pos The current position in the char array
+     * @return The new position in the char array, or PARSING_ERROR if the rule does not apply to the char array
+     */
+    private static int parseOidPrefix( char[] chars, int pos )
+    {
+        if ( ( StringTools.areEquals( chars, pos, DNUtils.OID_LOWER ) == DNUtils.PARSING_ERROR ) &&
+             ( StringTools.areEquals( chars, pos, DNUtils.OID_UPPER ) == DNUtils.PARSING_ERROR ) )
+        {
+            return DNUtils.PARSING_ERROR;
+        }
+        else
+        {
+            pos += DNUtils.OID_LOWER.length;
+
+            return pos;
+        }
+    }
+    
+    /**
+     * Parse this rule : <br>
+     * <p>
+     * &lt;attributType&gt; ::= [a-zA-Z] &lt;keychars&gt; | 
+     *                          &lt;oidPrefix&gt; [0-9] &lt;digits&gt; &lt;oids&gt; | 
+     *                          [0-9] &lt;digits&gt; &lt;oids&gt;
+     * </p>
+     * 
+     * The string *MUST* be an ASCII string, not an unicode string.
+     * 
+     * @param chars The char array to parse
+     * @param pos The current position in the char array
+     * @return The new position in the char array, or PARSING_ERROR if the rule does not apply to the char array
+     */
+    private static int parseAttributeType( char[] chars, int pos )
+    {
+        // <attributType> ::= [a-zA-Z] <keychars> | <oidPrefix> [0-9] <digits> <oids> | [0-9] <digits> <oids>
+        
+        if ( StringTools.isAlphaASCII( chars, pos ))
+        {
+            // <attributType> ::= [a-zA-Z] <keychars> | <oidPrefix> [0-9] <digits> <oids> 
+
+            // We have got an Alpha char, it may be the begining of an OID ?
+            int oldPos = pos;
+            
+            if ( ( pos = parseOidPrefix( chars, oldPos ) ) != DNUtils.PARSING_ERROR ) 
+            {
+                return parseOidValue(chars, pos);
+            }
+            else 
+            {
+                // It's not an oid, it's a String (ASCII)
+                // <attributType> ::= [a-zA-Z] <keychars>
+                // <keychars>       ::= [a-zA-Z] <keychar> | [0-9] <keychar> | '-' <keychar> | e
+                pos = oldPos + 1;
+
+                while ( StringTools.isAlphaDigitMinus( chars, pos ) )
+                {
+                    pos++;
+                }
+
+                return pos;
+            }
+        }
+        else
+        {
+
+            // An oid
+            // <attributType> ::= [0-9] <digits> <oids> 
+            return parseOidValue(chars, pos);
+        }
+    }
+
+    /**
+     * Parse this rule : <br>
+     * <p>
+     * &lt;attributeValue&gt;     ::= &lt;pairs-or-strings&gt; | '#' &lt;hexstring&gt; |'"' &lt;quotechar-or-pairs&gt; '"' <br>
+     * &lt;pairs-or-strings&gt;    ::= '\' &lt;pairchar&gt; &lt;pairs-or-strings&gt; | &lt;stringchar&gt; &lt;pairs-or-strings&gt; |  | e <br>
+     * &lt;quotechar-or-pairs&gt;    ::= &lt;quotechar&gt; &lt;quotechar-or-pairs&gt; | '\' &lt;pairchar&gt; &lt;quotechar-or-pairs&gt; | e <br>
+     * </p>
+     * 
+     * @param chars The char array to parse
+     * @param pos The current position in the char array
+     * @return The new position in the char array, or PARSING_ERROR if the rule does not apply to the char array
+     */
+    private static int parseAttributeValue( char[] chars, int pos )
+    {
+        if ( StringTools.isCharASCII( chars, pos, '#' ) )
+        {
+            pos++;
+
+            // <attributeValue> ::= '#' <hexstring>
+            if ( ( pos = DNUtils.parseHexString( chars, pos ) ) == DNUtils.PARSING_ERROR )
+            {
+
+                return DNUtils.PARSING_ERROR;
+            }
+
+            return StringTools.trimLeft( chars, pos );
+        }
+        else if ( StringTools.isCharASCII( chars, pos, '"' ) )
+        {
+            pos++;
+            int nbBytes = 0;
+
+            // <attributeValue>     ::= '"' <quotechar-or-pair> '"'
+            // <quotechar-or-pairs>    ::= <quotechar> <quotechar-or-pairs> | '\' <pairchar> <quotechar-or-pairs> | e
+            while ( true )
+            {
+                if ( StringTools.isCharASCII( chars, pos, '\\' ) )
+                {
+                    pos++;
+
+                    if ( DNUtils.isPairChar( chars, pos ) )
+                    {
+                        pos++;
+                    }
+                    else
+                    {
+                        return DNUtils.PARSING_ERROR;
+                    }
+                }
+                else if ( (nbBytes = DNUtils.isQuoteChar( chars, pos ) ) != DNUtils.PARSING_ERROR )
+                {
+                    pos += nbBytes;
+                }
+                else
+                {
+                    break;
+                }
+            }
+
+            if ( StringTools.isCharASCII( chars, pos, '"' ) )
+            {
+                pos++;
+
+                return StringTools.trimLeft( chars, pos );
+            }
+            else
+            {
+                return DNUtils.PARSING_ERROR;
+            }
+        }
+        else
+        {
+            while ( true )
+            {
+                if ( StringTools.isCharASCII( chars, pos, '\\' ) )
+                {
+                    // '\' <pairchar> <pairs-or-strings>
+                    pos++;
+
+                    if ( DNUtils.isPairChar( chars, pos ) == false )
+                    {
+                        return DNUtils.PARSING_ERROR;
+                    }
+                    else
+                    {
+                        pos++;
+                    }
+                }
+                else
+                {
+                    int nbChars = 0;
+                    
+                    // <stringchar> <pairs-or-strings>
+                    if ( ( nbChars = DNUtils.isStringChar( chars, pos )) != DNUtils.PARSING_ERROR )
+                    {
+                        // A special case : if we have some spaces before the '+' character,
+                        // we MUST skip them.
+                        if ( StringTools.isCharASCII( chars, pos, ' ') )
+                        {
+                            pos = StringTools.trimLeft( chars, pos );
+
+                            if ( ( DNUtils.isStringChar( chars, pos ) == DNUtils.PARSING_ERROR ) &&
+                                    ( StringTools.isCharASCII( chars, pos, '\\' ) == false ) )
+                            {
+                                // Ok, we are done with the stringchar.
+                                return pos;
+                            }
+                        }
+                        else
+                        {
+                            // An unicode char could be more than one byte long 
+                            pos += nbChars;
+                        }
+                    }
+                    else
+                    {
+                        return pos;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Parse this rule : <br>
+     * <p>
+     * &lt;nameComponents&gt;    ::= &lt;spaces&gt; '+' &lt;spaces&gt; &lt;attributeType&gt; &lt;spaces&gt; '=' &lt;spaces&gt; &lt;attributeValue&gt; &lt;nameComponents&gt; | e
+     * </p>
+     * 
+     * @param chars The char buffer to parse
+     * @param pos The current position in the byte buffer
+     * @return The new position in the char buffer, or PARSING_ERROR if the rule does not apply to the char buffer
+     */
+    private static int parseNameComponents( char[] chars, int pos, Rdn rdn ) throws InvalidNameException
+    {
+        int newPos = 0;
+        String type = null;
+        String value = null;
+
+        while ( true )
+        {
+            pos = StringTools.trimLeft( chars, pos );
+
+            if ( StringTools.isCharASCII( chars, pos, '+' ) )
+            {
+                pos++;
+            }
+            else
+            {
+                // <attributeTypeAndValues> ::= e
+                return pos;
+            }
+
+            pos = StringTools.trimLeft( chars, pos );
+
+            if ( ( newPos = parseAttributeType( chars, pos ) ) == DNUtils.PARSING_ERROR )
+            {
+                return DNUtils.PARSING_ERROR;
+            }
+
+            if ( rdn != null )
+            {
+                type = new String( chars, pos, newPos - pos );
+            }
+
+            pos = StringTools.trimLeft( chars, newPos );
+
+            if ( StringTools.isCharASCII( chars, pos, '=' ) )
+            {
+                pos++;
+            }
+            else
+            {
+                return DNUtils.PARSING_ERROR;
+            }
+
+            pos = StringTools.trimLeft( chars, pos );
+
+            newPos = parseAttributeValue( chars, pos );
+            
+            if ( newPos != DNUtils.PARSING_ERROR )
+            {
+                if ( rdn != null )
+                {
+                    newPos = StringTools.trimRight( chars, newPos );
+                    value = new String( chars, pos, newPos - pos );
+                    
+                    rdn.addAttributeTypeAndValue( type, value );
+                }
+            }
+            
+            pos = newPos;
+        }
+    }
+
+    /**
+     * Parse this rule : <br>
+     * <p>
+     * &lt;attributeValue&gt;     ::= &lt;pairs-or-strings&gt; | '#' &lt;hexstring&gt; |'"' &lt;quotechar-or-pairs&gt; '"' <br>
+     * &lt;pairs-or-strings&gt;    ::= '\' &lt;pairchar&gt; &lt;pairs-or-strings&gt; | &lt;stringchar&gt; &lt;pairs-or-strings&gt; |  | e <br>
+     * &lt;quotechar-or-pairs&gt;    ::= &lt;quotechar&gt; &lt;quotechar-or-pairs&gt; | '\' &lt;pairchar&gt; &lt;quotechar-or-pairs&gt; | e <br>
+     * </p>
+     * 
+     * @param chars The char array to parse
+     * @param pos The current position in the char array
+     * @return The new position in the char array, or PARSING_ERROR if the rule does not apply to the char array
+     */
+    public static int unescapeValue( String value ) throws IllegalArgumentException
+    {
+    	char[] chars = value.toCharArray();
+    	int pos = 0;
+    	
+        if ( StringTools.isCharASCII( chars, pos, '#' ) )
+        {
+            pos++;
+
+            // <attributeValue> ::= '#' <hexstring>
+            if ( ( pos = DNUtils.parseHexString( chars, pos ) ) == DNUtils.PARSING_ERROR )
+            {
+
+                throw new IllegalArgumentException();
+            }
+
+            return StringTools.trimLeft( chars, pos );
+        }
+        else if ( StringTools.isCharASCII( chars, pos, '"' ) )
+        {
+            pos++;
+            int nbBytes = 0;
+
+            // <attributeValue>     ::= '"' <quotechar-or-pair> '"'
+            // <quotechar-or-pairs>    ::= <quotechar> <quotechar-or-pairs> | '\' <pairchar> <quotechar-or-pairs> | e
+            while ( true )
+            {
+                if ( StringTools.isCharASCII( chars, pos, '\\' ) )
+                {
+                    pos++;
+
+                    if ( DNUtils.isPairChar( chars, pos ) )
+                    {
+                        pos++;
+                    }
+                    else
+                    {
+                        return DNUtils.PARSING_ERROR;
+                    }
+                }
+                else if ( (nbBytes = DNUtils.isQuoteChar( chars, pos ) ) != DNUtils.PARSING_ERROR )
+                {
+                    pos += nbBytes;
+                }
+                else
+                {
+                    break;
+                }
+            }
+
+            if ( StringTools.isCharASCII( chars, pos, '"' ) )
+            {
+                pos++;
+
+                return StringTools.trimLeft( chars, pos );
+            }
+            else
+            {
+                return DNUtils.PARSING_ERROR;
+            }
+        }
+        else
+        {
+            while ( true )
+            {
+                if ( StringTools.isCharASCII( chars, pos, '\\' ) )
+                {
+                    // '\' <pairchar> <pairs-or-strings>
+                    pos++;
+
+                    if ( DNUtils.isPairChar( chars, pos ) == false )
+                    {
+                        return DNUtils.PARSING_ERROR;
+                    }
+                    else
+                    {
+                        pos++;
+                    }
+                }
+                else
+                {
+                    int nbChars = 0;
+                    
+                    // <stringchar> <pairs-or-strings>
+                    if ( ( nbChars = DNUtils.isStringChar( chars, pos )) != DNUtils.PARSING_ERROR )
+                    {
+                        // A special case : if we have some spaces before the '+' character,
+                        // we MUST skip them.
+                        if ( StringTools.isCharASCII( chars, pos, ' ') )
+                        {
+                            pos = StringTools.trimLeft( chars, pos );
+
+                            if ( ( DNUtils.isStringChar( chars, pos ) == DNUtils.PARSING_ERROR ) &&
+                                    ( StringTools.isCharASCII( chars, pos, '\\' ) == false ) )
+                            {
+                                // Ok, we are done with the stringchar.
+                                return pos;
+                            }
+                        }
+                        else
+                        {
+                            // An unicode char could be more than one byte long 
+                            pos += nbChars;
+                        }
+                    }
+                    else
+                    {
+                        return pos;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Parse a NameComponent : <br>
+     * <p>
+     * &lt;name-component&gt;    ::= &lt;attributeType&gt; &lt;spaces&gt; '=' &lt;spaces&gt; &lt;attributeValue&gt; &lt;nameComponents&gt;
+     * </p>
+     * 
+     * @param bytes The buffer to parse
+     * @param pos The current position in the buffer
+     * @return The new position in the char array, or PARSING_ERROR if the rule does not apply to the char array 
+     */
+    public static int parse( char[] chars, int pos, Rdn rdn ) throws InvalidNameException
+    {
+        int newPos = 0;
+        String type = null;
+        String value = null;
+        int start = pos;
+        
+        pos = StringTools.trimLeft( chars, pos );
+        
+        if ( ( newPos = parseAttributeType( chars, pos ) ) == DNUtils.PARSING_ERROR )
+        {
+            return DNUtils.PARSING_ERROR;
+        }
+        
+        if ( rdn != null )
+        {
+            type = new String( chars, pos, newPos - pos );
+        }
+        
+        pos = StringTools.trimLeft( chars, newPos );
+
+        if ( StringTools.isCharASCII( chars, pos, '=' ) == false )
+        {
+            return DNUtils.PARSING_ERROR;
+        }
+        else
+        {
+            pos++;
+        }
+
+        pos = StringTools.trimLeft( chars, pos );
+
+        if ( ( newPos = parseAttributeValue( chars, pos ) ) == DNUtils.PARSING_ERROR )
+        {
+            return DNUtils.PARSING_ERROR;
+        }
+        
+        if ( rdn != null )
+        {
+            newPos = StringTools.trimRight( chars, newPos );
+            value = new String( chars, pos, newPos - pos );
+            
+            rdn.addAttributeTypeAndValue( type, value );
+        }
+
+        int end = parseNameComponents( chars, newPos, rdn );
+        rdn.setUpName( new String( chars, start, end - start ) );
+        rdn.normalizeString();
+        return end;
+    }
+
+    /**
+     * Parse a NameComponent : <br>
+     * <p>
+     * &lt;name-component&gt;    ::= &lt;attributeType&gt; &lt;spaces&gt; '=' &lt;spaces&gt; &lt;attributeValue&gt; &lt;nameComponents&gt;
+     * </p>
+     * 
+     * @param string The buffer to parse
+     * @param rdn The RDN to fill. Beware that if the RDN is not empty, the new AttributeTypeAndValue will be added. 
+     */
+    public static void parse( String string, Rdn rdn ) throws InvalidNameException
+    {
+        parse( string.toCharArray(), 0, rdn );
+        rdn.normalizeString();
+    }
+}

Propchange: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/name/RdnParser.java
------------------------------------------------------------------------------
    svn:executable = *

Added: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/schema/DNNormalizer.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/schema/DNNormalizer.java?rev=367149&view=auto
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/schema/DNNormalizer.java (added)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/schema/DNNormalizer.java Sun Jan  8 17:02:49 2006
@@ -0,0 +1,118 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.ldap.common.schema;
+
+
+import javax.naming.InvalidNameException;
+import javax.naming.Name ;
+import javax.naming.NamingException ;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.ldap.common.name.LdapDnParser;
+import org.apache.ldap.common.name.DnOidContainer;
+
+
+/**
+ * A distinguished name normalizer that works with a schema or without.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 359114 $
+ */
+public class DNNormalizer implements Normalizer
+{
+	private static DnOidContainer oidContainer = DnOidContainer.getInstance();
+	
+	public static void setOidContainer( DnOidContainer oidContainer )
+	{
+		DNNormalizer.oidContainer = oidContainer;
+	}
+	
+    /**
+     * @see org.apache.ldap.common.schema.Normalizer#normalize(java.lang.Object)
+     */
+    public Object normalize( Object value ) throws NamingException
+    {
+    	if ( value instanceof String )
+    	{
+    		return DNNormalizer.normalize( (String)value );
+    	}
+    	else
+    	{
+    		return DNNormalizer.normalize( (Name)value );
+    	}
+    }
+
+    private static Name internalNormalize( Name name ) throws InvalidNameException, NamingException
+	{
+    	// First, check that the mapping table is filled with 
+    	// values, else we can return the name as is.
+    	if ( oidContainer == null )
+    	{
+    		return name;
+    	}
+    	
+        // Loop on every NameComponent
+        if ( name.size() != 0 )
+        {
+        	//name = LdapDN.toOidName( name, DnOidContainer.getOids() );
+        }
+        
+        return name;
+	}
+	
+    /**
+     * Normalizes the value if it is a Name or a String returning the String 
+     * representation always.  If the value is not a String or a Name the object
+     * is returned as is.
+     *
+     * @see org.apache.ldap.common.schema.Normalizer#normalize(java.lang.Object)
+     */
+    public static Object normalize( Name value ) throws NamingException
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+        
+        return internalNormalize( (Name)value );
+    }
+
+    /**
+     * Normalizes the value if it is a Name or a String returning the String 
+     * representation always.  If the value is not a String or a Name the object
+     * is returned as is.
+     *
+     * @see org.apache.ldap.common.schema.Normalizer#normalize(java.lang.Object)
+     */
+    public static Object normalize( String value ) throws NamingException
+    {
+        if ( StringUtils.isEmpty( value ) )
+        {
+            return null;
+        }
+        
+        return internalNormalize( LdapDnParser.getNameParser().parse( value ) );
+    }
+    
+    /**
+     * A String representation of this normalizer
+     */
+    public String toString()
+    {
+    	return "DNNormalizer";
+    }
+}

Added: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/schema/OidNormalizer.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/schema/OidNormalizer.java?rev=367149&view=auto
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/schema/OidNormalizer.java (added)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/schema/OidNormalizer.java Sun Jan  8 17:02:49 2006
@@ -0,0 +1,92 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.ldap.common.schema;
+
+/**
+ * The OidNomalizer class contains a couple : and OID with its Normalizer
+ *  
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class OidNormalizer {
+	/** The oid */
+	private String name;
+	
+	/** The normalizer to be used with this OID */
+	private Normalizer normalizer;
+	
+	/**
+	 * A constructor which accept two parameters
+	 * @param oid The oid
+	 * @param normalizer The associated normalizer
+	 */
+	public OidNormalizer( String name, Normalizer normalizer )
+	{
+		this.name = name;
+		this.normalizer = normalizer;
+	}
+	
+	/**
+	 * A copy constructor. 
+	 * @param oidNormalizer The OidNormalizer to copy from
+	 */
+	public OidNormalizer( OidNormalizer oidNormalizer )
+	{
+		name = oidNormalizer.name;
+		normalizer = oidNormalizer.normalizer;
+	}
+
+	/**
+	 * Get the normalizer
+	 * @return The normalizer associated to the current OID
+	 */
+	public Normalizer getNormalizer() {
+		return normalizer;
+	}
+
+	/**
+	 * Set the normalizer
+	 * @param The normalizer to be associated to the current OID
+	 */
+	public void setNormalizer(Normalizer normalizer) {
+		this.normalizer = normalizer;
+	}
+
+	/**
+	 * Get the current name
+	 * @return The current name
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Set the current OID
+	 * @param The current OID
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	/**
+	 * Return a String representation of this class
+	 */
+	public String toString()
+	{
+		return "OidNormalizer : { " + name + ", " + normalizer.toString() + "}";
+	}
+}

Propchange: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/schema/OidNormalizer.java
------------------------------------------------------------------------------
    svn:executable = *

Added: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/util/DNUtils.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/util/DNUtils.java?rev=367149&view=auto
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/util/DNUtils.java (added)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/util/DNUtils.java Sun Jan  8 17:02:49 2006
@@ -0,0 +1,616 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.ldap.common.util;
+
+/**
+ * Utility class used by the LdapDN Parser.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class DNUtils
+{
+    //~ Static fields/initializers -----------------------------------------------------------------
+
+    /** <safe-init-char>    ::= [0x01-0x09] | 0x0B | 0x0C | [0x0E-0x1F] | [0x21-0x39] | 0x3B | [0x3D-0x7F] */
+    private static final boolean[] SAFE_INIT_CHAR =
+    {
+        false, true, true, true, true, true, true, true, true, true, false, true, true, false,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, false, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, false,
+        true, false, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true
+    };
+
+    /** <safe-char>        ::= [0x01-0x09] | 0x0B | 0x0C | [0x0E-0x7F] */
+    private static final boolean[] SAFE_CHAR =
+    {
+        false, true, true, true, true, true, true, true, true, true, false, true, true, false,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true
+    };
+
+    /** <base64-char>    ::= 0x2B | 0x2F | [0x30-0x39] | 0x3D | [0x41-0x5A] | [0x61-0x7A] */
+    private static final boolean[] BASE64_CHAR =
+    {
+        false, false, false, false, false, false, false, false, false, false, false, false, false,
+        false, false, false, false, false, false, false, false, false, false, false, false, false,
+        false, false, false, false, false, false, false, false, false, false, false, false, false,
+        false, false, false, false, true, false, false, false, true, true, true, true, true, true,
+        true, true, true, true, true, false, false, false, true, false, false, false, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, false, false, false, false, false,
+        false, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, false, false,
+        false, false, false
+    };
+
+    /** '"'  | '#'  | '+'  | ','  | [0-9] | ';'  | '<'  | '='  | '>'  | [A-F] | '\' | [a-f] 
+     * 0x22 | 0x23 | 0x2B | 0x2C | [0x30-0x39] | 0x3B | 0x3C | 0x3D | 0x3E | [0x41-0x46] | 0x5C | [0x61-0x66] */
+    private static final boolean[] PAIR_CHAR =
+    {
+        false, false, false, false, false, false, false, false, false, false, false, false, false,
+        false, false, false, false, false, false, false, false, false, false, false, false, false,
+        false, false, false, false, false, false, false, false, true, true, false, false, false,
+        false, false, false, false, true, true, false, false, false, true, true, true, true, true,
+        true, true, true, true, true, false, true, true, true, true, false, false, true, true,
+        true, true, true, true, false, false, false, false, false, false, false, false, false,
+        false, false, false, false, false, false, false, false, false, false, false, false, true,
+        false, false, false, false, true, true, true, true, true, true, false, false, false, false,
+        false, false, false, false, false, false, false, false, false, false, false, false, false,
+        false, false, false, false, false, false, false, false
+    };
+
+    /** "oid." static */
+    public static final char[] OID_LOWER = new char[] { 'o', 'i', 'd', '.' };
+
+    /** "OID." static */
+    public static final char[] OID_UPPER = new char[] { 'O', 'I', 'D', '.' };
+    
+    /** "oid." static */
+    public static final byte[] OID_LOWER_BYTES = new byte[] { 'o', 'i', 'd', '.' };
+
+    /** "OID." static */
+    public static final byte[] OID_UPPER_BYTES = new byte[] { 'O', 'I', 'D', '.' };
+
+    /** A value if we got an error while parsing */
+    public static final int PARSING_ERROR = -1;
+
+    /** If an hex pair contains only one char, this value is returned */ 
+    public static final int BAD_HEX_PAIR = -2;
+    
+    /** A constant representing one char length */
+    public static final int ONE_CHAR = 1;
+
+    /** A constant representing two chars length */
+    public static final int TWO_CHARS = 2;
+
+    /** A constant representing one byte length */
+    public static final int ONE_BYTE = 1;
+
+    /** A constant representing two bytes length */
+    public static final int TWO_BYTES = 2;
+
+    //~ Methods ------------------------------------------------------------------------------------
+
+    /**
+     * Walk the buffer while characters are Safe String characters :
+     *  <safe-string>    ::= <safe-init-char> <safe-chars>
+     *  <safe-init-char> ::= [0x01-0x09] | 0x0B | 0x0C | [0x0E-0x1F] | [0x21-0x39] | 0x3B | [0x3D-0x7F]
+     *  <safe-chars>     ::= <safe-char> <safe-chars> |
+     *  <safe-char>      ::= [0x01-0x09] | 0x0B | 0x0C | [0x0E-0x7F]
+     *
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return The position of the first character which is not a Safe Char
+     */
+    public static int parseSafeString( byte[] byteArray, int index )
+    {
+        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
+                ( index >= byteArray.length ) )
+        {
+            return -1;
+        }
+        else
+        {
+            byte c = byteArray[index];
+
+            if ( ( c > 127 ) || ( SAFE_INIT_CHAR[c] == false ) )
+            {
+                return -1;
+            }
+
+            index++;
+
+            while ( index < byteArray.length )
+            {
+                c = byteArray[index];
+
+                if ( ( c > 127 ) || ( SAFE_CHAR[c] == false ) )
+                {
+                    break;
+                }
+
+                index++;
+            }
+
+            return index;
+        }
+    }
+
+    /**
+     * Walk the buffer while characters are Alpha characters :
+     *  <alpha>    ::= [0x41-0x5A] | [0x61-0x7A]
+     * 
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return The position of the first character which is not an Alpha Char
+     */
+    public static int parseAlphaASCII( byte[] byteArray, int index )
+    {
+        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
+                ( index >= byteArray.length ) )
+        {
+            return -1;
+        }
+        else
+        {
+            byte c = byteArray[index++];
+
+            if ( ( c > 127 ) || ( StringTools.ALPHA[c] == false ) )
+            {
+                return -1;
+            }
+            else
+            {
+                return index;
+            }
+        }
+    }
+
+    /**
+     * Walk the buffer while characters are Alpha characters :
+     *  <alpha>    ::= [0x41-0x5A] | [0x61-0x7A]
+     * 
+     * @param charArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return The position of the first character which is not an Alpha Char
+     */
+    public static int parseAlphaASCII( char[] charArray, int index )
+    {
+        if ( ( charArray == null ) || ( charArray.length == 0 ) || ( index < 0 ) ||
+                ( index >= charArray.length ) )
+        {
+            return PARSING_ERROR;
+        }
+        else
+        {
+            char c = charArray[index++];
+
+            if ( ( c > 127 ) || ( StringTools.ALPHA[c] == false ) )
+            {
+                return PARSING_ERROR;
+            }
+            else
+            {
+                return index;
+            }
+        }
+    }
+
+    /**
+     * Check if the current character is a Pair Char
+     *  <pairchar>    ::= ',' | '=' | '+' | '<' | '>' | '#' | ';' | '\' | '"' | [0-9a-fA-F] [0-9a-fA-F]
+     *  
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return <code>true</code> if the current character is a Pair Char
+     */
+    public static boolean isPairChar( byte[] byteArray, int index )
+    {
+        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
+                ( index >= byteArray.length ) )
+        {
+            return false;
+        }
+        else
+        {
+            byte c = byteArray[index];
+
+            if ( ( c > 127 ) || ( PAIR_CHAR[c] == false ) )
+            {
+                return false;
+            }
+            else
+            {
+                if ( StringTools.isHex( byteArray, index++ ) )
+                {
+                    return StringTools.isHex( byteArray, index );
+                }
+                else
+                {
+                    return true;
+                }
+            }
+        }
+    }
+
+    /**
+     * Check if the current character is a Pair Char
+     *  <pairchar>    ::= ',' | '=' | '+' | '<' | '>' | '#' | ';' | '\' | '"' | [0-9a-fA-F] [0-9a-fA-F]
+     *  
+     * @param charArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return <code>true</code> if the current character is a Pair Char
+     */
+    public static boolean isPairChar( char[] charArray, int index )
+    {
+        if ( ( charArray == null ) || ( charArray.length == 0 ) || ( index < 0 ) ||
+                ( index >= charArray.length ) )
+        {
+            return false;
+        }
+        else
+        {
+            char c = charArray[index];
+
+            if ( ( c > 127 ) || ( PAIR_CHAR[c] == false ) )
+            {
+                return false;
+            }
+            else
+            {
+                if ( StringTools.isHex( charArray, index++ ) )
+                {
+                    return StringTools.isHex( charArray, index );
+                }
+                else
+                {
+                    return true;
+                }
+            }
+        }
+    }
+
+    /**
+     * Check if the current character is a String Char.
+     * Chars are Unicode, not ASCII.
+     *  <stringchar>    ::= [0x00-0xFFFF] - [,=+<>#;\"\n\r]
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return The current char if it is a String Char, or '#' (this is
+     * simpler than throwing an exception :)
+     */
+    public static int isStringChar( byte[] byteArray, int index )
+    {
+        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
+                ( index >= byteArray.length ) )
+        {
+            return -1;
+        }
+        else
+        {
+            byte c = byteArray[index];
+
+            if ( ( c == 0x0A ) ||
+                    ( c == 0x0D ) ||
+                    ( c == '"' ) ||
+                    ( c == '#' ) ||
+                    ( c == '+' ) ||
+                    ( c == ',' ) ||
+                    ( c == ';' ) ||
+                    ( c == '<' ) ||
+                    ( c == '=' ) ||
+                    ( c == '>' ) )
+            {
+                return -1;
+            }
+            else
+            {
+                return StringTools.countBytesPerChar(byteArray, index);
+            }
+        }
+    }
+
+    /**
+     * Check if the current character is a String Char.
+     * Chars are Unicode, not ASCII.
+     *  <stringchar>    ::= [0x00-0xFFFF] - [,=+<>#;\"\n\r]
+     * @param charArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return The current char if it is a String Char, or '#' (this is
+     * simpler than throwing an exception :)
+     */
+    public static int isStringChar( char[] charArray, int index )
+    {
+        if ( ( charArray == null ) || ( charArray.length == 0 ) || ( index < 0 ) ||
+                ( index >= charArray.length ) )
+        {
+            return PARSING_ERROR;
+        }
+        else
+        {
+            char c = charArray[index];
+
+            if ( ( c == 0x0A ) ||
+                    ( c == 0x0D ) ||
+                    ( c == '"' ) ||
+                    ( c == '#' ) ||
+                    ( c == '+' ) ||
+                    ( c == ',' ) ||
+                    ( c == ';' ) ||
+                    ( c == '<' ) ||
+                    ( c == '=' ) ||
+                    ( c == '>' ) )
+            {
+                return PARSING_ERROR;
+            }
+            else
+            {
+                return ONE_CHAR;
+            }
+        }
+    }
+
+    /**
+     * Check if the current character is a Quote Char
+     * We are testing Unicode chars
+     *  <quotechar>    ::= [0x00-0xFFFF] - [\"]
+     * 
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return <code>true</code> if the current character is a Quote Char
+     */
+    public static int isQuoteChar( byte[] byteArray, int index )
+    {
+        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
+                ( index >= byteArray.length ) )
+        {
+            return -1;
+        }
+        else
+        {
+            byte c = byteArray[index];
+
+            if ( ( c == '\\' ) || ( c == '"' ) )
+            {
+                return -1;
+            }
+            else
+            {
+                return StringTools.countBytesPerChar(byteArray, index);
+            }
+        }
+    }
+
+    /**
+     * Check if the current character is a Quote Char
+     * We are testing Unicode chars
+     *  <quotechar>    ::= [0x00-0xFFFF] - [\"]
+     * 
+     * @param charArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return <code>true</code> if the current character is a Quote Char
+     */
+    public static int isQuoteChar( char[] charArray, int index )
+    {
+        if ( ( charArray == null ) || ( charArray.length == 0 ) || ( index < 0 ) ||
+                ( index >= charArray.length ) )
+        {
+            return PARSING_ERROR;
+        }
+        else
+        {
+            char c = charArray[index];
+
+            if ( ( c == '\\' ) || ( c == '"' ) )
+            {
+                return PARSING_ERROR;
+            }
+            else
+            {
+                return ONE_CHAR;
+            }
+        }
+    }
+
+    /**
+     * Parse an hex pair
+     *   <hexpair>    ::= <hex> <hex>
+     *
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return The new position, -1 if the buffer does not contain an HexPair, -2 if the
+     * buffer contains an hex byte but not two.
+     */
+    public static int parseHexPair( byte[] byteArray, int index )
+    {
+        if ( StringTools.isHex( byteArray, index ) )
+        {
+            if ( StringTools.isHex( byteArray, index + 1 ) )
+            {
+                return index + 2;
+            }
+            else
+            {
+                return -2;
+            }
+        }
+        else
+        {
+            return -1;
+        }
+    }
+
+    /**
+     * Parse an hex pair
+     *   <hexpair>    ::= <hex> <hex>
+     *
+     * @param charArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return The new position, -1 if the buffer does not contain an HexPair, -2 if the
+     * buffer contains an hex byte but not two.
+     */
+    public static int parseHexPair( char[] charArray, int index )
+    {
+        if ( StringTools.isHex( charArray, index ) )
+        {
+            if ( StringTools.isHex( charArray, index + 1 ) )
+            {
+                return index + TWO_CHARS;
+            }
+            else
+            {
+                return BAD_HEX_PAIR;
+            }
+        }
+        else
+        {
+            return PARSING_ERROR;
+        }
+    }
+
+    /**
+     * Parse an hex string, which is a list of hex pairs
+     *  <hexstring>    ::= <hexpair> <hexpairs>
+     *  <hexpairs>    ::= <hexpair> <hexpairs> | e
+     *
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return Return the first position which is not an hex pair, or -1 if there is no
+     * hexpair at the beginning or if an hexpair is invalid (if we have only one hex instead of 2)
+     */
+    public static int parseHexString( byte[] byteArray, int index )
+    {
+        int result = parseHexPair( byteArray, index );
+
+        if ( result < 0 )
+        {
+            return -1;
+        }
+        else
+        {
+            index += 2;
+        }
+
+        while ( ( result = parseHexPair( byteArray, index ) ) >= 0 )
+        {
+            index += 2;
+        }
+
+        return ( ( result == -2 ) ? -1 : index );
+    }
+
+    /**
+     * Parse an hex string, which is a list of hex pairs
+     *  <hexstring>    ::= <hexpair> <hexpairs>
+     *  <hexpairs>    ::= <hexpair> <hexpairs> | e
+     *
+     * @param charArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return Return the first position which is not an hex pair, or -1 if there is no
+     * hexpair at the beginning or if an hexpair is invalid (if we have only one hex instead of 2)
+     */
+    public static int parseHexString( char[] charArray, int index )
+    {
+        int result = parseHexPair( charArray, index );
+
+        if ( result < 0 )
+        {
+            return PARSING_ERROR;
+        }
+        else
+        {
+            index += TWO_CHARS;
+        }
+
+        while ( ( result = parseHexPair( charArray, index ) ) >= 0 )
+        {
+            index += TWO_CHARS;
+        }
+
+        return ( ( result == BAD_HEX_PAIR ) ? PARSING_ERROR : index );
+    }
+
+    /**
+     * Walk the buffer while characters are Base64 characters : 
+     *     <base64-string>      ::= <base64-char> <base64-chars>
+     *  <base64-chars>       ::= <base64-char> <base64-chars> |
+     *  <base64-char>        ::= 0x2B | 0x2F | [0x30-0x39] | 0x3D | [0x41-0x5A] | [0x61-0x7A]
+     *
+     * @param byteArray The buffer which contains the data
+     * @param index Current position in the buffer
+     *
+     * @return The position of the first character which is not a Base64 Char
+     */
+    public static int parseBase64String( byte[] byteArray, int index )
+    {
+        if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) ||
+                ( index >= byteArray.length ) )
+        {
+            return -1;
+        }
+        else
+        {
+            byte c = byteArray[index];
+
+            if ( ( c > 127 ) || ( BASE64_CHAR[c] == false ) )
+            {
+                return -1;
+            }
+
+            index++;
+
+            while ( index < byteArray.length )
+            {
+                c = byteArray[index];
+
+                if ( ( c > 127 ) || ( BASE64_CHAR[c] == false ) )
+                {
+                    break;
+                }
+
+                index++;
+            }
+
+            return index;
+        }
+    }
+
+}

Propchange: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/util/DNUtils.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/codec/search/SearchRequestTest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/codec/search/SearchRequestTest.java?rev=367149&r1=367148&r2=367149&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/codec/search/SearchRequestTest.java (original)
+++ directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/codec/search/SearchRequestTest.java Sun Jan  8 17:02:49 2006
@@ -18,6 +18,8 @@
 
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.naming.directory.Attributes;
 
@@ -25,6 +27,9 @@
 import org.apache.asn1.codec.EncoderException;
 import org.apache.asn1.ber.Asn1Decoder;
 import org.apache.asn1.ber.IAsn1Container;
+import org.apache.ldap.common.name.DnOidContainer;
+import org.apache.ldap.common.schema.DeepTrimToLowerNormalizer;
+import org.apache.ldap.common.schema.OidNormalizer;
 import org.apache.ldap.common.util.StringTools;
 import org.apache.ldap.common.codec.AttributeValueAssertion;
 import org.apache.ldap.common.codec.Control;
@@ -50,6 +55,23 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class SearchRequestTest extends TestCase {
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        
+        Map oids = new HashMap(); 
+        oids.put( "dc", new OidNormalizer( "dc", new  DeepTrimToLowerNormalizer() ) );
+        oids.put( "domaincomponent", new OidNormalizer( "dc", new  DeepTrimToLowerNormalizer() ) );
+        oids.put( "0.9.2342.19200300.100.1.25", new OidNormalizer( "dc", new  DeepTrimToLowerNormalizer() ) );
+        oids.put( "ou", new OidNormalizer( "ou", new  DeepTrimToLowerNormalizer() ) );
+        oids.put( "organizationalUnitName", new OidNormalizer( "ou", new  DeepTrimToLowerNormalizer() ) );
+        oids.put( "2.5.4.11", new OidNormalizer( "ou", new  DeepTrimToLowerNormalizer() ) );
+        oids.put( "objectclass", new OidNormalizer( "objectclass", new  DeepTrimToLowerNormalizer() ) );
+        oids.put( "2.5.4.0", new OidNormalizer( "objectclass", new  DeepTrimToLowerNormalizer() ) );
+		
+        DnOidContainer.setOids( oids );
+	}
+	
     /**
      * Test the decoding of a SearchRequest with no controls.
      * The search filter is : 
@@ -1873,4 +1895,152 @@
            Assert.fail( ee.getMessage() );
        }
     }    
+
+    /**
+     * Test the decoding of a SearchRequest with no controls but with
+     * oid attributes.
+     * The search filter is : 
+     * (&(|(objectclass=top)(2.5.4.11=contacts))(!(organizationalUnitName=ttt)))
+     */
+    public void testDecodeSearchRequestGlobalNoControlsOidAndAlias()
+    {
+        Asn1Decoder ldapDecoder = new LdapDecoder();
+
+        ByteBuffer  stream      = ByteBuffer.allocate( 0xA1 );
+        stream.put(
+            new byte[]
+            {
+                0x30, (byte)0x81, (byte)0x9E, // LDAPMessage ::=SEQUENCE {
+				0x02, 0x01, 0x01, 	          //        messageID MessageID
+				0x63, (byte)0x81, (byte)0x98,                   //	      CHOICE { ..., searchRequest SearchRequest, ...
+                        			     	  // SearchRequest ::= APPLICATION[3] SEQUENCE {
+				0x04, 0x1F, 		     	  //    baseObject LDAPDN,
+				'u', 'i', 'd', '=', 'a', 'k', 'a', 'r', 'a', 's', 'u', 'l', 'u', ',', 'd', 'c', '=',
+                'e', 'x', 'a', 'm', 'p', 'l', 'e', ',', 'd', 'c', '=', 'c', 'o', 'm',
+				0x0A, 0x01, 0x01,        	  //    scope           ENUMERATED {
+                					     	  //        baseObject              (0),
+				                         	  //        singleLevel             (1),
+				                         	  //        wholeSubtree            (2) },
+				0x0A, 0x01, 0x03,        	  //    derefAliases    ENUMERATED {
+									     	  //        neverDerefAliases       (0),
+									     	  //        derefInSearching        (1),
+									     	  //        derefFindingBaseObj     (2),
+									     	  //        derefAlways             (3) },
+				                         	  //    sizeLimit INTEGER (0 .. maxInt), (1000)
+				0x02, 0x02, 0x03, (byte)0xE8,
+                					     	  //    timeLimit INTEGER (0 .. maxInt), (1000)
+				0x02, 0x02, 0x03, (byte)0xE8,
+				0x01, 0x01, (byte)0xFF,   	  //    typesOnly BOOLEAN, (TRUE)
+				                         	  //    filter    Filter,
+				(byte)0xA0, 0x4D,        	  // Filter ::= CHOICE {
+				                         	  //    and             [0] SET OF Filter,
+				(byte)0xA1, 0x2A,        	  //    or              [1] SET of Filter,
+				(byte)0xA3, 0x12,        	  //    equalityMatch   [3] AttributeValueAssertion,
+									     	  // AttributeValueAssertion ::= SEQUENCE {
+								 	          //    attributeDesc   AttributeDescription (LDAPString),
+				0x04, 0x0B, 'o', 'b', 'j', 'e', 'c', 't', 'c', 'l', 'a', 's', 's',
+									          //    assertionValue  AssertionValue (OCTET STRING) }
+				0x04, 0x03, 't', 'o', 'p',
+				(byte)0xA3, 0x14,             //    equalityMatch   [3] AttributeValueAssertion,
+				                              // AttributeValueAssertion ::= SEQUENCE {
+				0x04, 0x08, '2', '.', '5', '.', '4', '.', '1', '1',         //    attributeDesc   AttributeDescription (LDAPString),
+			                                  //    assertionValue  AssertionValue (OCTET STRING) }
+				0x04, 0x08, 'c', 'o', 'n', 't', 'a', 'c', 't', 's',
+				(byte)0xA2, 0x1F,             //    not             [2] Filter,
+				(byte)0xA3, 0x1D,             //    equalityMatch   [3] AttributeValueAssertion,
+			                                  // AttributeValueAssertion ::= SEQUENCE {
+		 	                                  //    attributeDesc   AttributeDescription (LDAPString),
+                0x04, 0x16, 'o', 'r', 'g', 'a', 'n', 'i', 'z', 'a', 't', 'i', 'o', 'n', 'a', 'l', 'U', 'n', 'i', 't', 'N', 'a', 'm', 'e',
+			                                  //    assertionValue  AssertionValue (OCTET STRING) }
+                0x04, 0x03, 't', 't', 't',
+              						          //    attributes      AttributeDescriptionList }
+                0x30, 0x15,				      // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
+                0x04, 0x05, 'a', 't', 't', 'r', '0', // AttributeDescription ::= LDAPString
+                0x04, 0x05, 'a', 't', 't', 'r', '1', // AttributeDescription ::= LDAPString
+                0x04, 0x05, 'a', 't', 't', 'r', '2'  // AttributeDescription ::= LDAPString
+            } );
+
+        stream.flip();
+
+        // Allocate a BindRequest Container
+        IAsn1Container ldapMessageContainer = new LdapMessageContainer();
+
+        try
+        {
+            ldapDecoder.decode( stream, ldapMessageContainer );
+        }
+        catch ( DecoderException de )
+        {
+            de.printStackTrace();
+            Assert.fail( de.getMessage() );
+        }
+    	
+        LdapMessage message = ( ( LdapMessageContainer ) ldapMessageContainer ).getLdapMessage();
+        SearchRequest sr      = message.getSearchRequest();
+
+        Assert.assertEquals( 1, message.getMessageId() );
+        Assert.assertEquals( "uid=akarasulu,dc=example,dc=com", sr.getBaseObject().toString() );
+        Assert.assertEquals( LdapConstants.SCOPE_SINGLE_LEVEL, sr.getScope() );
+        Assert.assertEquals( LdapConstants.DEREF_ALWAYS, sr.getDerefAliases() );
+        Assert.assertEquals( 1000, sr.getSizeLimit() );
+        Assert.assertEquals( 1000, sr.getTimeLimit() );
+        Assert.assertEquals( true, sr.isTypesOnly() );
+        
+        // (& (...
+        AndFilter andFilter = (AndFilter)sr.getFilter();
+        Assert.assertNotNull(andFilter);
+        
+        ArrayList andFilters = andFilter.getAndFilter();
+        
+        // (& (| (...
+        Assert.assertEquals(2, andFilters.size());
+        OrFilter orFilter = (OrFilter)andFilters.get(0);
+        Assert.assertNotNull(orFilter);
+        
+        // (& (| (obectclass=top) (...
+        ArrayList orFilters = orFilter.getOrFilter();
+        Assert.assertEquals(2, orFilters.size());
+        AttributeValueAssertionFilter equalityMatch = (AttributeValueAssertionFilter)orFilters.get(0);  
+        Assert.assertNotNull(equalityMatch);
+        
+        AttributeValueAssertion assertion = equalityMatch.getAssertion();
+        Assert.assertNotNull(assertion);
+        
+        Assert.assertEquals("objectclass", assertion.getAttributeDesc().toString());
+        Assert.assertEquals("top", assertion.getAssertionValue().toString());
+        
+        // (& (| (objectclass=top) (ou=contacts) ) (...
+        equalityMatch = (AttributeValueAssertionFilter)orFilters.get(1);  
+        Assert.assertNotNull(equalityMatch);
+        
+        assertion = equalityMatch.getAssertion();
+        Assert.assertNotNull(assertion);
+        
+        Assert.assertEquals("ou", assertion.getAttributeDesc().toString());
+        Assert.assertEquals("contacts", assertion.getAssertionValue().toString());
+        
+        // (& (| (objectclass=top) (ou=contacts) ) (! ...
+        NotFilter notFilter = ( NotFilter )andFilters.get(1);
+        Assert.assertNotNull(notFilter);
+        
+        // (& (| (objectclass=top) (ou=contacts) ) (! (objectclass=ttt) ) )
+        equalityMatch = (AttributeValueAssertionFilter)notFilter.getNotFilter();  
+        Assert.assertNotNull(equalityMatch);
+        
+        assertion = equalityMatch.getAssertion();
+        Assert.assertNotNull(assertion);
+        
+        Assert.assertEquals("ou", assertion.getAttributeDesc().toString());
+        Assert.assertEquals("ttt", assertion.getAssertionValue().toString());
+        
+        Attributes attributes = sr.getAttributes();
+        
+        for (int i = 0; i < attributes.size(); i++) 
+        {
+        	Assert.assertNotNull( attributes.get( "attr" + i ) );
+        }
+
+        // We won't check the encoding, as it has changed because of 
+        // attributes transformations
+    }
 }

Added: directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/name/AttributeTypeAndValueTest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/name/AttributeTypeAndValueTest.java?rev=367149&view=auto
==============================================================================
--- directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/name/AttributeTypeAndValueTest.java (added)
+++ directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/name/AttributeTypeAndValueTest.java Sun Jan  8 17:02:49 2006
@@ -0,0 +1,145 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.ldap.common.name;
+
+import javax.naming.InvalidNameException;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+/**
+ * Test the class AttributeTypeAndValue
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class AttributeTypeAndValueTest extends TestCase
+{
+    //~ Methods ------------------------------------------------------------------------------------
+
+    /**
+     * Setup the test
+     */
+    protected void setUp()
+    {
+    }
+
+    /**
+     * Test a null AttributeTypeAndValue
+     */
+    public void testAttributeTypeAndValueNull() throws InvalidNameException
+    {
+        Assert.assertEquals( "", new AttributeTypeAndValue().toString() );
+    }
+
+    /**
+     * test an empty AttributeTypeAndValue
+     */
+    public void testLdapRDNEmpty() throws InvalidNameException
+    {
+    	try
+    	{
+    		new AttributeTypeAndValue( "", "" );
+    		Assert.fail( "Should not occurs ... " );
+    	}
+    	catch ( InvalidNameException ine )
+    	{
+    		Assert.assertTrue( true );
+    	}
+    }
+
+    /**
+     * test a simple AttributeTypeAndValue : a = b
+     */
+    public void testLdapRDNSimple() throws InvalidNameException
+    {
+        Assert.assertEquals( "a=b", new AttributeTypeAndValue( "a", "b" ).toString() );
+    }
+
+    /**
+     * Compares two equals atavs
+     */
+    public void testCompareToEquals() throws InvalidNameException
+    {
+    	AttributeTypeAndValue atav1 = new AttributeTypeAndValue( "a", "b" );
+    	AttributeTypeAndValue atav2 = new AttributeTypeAndValue( "a", "b" );
+    	
+        Assert.assertEquals( 0, atav1.compareTo( atav2) );
+    }
+
+    /**
+     * Compares two equals atavs but with a type in different case 
+     */
+    public void testCompareToEqualsCase() throws InvalidNameException
+    {
+    	AttributeTypeAndValue atav1 = new AttributeTypeAndValue( "a", "b" );
+    	AttributeTypeAndValue atav2 = new AttributeTypeAndValue( "A", "b" );
+    	
+        Assert.assertEquals( 0, atav1.compareTo( atav2) );
+    }
+
+    /**
+     * Compare two atavs : the first one is superior because its type is superior
+     */
+    public void testCompareAtav1TypeSuperior() throws InvalidNameException
+    {
+    	AttributeTypeAndValue atav1 = new AttributeTypeAndValue( "b", "b" );
+    	AttributeTypeAndValue atav2 = new AttributeTypeAndValue( "a", "b" );
+    	
+        Assert.assertEquals( 1, atav1.compareTo( atav2) );
+    }
+
+    /**
+     * Compare two atavs : the second one is superior because its type is superior
+     */
+    public void testCompareAtav2TypeSuperior() throws InvalidNameException
+    {
+    	AttributeTypeAndValue atav1 = new AttributeTypeAndValue( "a", "b" );
+    	AttributeTypeAndValue atav2 = new AttributeTypeAndValue( "b", "b" );
+    	
+        Assert.assertEquals( -1, atav1.compareTo( atav2) );
+    }
+
+    /**
+     * Compare two atavs : the first one is superior because its type is superior
+     */
+    public void testCompareAtav1ValueSuperior() throws InvalidNameException
+    {
+    	AttributeTypeAndValue atav1 = new AttributeTypeAndValue( "a", "b" );
+    	AttributeTypeAndValue atav2 = new AttributeTypeAndValue( "a", "a" );
+    	
+        Assert.assertEquals( 1, atav1.compareTo( atav2) );
+    }
+
+    /**
+     * Compare two atavs : the second one is superior because its type is superior
+     */
+    public void testCompareAtav2ValueSuperior() throws InvalidNameException
+    {
+    	AttributeTypeAndValue atav1 = new AttributeTypeAndValue( "a", "a" );
+    	AttributeTypeAndValue atav2 = new AttributeTypeAndValue( "a", "b" );
+    	
+        Assert.assertEquals( -1, atav1.compareTo( atav2) );
+    }
+
+    public void testNormalize() throws InvalidNameException
+    {
+    	AttributeTypeAndValue atav = new AttributeTypeAndValue( " A ", "a" );
+    	
+    	Assert.assertEquals( "a=a", atav.normalize() );
+    }
+}
+

Propchange: directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/name/AttributeTypeAndValueTest.java
------------------------------------------------------------------------------
    svn:executable = *

Copied: directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/name/DNParserTest.java (from r366272, directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/codec/util/DNParserTest.java)
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/name/DNParserTest.java?p2=directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/name/DNParserTest.java&p1=directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/codec/util/DNParserTest.java&r1=366272&r2=367149&rev=367149&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/codec/util/DNParserTest.java (original)
+++ directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/name/DNParserTest.java Sun Jan  8 17:02:49 2006
@@ -14,16 +14,17 @@
  *   limitations under the License.
  *
  */
-package org.apache.ldap.common.codec.util;
+package org.apache.ldap.common.name;
 
-import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingException;
 
 import junit.framework.Assert;
 import junit.framework.TestCase;
 
-import org.apache.ldap.common.codec.util.DNParser;
-import org.apache.ldap.common.codec.util.LdapDN;
-
+import org.apache.ldap.common.name.LdapDN;
+import org.apache.ldap.common.util.StringTools;
 
 /**
  * Test the class LdapDN
@@ -42,34 +43,34 @@
     }
 
     // CONSTRUCTOR functions --------------------------------------------------
-
+    
     /**
      * test an empty DN
      */
-    public void testLdapDNEmpty() throws InvalidNameException
+    public void testLdapDNEmpty() throws NamingException
     {
-        DNParser dnParser = new DNParser();
-
+    	NameParser dnParser = LdapDnParser.getNameParser();
+    	
         Assert.assertEquals( "", (( LdapDN )dnParser.parse( "" )).getName() );
     }
 
     /**
      * test a simple DN : a = b
      */
-    public void testLdapDNSimple() throws InvalidNameException
+    public void testLdapDNSimple() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
 
-        Assert.assertEquals( "a = b", (( LdapDN )dnParser.parse( "a = b" )).getName() );
-        Assert.assertEquals( "a=b", (( LdapDN )dnParser.parse( "a = b" )).getString() );
+    	Assert.assertEquals( "a = b", (( LdapDN )dnParser.parse( "a = b" )).getName() );
+        Assert.assertEquals( "a=b", (( LdapDN )dnParser.parse( "a = b" )).toString() );
     }
 
     /**
      * test a composite DN : a = b, d = e
      */
-    public void testLdapDNComposite() throws InvalidNameException
+    public void testLdapDNComposite() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "a = b, c = d" );
         Assert.assertEquals( "a=b,c=d", dn.toString() );
         Assert.assertEquals( "a = b, c = d", dn.getName() );
@@ -78,9 +79,9 @@
     /**
      * test a composite DN with or without spaces: a=b, a =b, a= b, a = b, a  =  b
      */
-    public void testLdapDNCompositeWithSpace() throws InvalidNameException
+    public void testLdapDNCompositeWithSpace() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "a=b, a =b, a= b, a = b, a  =  b" );
         Assert.assertEquals( "a=b,a=b,a=b,a=b,a=b", dn.toString() );
         Assert.assertEquals( "a=b, a =b, a= b, a = b, a  =  b", dn.getName() );
@@ -90,10 +91,10 @@
      * test a composite DN with differents separators : a=b;c=d,e=f
      * It should return a=b,c=d,e=f (the ';' is replaced by a ',')
      */
-    public void testLdapDNCompositeSepators() throws InvalidNameException
+    public void testLdapDNCompositeSepators() throws NamingException
     {
-        DNParser dnParser = new DNParser();
-        LdapDN dn = ( LdapDN )dnParser.parse( "a=b;c=d,e=f" );
+    	NameParser dnParser = LdapDnParser.getNameParser();
+    	LdapDN dn = ( LdapDN )dnParser.parse( "a=b;c=d,e=f" );
         Assert.assertEquals( "a=b,c=d,e=f", dn.toString() );
         Assert.assertEquals( "a=b;c=d,e=f", dn.getName() );
     }
@@ -101,9 +102,9 @@
     /**
      * test a simple DN with multiple NameComponents : a = b + c = d
      */
-    public void testLdapDNSimpleMultivaluedAttribute() throws InvalidNameException
+    public void testLdapDNSimpleMultivaluedAttribute() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "a = b + c = d" );
         Assert.assertEquals( "a=b+c=d", dn.toString() );
         Assert.assertEquals( "a = b + c = d", dn.getName() );
@@ -112,9 +113,9 @@
     /**
      * test a composite DN with multiple NC and separators : a=b+c=d, e=f + g=h + i=j
      */
-    public void testLdapDNCompositeMultivaluedAttribute() throws InvalidNameException
+    public void testLdapDNCompositeMultivaluedAttribute() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "a=b+c=d, e=f + g=h + i=j" );
         Assert.assertEquals( "a=b+c=d,e=f+g=h+i=j", dn.toString() );
         Assert.assertEquals( "a=b+c=d, e=f + g=h + i=j", dn.getName() );
@@ -123,9 +124,9 @@
     /**
      * test a simple DN with an oid prefix (uppercase) : OID.12.34.56 = azerty
      */
-    public void testLdapDNOidUpper() throws InvalidNameException
+    public void testLdapDNOidUpper() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "OID.12.34.56 = azerty" );
         Assert.assertEquals( "oid.12.34.56=azerty", dn.toString() );
         Assert.assertEquals( "OID.12.34.56 = azerty", dn.getName() );
@@ -134,9 +135,9 @@
     /**
      * test a simple DN with an oid prefix (lowercase) : oid.12.34.56 = azerty
      */
-    public void testLdapDNOidLower() throws InvalidNameException
+    public void testLdapDNOidLower() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "oid.12.34.56 = azerty" );
         Assert.assertEquals( "oid.12.34.56=azerty", dn.toString() );
         Assert.assertEquals( "oid.12.34.56 = azerty", dn.getName() );
@@ -145,9 +146,9 @@
     /**
      * test a simple DN with an oid attribut without oid prefix : 12.34.56 = azerty
      */
-    public void testLdapDNOidWithoutPrefix() throws InvalidNameException
+    public void testLdapDNOidWithoutPrefix() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "12.34.56 = azerty" );
         Assert.assertEquals( "12.34.56=azerty", dn.toString() );
         Assert.assertEquals( "12.34.56 = azerty", dn.getName() );
@@ -156,9 +157,9 @@
     /**
      * test a composite DN with an oid attribut wiithout oid prefix : 12.34.56 = azerty; 7.8 = test
      */
-    public void testLdapDNCompositeOidWithoutPrefix() throws InvalidNameException
+    public void testLdapDNCompositeOidWithoutPrefix() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "12.34.56 = azerty; 7.8 = test" );
         Assert.assertEquals( "12.34.56=azerty,7.8=test", dn.toString() );
         Assert.assertEquals( "12.34.56 = azerty; 7.8 = test", dn.getName() );
@@ -167,9 +168,9 @@
     /**
      * test a simple DN with pair char attribute value : a = \,\=\+\<\>\#\;\\\"\A0\00"
      */
-    public void testLdapDNPairCharAttributeValue() throws InvalidNameException
+    public void testLdapDNPairCharAttributeValue() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "a = \\,\\=\\+\\<\\>\\#\\;\\\\\\\"\\A0\\00" );
         Assert.assertEquals( "a=\\,\\=\\+\\<\\>\\#\\;\\\\\\\"\\A0\\00", dn.toString() );
         Assert.assertEquals( "a = \\,\\=\\+\\<\\>\\#\\;\\\\\\\"\\A0\\00", dn.getName() );
@@ -178,9 +179,9 @@
     /**
      * test a simple DN with hexString attribute value : a = #0010A0AAFF
      */
-    public void testLdapDNHexStringAttributeValue() throws InvalidNameException
+    public void testLdapDNHexStringAttributeValue() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "a = #0010A0AAFF" );
         Assert.assertEquals( "a=#0010A0AAFF", dn.toString() );
         Assert.assertEquals( "a = #0010A0AAFF", dn.getName() );
@@ -189,9 +190,9 @@
     /**
      * test a simple DN with quoted attribute value : a = "quoted \"value"
      */
-    public void testLdapDNQuotedAttributeValue() throws InvalidNameException
+    public void testLdapDNQuotedAttributeValue() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "a = quoted \\\"value" );
         Assert.assertEquals( "a=quoted \\\"value", dn.toString() );
         Assert.assertEquals( "a = quoted \\\"value", dn.getName() );
@@ -201,32 +202,279 @@
      * Test the encoding of a LdanDN
      *
      */
-    public void testNameToBytes() throws Exception
+    public void testNameToBytes() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN dn = ( LdapDN )dnParser.parse( "cn = John, ou = People, OU = Marketing" );
-
-        byte[] bytes = dn.getBytes();
-
-        Assert.assertEquals( 30, dn.getNbBytes() );
-        Assert.assertEquals("cn=John,ou=People,ou=Marketing", new String( bytes, "UTF-8" ) );
+        
+        byte[] bytes = LdapDN.getBytes( dn );
+        
+        Assert.assertEquals( 30, bytes.length );
+        Assert.assertEquals("cn=John,ou=People,ou=Marketing", StringTools.utf8ToString( bytes ) );
     }
-
-    public void testStringParser() throws Exception
+    
+    public void testStringParser() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN name = ( LdapDN )dnParser.parse( "CN = Emmanuel  Lécharny" );
-
+        
         Assert.assertEquals( "CN = Emmanuel  Lécharny", name.getName() );
         Assert.assertEquals( "cn=Emmanuel  Lécharny", name.toString() );
     }
 
-    public void testVsldapExtras() throws Exception
+    public void testVsldapExtras() throws NamingException
     {
-        DNParser dnParser = new DNParser();
+    	NameParser dnParser = LdapDnParser.getNameParser();
         LdapDN name = ( LdapDN )dnParser.parse( "cn=Billy Bakers, OID.2.5.4.11=Corporate Tax, ou=Fin-Accounting, ou=Americas, ou=Search, o=IMC, c=US" );
-
+        
         Assert.assertEquals( "cn=Billy Bakers, OID.2.5.4.11=Corporate Tax, ou=Fin-Accounting, ou=Americas, ou=Search, o=IMC, c=US", name.getName() );
         Assert.assertEquals( "cn=Billy Bakers,oid.2.5.4.11=Corporate Tax,ou=Fin-Accounting,ou=Americas,ou=Search,o=IMC,c=US", name.toString() );
+    }
+    
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * Class under test for void DnParser()
+     *
+     * @throws NamingException if anything goes wrong
+     */
+    public final void testDnParser() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+
+        assertNotNull( parser );
+    }
+
+
+    /**
+     * Class under test for Name parse(String)
+     *
+     * @throws NamingException if anything goes wrong
+     */
+    public final void testParseStringEmpty() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+
+        Name nameEmpty = parser.parse( "" );
+
+        assertNotNull( nameEmpty );
+    }
+
+
+    /**
+     * Class under test for Name parse(String)
+     *
+     * @throws NamingException if anything goes wrong
+     */
+    public final void testParseStringNull() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+
+        Name nameNull = parser.parse( null );
+
+        assertEquals( "Null DN are legal : ", "", nameNull.toString() );
+    }
+
+
+    /**
+     * Class under test for Name parse(String)
+     *
+     * @throws NamingException if anything goes wrong
+     */
+    public final void testParseStringRFC1779_1() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+
+        Name nameRFC1779_1 = parser.parse( "CN=Marshall T. Rose, O=Dover Beach Consulting, L=Santa Clara, ST=California, C=US" );
+
+        assertEquals( "RFC1779_1 : ", "CN=Marshall T. Rose, O=Dover Beach Consulting, L=Santa Clara, ST=California, C=US", ((LdapDN)nameRFC1779_1).toUpName() );
+        assertEquals( "RFC1779_1 : ", "cn=Marshall T. Rose,o=Dover Beach Consulting,l=Santa Clara,st=California,c=US", nameRFC1779_1.toString() );
+    }
+
+    /**
+     * Class under test for Name parse(String)
+     *
+     * @throws NamingException if anything goes wrong
+     */
+    public final void testParseStringRFC2253_1() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+
+        Name nameRFC2253_1 = parser.parse( "CN=Steve Kille,O=Isode limited,C=GB" );
+
+        assertEquals( "RFC2253_1 : ",
+                "CN=Steve Kille,O=Isode limited,C=GB",
+                ((LdapDN)nameRFC2253_1).toUpName() );
+    }
+
+
+    /**
+     * Class under test for Name parse(String)
+     *
+     * @throws NamingException if anything goes wrong
+     */
+    public final void testParseStringRFC2253_2() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+
+        Name nameRFC2253_2 = parser.parse( "CN = Sales + CN =   J. Smith , O = Widget Inc. , C = US" );
+
+        assertEquals( "RFC2253_2 : ",
+                "CN = Sales + CN =   J. Smith , O = Widget Inc. , C = US",
+                ((LdapDN)nameRFC2253_2).toUpName() );
+        assertEquals( "RFC2253_2 : ",
+                "cn=J. Smith+cn=Sales,o=Widget Inc.,c=US",
+                nameRFC2253_2.toString() );
+    }
+
+
+    /**
+     * Class under test for Name parse(String)
+     *
+     * @throws NamingException if anything goes wrong
+     */
+    public final void testParseStringRFC2253_3() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+
+        Name nameRFC2253_3 = parser.parse( "CN=L. Eagle,   O=Sue\\, Grabbit and Runn, C=GB" );
+
+        assertEquals( "RFC2253_3 : ", "CN=L. Eagle,   O=Sue\\, Grabbit and Runn, C=GB", ((LdapDN)nameRFC2253_3).toUpName() );
+        assertEquals( "RFC2253_3 : ", "cn=L. Eagle,o=Sue\\, Grabbit and Runn,c=GB", nameRFC2253_3.toString() );
+    }
+
+
+    /**
+     * Class under test for Name parse(String)
+     *
+     * @throws NamingException if anything goes wrong
+     */
+    public final void testParseStringRFC2253_4() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+
+        Name nameRFC2253_4 = parser.parse( "CN=Before\\0DAfter,O=Test,C=GB" );
+        assertEquals( "RFC2253_4 : ", "CN=Before\\0DAfter,O=Test,C=GB", ((LdapDN)nameRFC2253_4).toUpName() );
+    }
+
+
+    /**
+     * Class under test for Name parse(String)
+     *
+     * @throws NamingException if anything goes wrong
+     */
+    public final void testParseStringRFC2253_5() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+
+        Name nameRFC2253_5 = parser.parse( "1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB" );
+
+        assertEquals( "RFC2253_5 : ",
+                "1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB",
+                ((LdapDN)nameRFC2253_5).toUpName() );
+    }
+
+
+    /**
+     * Class under test for Name parse(String)
+     *
+     * @throws NamingException if anything goes wrong
+     */
+    public final void testParseStringRFC2253_6() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+
+        Name nameRFC2253_6 = parser.parse( "SN=Lu\\C4\\8Di\\C4\\87" );
+
+        assertEquals( "RFC2253_6 : ",
+                "SN=Lu\\C4\\8Di\\C4\\87",
+                ((LdapDN)nameRFC2253_6).toUpName() );
+    }
+
+
+    /**
+     * Class under test for Name parse(String)
+     *
+     * @throws NamingException if anything goes wrong
+     */
+    public final void testParseInvalidString() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+
+        try
+        {
+            parser.parse( "&#347;=&#347;rasulu,dc=example,dc=com" );
+            fail( "the invalid name should never succeed in a parse" );
+        }
+        catch ( Exception e )
+        {
+            assertNotNull(e);
+        }
+    }
+
+
+    /**
+     * Tests to see if inner whitespace is preserved after an escaped ',' in
+     * a value of a name component.  This test was added to try to reproduce
+     * the bug encountered in DIREVE-179 <a href="http://issues.apache.org/jira/browse/DIREVE-179">
+     * here</a>. 
+     *
+     * @throws NamingException if anything goes wrong on parse()
+     */
+    public final void testPreserveSpaceAfterEscape() throws NamingException
+    {
+    	NameParser parser = LdapDnParser.getNameParser();
+        String input = "ou=some test\\,  something else";
+        String result = parser.parse( input ).toString();
+        assertEquals( input, result );
+    }
+    
+    public void testWindowsFilePath() throws Exception
+    {
+        // '\' should be escaped as stated in RFC 2253
+        String path = "windowsFilePath=C:\\\\cygwin";
+        NameParser parser = LdapDnParser.getNameParser();
+        Name result = parser.parse( path );
+        assertEquals( path, ((LdapDN)result).toUpName() );
+        assertEquals( "windowsfilepath=C:\\\\cygwin", result.toString() );
+    }    
+    
+    public void testNameFrenchChars() throws Exception
+    {
+        String cn = new String(
+                new byte[] { 'c', 'n', '=', 0x4A, (byte) 0xC3, (byte) 0xA9, 0x72, (byte) 0xC3, (byte) 0xB4, 0x6D, 0x65 });
+
+        NameParser parser = LdapDnParser.getNameParser();
+        String result = parser.parse( cn ).toString();
+        
+        assertEquals( cn, result.toString() );
+
+    }
+
+    public void testNameGermanChars() throws Exception
+    {
+        String cn = new String(new byte[]{'c', 'n', '=', (byte)0xC3, (byte)0x84, (byte)0xC3, (byte)0x96, (byte)0xC3, 
+                    (byte)0x9C, (byte)0xC3, (byte)0x9F, (byte)0xC3, (byte)0xA4, (byte)0xC3, (byte)0xB6, (byte)0xC3, (byte)0xBC}, "UTF-8");
+        
+
+        NameParser parser = LdapDnParser.getNameParser();
+        String result = parser.parse( cn ).toString();
+        
+        assertEquals( cn, result.toString() );
+    }
+
+    public void testNameTurkishChars() throws Exception
+    {
+        String cn = new String(new byte[]{'c', 'n', '=', (byte)0xC4, (byte)0xB0, (byte)0xC4, (byte)0xB1, 
+                (byte)0xC5, (byte)0x9E, (byte)0xC5, (byte)0x9F, 
+                (byte)0xC3, (byte)0x96, (byte)0xC3, (byte)0xB6, 
+                (byte)0xC3, (byte)0x9C, (byte)0xC3, (byte)0xBC, 
+                (byte)0xC4, (byte)0x9E, (byte)0xC4, (byte)0x9F }, "UTF-8");
+
+        NameParser parser = LdapDnParser.getNameParser();
+        String result = parser.parse( cn ).toString();
+        
+        assertEquals( cn, result.toString() );
+
     }
 }



Mime
View raw message