Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 47234 invoked from network); 6 Jun 2008 16:49:17 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 6 Jun 2008 16:49:17 -0000 Received: (qmail 25368 invoked by uid 500); 6 Jun 2008 16:49:20 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 25301 invoked by uid 500); 6 Jun 2008 16:49:20 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 25289 invoked by uid 99); 6 Jun 2008 16:49:20 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 06 Jun 2008 09:49:20 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 06 Jun 2008 16:48:38 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id F064423889C2; Fri, 6 Jun 2008 09:48:55 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r664030 - in /directory/shared/branches/bigbang/ldap/src: main/java/org/apache/directory/shared/ldap/name/ main/java/org/apache/directory/shared/ldap/util/ test/java/org/apache/directory/shared/ldap/name/ Date: Fri, 06 Jun 2008 16:48:55 -0000 To: commits@directory.apache.org From: elecharny@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080606164855.F064423889C2@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: elecharny Date: Fri Jun 6 09:48:55 2008 New Revision: 664030 URL: http://svn.apache.org/viewvc?rev=664030&view=rev Log: Merged the fix for the RDN bug (DIRSERVER-1183) Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/name/Rdn.java directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/name/RdnParser.java directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DNUtils.java directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/name/RdnTest.java Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/name/Rdn.java URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/name/Rdn.java?rev=664030&r1=664029&r2=664030&view=diff ============================================================================== --- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/name/Rdn.java (original) +++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/name/Rdn.java Fri Jun 6 09:48:55 2008 @@ -106,6 +106,7 @@ * are not case sensitive, we can say that a = A * * @author Apache Directory Project + * @version $Rev$, $Date$ */ public class Rdn implements Cloneable, Comparable, Serializable, Iterable { @@ -172,11 +173,14 @@ /** CompareTo() results */ public static final int UNDEFINED = Integer.MAX_VALUE; + /** Constant used in comparisons */ public static final int SUPERIOR = 1; + /** Constant used in comparisons */ public static final int INFERIOR = -1; - public static final int EQUALS = 0; + /** Constant used in comparisons */ + public static final int EQUAL = 0; /** @@ -225,20 +229,17 @@ /** * A constructor that constructs a RDN from a type and a value. Constructs * an Rdn from the given attribute type and value. The string attribute - * values are not interpretted as RFC 2253 formatted RDN strings. That is, - * the values are used literally (not parsed) and assumed to be unescaped. + * values are not interpreted as RFC 2253 formatted RDN strings. That is, + * the values are used literally (not parsed) and assumed to be un-escaped. * - * @param type - * The type of the RDN - * @param value - * The value of the RDN - * @throws InvalidNameException - * If the RDN is invalid + * @param upType The user provided type of the RDN + * @param upValue The user provided value of the RDN + * @param normType The normalized provided type of the RDN + * @param normValue The normalized provided value of the RDN + * @throws InvalidNameException If the RDN is invalid */ public Rdn( String upType, String normType, String upValue, String normValue ) throws InvalidNameException { - super(); - addAttributeTypeAndValue( upType, normType, upValue, normValue ); upName = upType + '=' + upValue; @@ -250,17 +251,12 @@ /** - * A constructor that constructs a RDN from a type and a value. Constructs - * an Rdn from the given attribute type and value. The string attribute - * values are not interpretted as RFC 2253 formatted RDN strings. That is, - * the values are used literally (not parsed) and assumed to be unescaped. + * A constructor that constructs a RDN from a type, a position and a length. * - * @param type - * The type of the RDN - * @param value - * The value of the RDN - * @throws InvalidNameException - * If the RDN is invalid + * @param start The starting point for this RDN in the user provided DN + * @param length The RDN's length + * @param upName The user provided name + * @param normName the normalized name */ /* No protection */ Rdn( int start, int length, String upName, String normName ) { @@ -281,7 +277,6 @@ @SuppressWarnings({"unchecked"}) public Rdn( Rdn rdn ) { - super(); nbAtavs = rdn.getNbAtavs(); this.normName = rdn.normName; this.upName = rdn.getUpName(); @@ -299,17 +294,16 @@ default: // We must duplicate the treeSet and the hashMap - Iterator iter = rdn.atavs.iterator(); - atavs = new TreeSet(); atavTypes = new MultiHashMap(); - while ( iter.hasNext() ) + for ( AttributeTypeAndValue currentAtav:rdn.atavs ) { - AttributeTypeAndValue currentAtav = iter.next(); atavs.add( (AttributeTypeAndValue)currentAtav.clone() ); atavTypes.put( currentAtav.getUpType(), currentAtav ); } + + return; } } @@ -374,18 +368,19 @@ /** * Add a AttributeTypeAndValue to the current RDN * - * @param type - * The type of the added RDN. - * @param value - * The value of the added RDN + * @param upType The user provided type of the added RDN. + * @param type The normalized provided type of the added RDN. + * @param upValue The user provided value of the added RDN + * @param value The normalized provided value of the added RDN * @throws InvalidNameException * If the RDN is invalid */ - // WARNING : The protection level is left unspecified intentionnaly. + // WARNING : The protection level is left unspecified intentionally. // We need this method to be visible from the DnParser class, but not // from outside this package. @SuppressWarnings({"unchecked"}) - /* Unspecified protection */void addAttributeTypeAndValue( String upType, String type, Object upValue, Object value ) throws InvalidNameException + /* Unspecified protection */void addAttributeTypeAndValue( String upType, String type, Object upValue, Object value ) + throws InvalidNameException { // First, let's normalize the type String normalizedType = StringTools.lowerCaseAscii(type); @@ -432,26 +427,21 @@ /** * Add a AttributeTypeAndValue to the current RDN * - * @param type - * The type of the added RDN. - * @param value - * The value of the added RDN - * @throws InvalidNameException - * If the RDN is invalid + * @param value The added AttributeTypeAndValue */ // WARNING : The protection level is left unspecified intentionnaly. // We need this method to be visible from the DnParser class, but not // from outside this package. @SuppressWarnings({"unchecked"}) - /* Unspecified protection */void addAttributeTypeAndValue( AttributeTypeAndValue atav ) + /* Unspecified protection */void addAttributeTypeAndValue( AttributeTypeAndValue value ) { - String normalizedType = atav.getNormType(); + String normalizedType = value.getNormType(); switch ( nbAtavs ) { case 0: // This is the first AttributeTypeAndValue. Just stores it. - this.atav = atav; + this.atav = value; nbAtavs = 1; atavType = normalizedType; return; @@ -474,8 +464,8 @@ default: // add a new AttributeTypeAndValue - atavs.add( atav ); - atavTypes.put( normalizedType, atav ); + atavs.add( value ); + atavTypes.put( normalizedType, value ); nbAtavs++; break; @@ -508,6 +498,7 @@ * @param type * The type of the NameArgument * @return The Value to be returned, or null if none found. + * @throws InvalidNameException */ public Object getValue( String type ) throws InvalidNameException { @@ -524,10 +515,8 @@ { return atav.getNormValue(); } - else - { - return ""; - } + + return ""; default: if ( atavTypes.containsKey( normalizedType ) ) @@ -542,11 +531,10 @@ { StringBuffer sb = new StringBuffer(); boolean isFirst = true; + List atavList = ( ( List ) obj ); - for ( int i = 0; i < ( ( List ) obj ).size(); i++ ) + for ( AttributeTypeAndValue elem:atavList ) { - AttributeTypeAndValue elem = ( AttributeTypeAndValue ) ( ( List ) obj ).get( i ); - if ( isFirst ) { isFirst = false; @@ -566,10 +554,8 @@ throw new InvalidNameException( "Bad object stored in the RDN" ); } } - else - { - return ""; - } + + return ""; } } @@ -619,20 +605,16 @@ { return atav; } - else - { - return null; - } + + return null; default: if ( atavTypes.containsKey( normalizedType ) ) { return atavTypes.get( normalizedType ); } - else - { - return null; - } + + return null; } } @@ -682,8 +664,9 @@ /** * Clone the Rdn + * + * @return A clone of the current RDN */ - @SuppressWarnings({"unchecked"}) public Object clone() { try @@ -727,12 +710,12 @@ /** * Compares two RDNs. They are equals if : - * - their have the same number of NC (AttributeTypeAndValue) - * - each ATAVs are equals - * - comparizon of type are done case insensitive - * - each value is equel, case sensitive - * - Order of ATAV is not important If the RDNs are not equals, a positive number is - * returned if the first RDN is greated, negative otherwise + *
  • their have the same number of NC (AttributeTypeAndValue) + *
  • each ATAVs are equals + *
  • comparison of type are done case insensitive + *
  • each value is equal, case sensitive + *
  • Order of ATAV is not important If the RDNs are not equals, a positive number is + * returned if the first RDN is greater, negative otherwise * * @param object * @return 0 if both rdn are equals. -1 if the current RDN is inferior, 1 if @@ -760,7 +743,7 @@ switch ( nbAtavs ) { case 0: - return EQUALS; + return EQUAL; case 1: return atav.compareTo( rdn.atav ); @@ -775,53 +758,29 @@ if ( rdn.atavTypes.containsKey( type ) ) { - List atavLocalList = ( List ) atavTypes.get( type ); - List atavParamList = ( List ) rdn.atavTypes.get( type ); + List atavLocalList = ( List ) atavTypes.get( type ); + List atavParamList = ( List ) rdn.atavTypes.get( type ); - if ( atavLocalList.size() == 1 ) + // We have to verify that each value of the + // first list are present in + // the second list + for ( AttributeTypeAndValue atavLocal:atavLocalList ) { - // We have only one ATAV - AttributeTypeAndValue atavLocal = ( AttributeTypeAndValue ) atavLocalList.get( 0 ); - AttributeTypeAndValue atavParam = ( AttributeTypeAndValue ) atavParamList.get( 0 ); - - // If the ATAVs are different we are finished. - // It the ATAVs are equal we must compare the remaining ATAVs, too. - int result = atavLocal.compareTo( atavParam ); - if ( result != 0 ) - { - return result; - } - } - else - { - // We have to verify that each value of the - // first list are present in - // the second list - Iterator atavLocals = atavLocalList.iterator(); + boolean found = false; - while ( atavLocals.hasNext() ) + for ( AttributeTypeAndValue atavParam:atavParamList ) { - AttributeTypeAndValue atavLocal = atavLocals.next(); - - Iterator atavParams = atavParamList.iterator(); - boolean found = false; - - while ( atavParams.hasNext() ) + if ( atavLocal.compareTo( atavParam ) == EQUAL ) { - AttributeTypeAndValue atavParam = atavParams.next(); - - if ( atavLocal.compareTo( atavParam ) == EQUALS ) - { - found = true; - break; - } + found = true; + break; } + } - if ( !found ) - { - // The ATAV does not exist in the second RDN - return SUPERIOR; - } + if ( !found ) + { + // The ATAV does not exist in the second RDN + return SUPERIOR; } } } @@ -833,7 +792,7 @@ } } - return EQUALS; + return EQUAL; } } else @@ -844,7 +803,7 @@ /** - * Returns a String representation of the RDN + * @return a String representation of the RDN */ public String toString() { @@ -853,7 +812,7 @@ /** - * Returns a String representation of the RDN + * @return the user provided name */ public String getUpName() { @@ -862,7 +821,7 @@ /** - * Returns The normalized name + * @return The normalized name */ public String getNormName() { @@ -872,6 +831,7 @@ /** * Set the User Provided Name + * @param upName the User Provided dame */ public void setUpName( String upName ) { @@ -905,7 +865,7 @@ return atav; default: - return (AttributeTypeAndValue)((TreeSet)atavs).first(); + return ((TreeSet)atavs).first(); } } @@ -926,7 +886,7 @@ return atav.getUpType(); default: - return ( ( AttributeTypeAndValue )((TreeSet)atavs).first() ).getUpType(); + return ((TreeSet)atavs).first().getUpType(); } } @@ -946,7 +906,7 @@ return atav.getNormType(); default: - return ( ( AttributeTypeAndValue )((TreeSet)atavs).first() ).getNormType(); + return ((TreeSet)atavs).first().getNormType(); } } @@ -966,7 +926,7 @@ return atav.getNormValue(); default: - return ( ( AttributeTypeAndValue )((TreeSet)atavs).first() ).getNormValue(); + return ((TreeSet)atavs).first().getNormValue(); } } @@ -987,7 +947,7 @@ return atav.getUpValue(); default: - return ( ( AttributeTypeAndValue )((TreeSet)atavs).first() ).getUpValue(); + return ((TreeSet)atavs).first().getUpValue(); } } @@ -1013,7 +973,7 @@ return false; } - return compareTo( rdn ) == EQUALS; + return compareTo( rdn ) == EQUAL; } @@ -1050,21 +1010,14 @@ break; default : - Iterator types = atavTypes.keySet().iterator(); - - while ( types.hasNext() ) + for ( String type:atavTypes.keySet() ) { - String type = ( String ) types.next(); - List values = ( List ) atavTypes.get( type ); + List values = ( List ) atavTypes.get( type ); attribute = new AttributeImpl( type ); - Iterator iterValues = values.iterator(); - - while ( iterValues.hasNext() ) + for ( AttributeTypeAndValue value:values ) { - AttributeTypeAndValue value = iterValues.next(); - attribute.add( value.getNormValue() ); } @@ -1095,7 +1048,7 @@ * @throws IllegalArgumentException - * When an Illegal value is provided. */ - public static Object unescapeValue( String value ) throws IllegalArgumentException + public static Object unescapeValue( String value ) { if ( StringTools.isEmpty( value ) ) { @@ -1171,6 +1124,8 @@ isHex = true; pair = ( (byte)( StringTools.getHexValue( chars[i] ) << 4 ) ); } + + break; } } else @@ -1207,11 +1162,10 @@ default: byte[] result = StringTools.charToBytes( chars[i] ); - - for ( int j = 0; j < result.length; j++ ) - { - bytes[pos++] = result[j]; - } + System.arraycopy( result, 0, bytes, pos, result.length ); + pos += result.length; + + break; } } } @@ -1331,6 +1285,7 @@ default: newChars[pos++] = chars[i]; + break; } } @@ -1358,10 +1313,11 @@ } /** - * Gets the hashcode of this rdn. - * - * @see java.lang.Object#hashCode() - */ + * Gets the hashcode of this rdn. + * + * @see java.lang.Object#hashCode() + * @return the instance's hash code + */ public int hashCode() { int result = 37; @@ -1384,6 +1340,8 @@ { result = result * 17 + ata.hashCode(); } + + break; } return result; @@ -1407,7 +1365,9 @@ *
  • start
  • The position of this ATAV in the upName string *
  • length
  • The ATAV user provided length *
  • Call the ATAV write method
  • The ATAV itself - * + * + * @param out The stream into which the serialized RDN will be put + * @throws IOException If the stream can't be written */ public void writeExternal( ObjectOutput out ) throws IOException { @@ -1436,9 +1396,9 @@ break; default : - for ( AttributeTypeAndValue atav:atavs ) + for ( AttributeTypeAndValue value:atavs ) { - out.writeObject( atav ); + out.writeObject( value ); } break; @@ -1454,6 +1414,10 @@ * We read back the data to create a new RDB. The structure * read is exposed in the {@link Rdn#writeExternal(ObjectOutput)} * method

    + * + * @param in The input stream from which the RDN will be read + * @throws IOException If we can't read from the input stream + * @throws ClassNotFoundException If we can't create a new RDN */ public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException { @@ -1493,9 +1457,9 @@ for ( int i = 0; i < nbAtavs; i++ ) { - AttributeTypeAndValue atav = (AttributeTypeAndValue)in.readObject(); - atavs.add( atav ); - atavTypes.put( atav.getNormType(), atav ); + AttributeTypeAndValue value = (AttributeTypeAndValue)in.readObject(); + atavs.add( value ); + atavTypes.put( value.getNormType(), value ); } atav = null; Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/name/RdnParser.java URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/name/RdnParser.java?rev=664030&r1=664029&r2=664030&view=diff ============================================================================== --- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/name/RdnParser.java (original) +++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/name/RdnParser.java Fri Jun 6 09:48:55 2008 @@ -84,6 +84,7 @@ *
    * * @author Apache Directory Project + * @version $Rev$, $Date$ */ public class RdnParser { @@ -104,7 +105,7 @@ pos.end = pos.start; // ::= [0-9] - if ( StringTools.isDigit( bytes, pos.start ) == false ) + if ( !StringTools.isDigit( bytes, pos.start ) ) { // Nope... An error return null; @@ -120,7 +121,7 @@ } // ::= '.' [0-9] | e - if ( StringTools.isCharASCII( bytes, pos.end, '.' ) == false ) + if ( !StringTools.isCharASCII( bytes, pos.end, '.' ) ) { return null; } @@ -130,7 +131,7 @@ { pos.end++; - if ( StringTools.isDigit( bytes, pos.end ) == false ) + if ( !StringTools.isDigit( bytes, pos.end ) ) { return null; } @@ -169,7 +170,7 @@ pos.end = pos.start; // ::= [0-9] - if ( StringTools.isDigit( bytes, pos.start ) == false ) + if ( !StringTools.isDigit( bytes, pos.start ) ) { // Nope... An error return false; @@ -185,7 +186,7 @@ } // ::= '.' [0-9] | e - if ( StringTools.isCharASCII( bytes, pos.end, '.' ) == false ) + if ( !StringTools.isCharASCII( bytes, pos.end, '.' ) ) { return false; } @@ -195,7 +196,7 @@ { pos.end++; - if ( StringTools.isDigit( bytes, pos.end ) == false ) + if ( !StringTools.isDigit( bytes, pos.end ) ) { return false; } @@ -419,6 +420,7 @@ pos.length = 0; pos.end = pos.start; int nbBytes = 0; + int length = 0; // ::= '"' '"' // ::= | '\' @@ -430,22 +432,40 @@ pos.end++; int nbChars = 0; - if ( ( nbChars = DNUtils.countPairChar( bytes, pos.start ) ) != DNUtils.PARSING_ERROR ) + if ( ( nbChars = DNUtils.countPairChar( bytes, pos.end ) ) == DNUtils.PARSING_ERROR ) { - pos.end += nbChars; + return null; } else { - return null; + if ( nbChars == 1 ) + { + buffer[currPos++] = bytes[pos.end]; + } + else + { + byte b = StringTools.getHexValue( bytes[pos.end], bytes[pos.end + 1] ); + + buffer[currPos++] = b; + } + + pos.end += nbChars; + length += nbChars; } } else if ( ( nbBytes = DNUtils.isQuoteChar( bytes, pos.end ) ) != DNUtils.PARSING_ERROR ) { + for ( int i = 0; i < nbBytes; i++ ) + { + buffer[currPos++] = bytes[pos.end + i]; + } + pos.end += nbBytes; + length += nbBytes; } else { - pos.length = pos.end - pos.start; + //pos.length = pos.end - pos.start; break; } } @@ -453,7 +473,8 @@ if ( StringTools.isCharASCII( bytes, pos.end, '"' ) ) { pos.end++; - return StringTools.utf8ToString( bytes, pos.start, pos.length ); + return StringTools.utf8ToString( buffer, length ); + //return StringTools.utf8ToString( bytes, pos.start, pos.length ); } else { @@ -463,7 +484,6 @@ else { int escapedSpace = -1; - boolean hasPairChar = false; while ( true ) { @@ -473,6 +493,7 @@ pos.end++; int nbChars = 0; + if ( ( nbChars = DNUtils.countPairChar( bytes, pos.end ) ) == DNUtils.PARSING_ERROR ) { return null; @@ -485,11 +506,6 @@ } else { - if ( hasPairChar == false ) - { - hasPairChar = true; - } - byte b = StringTools.getHexValue( bytes[pos.end], bytes[pos.end + 1] ); buffer[currPos++] = b; @@ -528,10 +544,11 @@ //StringTools.trimLeft( string, pos ); if ( ( DNUtils.isStringChar( bytes, pos.end ) == DNUtils.PARSING_ERROR ) - && ( StringTools.isCharASCII( bytes, pos.end, '\\' ) == false ) ) + && ( !StringTools.isCharASCII( bytes, pos.end, '\\' ) ) ) { // Ok, we are done with the stringchar. - String result = StringTools.trimRight( StringTools.utf8ToString( bytes, pos.start, pos.start + pos.length ) ); + String result = StringTools.trimRight( + StringTools.utf8ToString( bytes, pos.start, pos.start + pos.length ) ); return result; } @@ -645,7 +662,7 @@ pos.end++; int nbChars = 0; - if ( ( nbChars = DNUtils.countPairChar( bytes, pos.start ) ) != DNUtils.PARSING_ERROR ) + if ( ( nbChars = DNUtils.countPairChar( bytes, pos.end ) ) != DNUtils.PARSING_ERROR ) { pos.end += nbChars; } @@ -710,7 +727,7 @@ //StringTools.trimLeft( string, pos ); if ( ( DNUtils.isStringChar( bytes, pos.end ) == DNUtils.PARSING_ERROR ) - && ( StringTools.isCharASCII( bytes, pos.end, '\\' ) == false ) ) + && ( !StringTools.isCharASCII( bytes, pos.end, '\\' ) ) ) { // Ok, we are done with the stringchar. return true; @@ -745,11 +762,18 @@ * * @param bytes The byte buffer to parse * @param pos The current position in the byte buffer + * @param rdn The rdn to generate * @return The new position in the byte buffer, or PARSING_ERROR if the rule * does not apply to the byte buffer + * @throws InvalidNameException If the NameComponent is invalid */ private static int parseNameComponents( byte[] bytes, Position pos, Rdn rdn ) throws InvalidNameException { + if ( rdn == null ) + { + throw new InvalidNameException( "The RDN should not be null" ); + } + int newStart = 0; String type = null; Object value = null; @@ -819,6 +843,7 @@ * * @param bytes The byte buffer to parse * @param pos The current position in the byte buffer + * @param isFirstRdn A flag set if the RDN is the first one * @return true if the rule is valid */ private static boolean isValidNameComponents( byte[] bytes, Position pos, boolean isFirstRdn ) @@ -885,6 +910,7 @@ * @param rdn The constructed RDN * @return The new position in the char array, or PARSING_ERROR if the rule * does not apply to the char array + * @throws InvalidNameException If the NameComponent is invalid */ public static int parse( String dn, Position pos, Rdn rdn ) throws InvalidNameException { @@ -904,14 +930,15 @@ * @param rdn The constructed RDN * @return The new position in the byte array, or PARSING_ERROR if the rule * does not apply to the byte array + * @throws InvalidNameException If the NameComponent is invalid */ public static int parse( byte[] dn, Position pos, Rdn rdn ) throws InvalidNameException { - if ( rdn == null ) - { - throw new InvalidNameException( "Cannot feed a null RDN structure" ); - } - + if ( rdn == null ) + { + throw new InvalidNameException( "Cannot feed a null RDN structure" ); + } + String type = null; Object value = null; int start = pos.start; @@ -930,7 +957,7 @@ StringTools.trimLeft( dn, pos ); - if ( StringTools.isCharASCII( dn, pos.start, '=' ) == false ) + if ( !StringTools.isCharASCII( dn, pos.start, '=' ) ) { return DNUtils.PARSING_ERROR; } @@ -972,28 +999,12 @@ * <spaces> <attributeValue> <nameComponents> *

    * - * @param dn The String to parse - * @param pos The current position in the buffer - * @return true if the RDN is valid - */ - public static boolean isValid( String dn, Position pos, boolean isfirstRdn ) - { - return isValid( StringTools.getBytesUtf8( dn ), pos, isfirstRdn ); - } - - - /** - * Validate a NameComponent :
    - *

    - * <name-component> ::= <attributeType> <spaces> '=' - * <spaces> <attributeValue> <nameComponents> - *

    - * * @param dn The byte array to parse * @param pos The current position in the buffer + * @param isFirstRdn a flag set if the RDN is the first for the current DN * @return true if the RDN is valid */ - public static boolean isValid( byte[] dn, Position pos, boolean isfirstRdn ) + public static boolean isValid( byte[] dn, Position pos, boolean isFirstRdn ) { StringTools.trimLeft( dn, pos ); @@ -1009,7 +1020,7 @@ StringTools.trimLeft( dn, pos ); - if ( StringTools.isCharASCII( dn, pos.start, '=' ) == false ) + if ( !StringTools.isCharASCII( dn, pos.start, '=' ) ) { return false; } @@ -1030,7 +1041,7 @@ pos.start = pos.end; pos.length = 0; - if ( !isValidNameComponents( dn, pos, isfirstRdn ) ) + if ( !isValidNameComponents( dn, pos, isFirstRdn ) ) { return false; } @@ -1050,6 +1061,7 @@ * @param dn The String to parse * @param rdn The RDN to fill. Beware that if the RDN is not empty, the new * AttributeTypeAndValue will be added. + * @throws InvalidNameException If the NameComponent is invalid */ public static void parse( String dn, Rdn rdn ) throws InvalidNameException { Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DNUtils.java URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DNUtils.java?rev=664030&r1=664029&r2=664030&view=diff ============================================================================== --- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DNUtils.java (original) +++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DNUtils.java Fri Jun 6 09:48:55 2008 @@ -19,14 +19,12 @@ */ package org.apache.directory.shared.ldap.util; -import org.apache.directory.shared.ldap.util.Position; -import org.apache.directory.shared.ldap.util.StringTools; - /** * Utility class used by the LdapDN Parser. * * @author Apache Directory Project + * @version $Rev$, $Date$ */ public class DNUtils { @@ -123,28 +121,52 @@ }; /** - * ' ' | '"' | '#' | '+' | ',' | [0-9] | ';' | '<' | '=' | '>' | [A-F] | '\' | - * [a-f] 0x22 | 0x23 | 0x2B | 0x2C | [0x30-0x39] | 0x3B | 0x3C | 0x3D | 0x3E | + * ' ' | '"' | '#' | '+' | ',' | [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, - true, 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 + false, false, false, false, false, false, false, false, // 00 -> 07 + false, false, false, false, false, false, false, false, // 08 -> 0F + false, false, false, false, false, false, false, false, // 10 -> 17 + false, false, false, false, false, false, false, false, // 18 -> 1F + true, false, true, true, false, false, false, false, // 20 -> 27 ( ' ', '"', '#' ) + false, false, false, true, true, false, false, false, // 28 -> 2F ( '+', ',' ) + true, true, true, true, true, true, true, true, // 30 -> 37 ( '0'..'7' ) + true, true, false, true, true, true, true, false, // 38 -> 3F ( '8', '9', ';', '<', '=', '>' ) + false, true, true, true, true, true, true, false, // 40 -> 47 ( 'A', 'B', 'C', 'D', 'E', 'F' ) + false, false, false, false, false, false, false, false, // 48 -> 4F + false, false, false, false, false, false, false, false, // 50 -> 57 + false, false, false, false, true, false, false, false, // 58 -> 5F ( '\' ) + false, true, true, true, true, true, true, false, // 60 -> 67 ( 'a', 'b', 'c', 'd', 'e', 'f' ) + false, false, false, false, false, false, false, false, // 68 -> 6F + false, false, false, false, false, false, false, false, // 70 -> 77 + false, false, false, false, false, false, false, false // 78 -> 7F + }; + + /** + * ' ' | '"' | '#' | '+' | ',' | ';' | '<' | '=' | '>' | '\' | + * 0x22 | 0x23 | 0x2B | 0x2C | 0x3B | 0x3C | 0x3D | 0x3E | 0x5C + */ + private static final boolean[] PAIR_CHAR_ONLY = + { + false, false, false, false, false, false, false, false, // 00 -> 07 + false, false, false, false, false, false, false, false, // 08 -> 0F + false, false, false, false, false, false, false, false, // 10 -> 17 + false, false, false, false, false, false, false, false, // 18 -> 1F + true, false, true, true, false, false, false, false, // 20 -> 27 ( ' ', '"', '#' ) + false, false, false, true, true, false, false, false, // 28 -> 2F ( '+', ',' ) + false, false, false, false, false, false, false, false, // 30 -> 37 + false, false, false, true, true, true, true, false, // 38 -> 3F ( ';', '<', '=', '>' ) + false, false, false, false, false, false, false, false, // 40 -> 47 + false, false, false, false, false, false, false, false, // 48 -> 4F + false, false, false, false, false, false, false, false, // 50 -> 57 + false, false, false, false, true, false, false, false, // 58 -> 5F ( '\' ) + false, false, false, false, false, false, false, false, // 60 -> 67 + false, false, false, false, false, false, false, false, // 68 -> 6F + false, false, false, false, false, false, false, false, // 70 -> 77 + false, false, false, false, false, false, false, false // 78 -> 7F }; /** @@ -202,7 +224,7 @@ { byte c = bytes[index]; - if ( ( ( c | 0x7F ) != 0x7F ) || ( SAFE_INIT_CHAR[c] == false ) ) + if ( ( ( c | 0x7F ) != 0x7F ) || ( !SAFE_INIT_CHAR[c] ) ) { return -1; } @@ -213,7 +235,7 @@ { c = bytes[index]; - if ( ( ( c | 0x7F ) != 0x7F ) || ( SAFE_CHAR[c] == false ) ) + if ( ( ( c | 0x7F ) != 0x7F ) || ( !SAFE_CHAR[c] ) ) { break; } @@ -244,13 +266,13 @@ { byte b = bytes[index++]; - if ( StringTools.isAlpha( b ) == false ) + if ( StringTools.isAlpha( b ) ) { - return -1; + return index-1; } else { - return index; + return -1; } } } @@ -274,19 +296,23 @@ { byte c = bytes[index]; - if ( ( ( c | 0x7F ) != 0x7F ) || ( PAIR_CHAR[c] == false ) ) + if ( ( ( c | 0x7F ) != 0x7F ) || ( !PAIR_CHAR[c] ) ) { return false; } else { - if ( StringTools.isHex( bytes, index++ ) ) + if ( PAIR_CHAR_ONLY[c] ) + { + return true; + } + else if ( StringTools.isHex( bytes, index++ ) ) { return StringTools.isHex( bytes, index ); } else { - return true; + return false; } } } @@ -320,19 +346,23 @@ { byte c = bytes[index]; - if ( ( ( c | 0x7F ) != 0x7F ) || ( PAIR_CHAR[c] == false ) ) + if ( ( ( c | 0x7F ) != 0x7F ) || ( !PAIR_CHAR[c] ) ) { return PARSING_ERROR; } else { - if ( StringTools.isHex( bytes, index++ ) ) + if ( PAIR_CHAR_ONLY[c] ) + { + return 1; + } + else if ( StringTools.isHex( bytes, index++ ) ) { return StringTools.isHex( bytes, index ) ? 2 : PARSING_ERROR; } else { - return 1; + return PARSING_ERROR; } } } @@ -532,7 +562,7 @@ { byte c = bytes[index]; - if ( ( ( c | 0x7F ) != 0x7F ) || ( BASE64_CHAR[c] == false ) ) + if ( ( ( c | 0x7F ) != 0x7F ) || ( !BASE64_CHAR[c] ) ) { return -1; } @@ -543,7 +573,7 @@ { c = bytes[index]; - if ( ( ( c | 0x7F ) != 0x7F ) || ( BASE64_CHAR[c] == false ) ) + if ( ( ( c | 0x7F ) != 0x7F ) || ( !BASE64_CHAR[c] ) ) { break; } Modified: directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/name/RdnTest.java URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/name/RdnTest.java?rev=664030&r1=664029&r2=664030&view=diff ============================================================================== --- directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/name/RdnTest.java (original) +++ directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/name/RdnTest.java Fri Jun 6 09:48:55 2008 @@ -32,22 +32,22 @@ import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; -import org.apache.directory.shared.ldap.name.Rdn; -import org.apache.directory.shared.ldap.name.RdnParser; import org.apache.directory.shared.ldap.util.StringTools; -import org.junit.Test; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.junit.Test; + /** * Test the class Rdn * * @author Apache Directory Project + * @version $Rev$, $Date$, */ public class RdnTest { @@ -65,6 +65,8 @@ /** * test an empty RDN + * + * @throws InvalidNameException */ @Test public void testRdnEmpty() throws InvalidNameException @@ -75,6 +77,8 @@ /** * test a simple RDN : a = b + * + * @throws InvalidNameException */ @Test public void testRdnSimple() throws InvalidNameException @@ -85,6 +89,8 @@ /** * test a composite RDN : a = b, d = e + * + * @throws InvalidNameException */ @Test public void testRdnComposite() throws InvalidNameException @@ -96,6 +102,8 @@ /** * test a composite RDN with or without spaces: a=b, a =b, a= b, a = b, a = * b + * + * @throws InvalidNameException */ @Test public void testRdnCompositeWithSpace() throws InvalidNameException @@ -121,6 +129,8 @@ /** * test a simple RDN with differents separators : a = b + c = d + * + * @throws InvalidNameException */ @Test public void testRdnSimpleMultivaluedAttribute() throws InvalidNameException @@ -133,6 +143,8 @@ /** * test a composite RDN with differents separators : a=b+c=d, e=f + g=h + * i=j + * + * @throws InvalidNameException */ @Test public void testRdnCompositeMultivaluedAttribute() throws InvalidNameException @@ -150,6 +162,8 @@ /** * test a simple RDN with an oid prefix (uppercase) : OID.12.34.56 = azerty + * + * @throws InvalidNameException */ @Test public void testRdnOidUpper() throws InvalidNameException @@ -160,6 +174,8 @@ /** * test a simple RDN with an oid prefix (lowercase) : oid.12.34.56 = azerty + * + * @throws InvalidNameException */ @Test public void testRdnOidLower() throws InvalidNameException @@ -171,6 +187,8 @@ /** * test a simple RDN with an oid attribut wiithout oid prefix : 12.34.56 = * azerty + * + * @throws InvalidNameException */ @Test public void testRdnOidWithoutPrefix() throws InvalidNameException @@ -182,6 +200,8 @@ /** * test a composite RDN with an oid attribut wiithout oid prefix : 12.34.56 = * azerty; 7.8 = test + * + * @throws InvalidNameException */ @Test public void testRdnCompositeOidWithoutPrefix() throws InvalidNameException @@ -193,6 +213,8 @@ /** * test a simple RDN with pair char attribute value : a = \,\=\+\<\>\#\;\\\"\C3\A9" + * + * @throws InvalidNameException */ @Test public void testRdnPairCharAttributeValue() throws InvalidNameException @@ -216,6 +238,8 @@ /** * test a simple RDN with quoted attribute value : a = "quoted \"value" + * + * @throws InvalidNameException */ @Test public void testRdnQuotedAttributeValue() throws InvalidNameException @@ -228,24 +252,26 @@ * Test the clone method for a RDN. */ @Test - public void testParseRDNNull() throws InvalidNameException + public void testParseRDNNull() { Rdn rdn = null; try { - RdnParser.parse( "c=d", rdn ); - fail(); + RdnParser.parse( "c=d", rdn ); + fail(); } catch ( InvalidNameException ine ) { - assertTrue( true ); + assertTrue( true ); } } /** * Test the clone method for a RDN. + * + * @throws InvalidNameException */ @Test public void testRDNCloningOneNameComponent() throws InvalidNameException @@ -262,6 +288,8 @@ /** * Test the clone method for a RDN. + * + * @throws InvalidNameException */ @Test public void testRDNCloningTwoNameComponent() throws InvalidNameException @@ -281,6 +309,8 @@ /** * Test the compareTo method for a RDN. + * + * @throws InvalidNameException */ @Test public void testRDNCompareToNull() throws InvalidNameException @@ -293,6 +323,8 @@ /** * Compares a composite NC to a single NC. + * + * @throws InvalidNameException */ @Test public void testRDNCompareToNCS2NC() throws InvalidNameException @@ -305,6 +337,8 @@ /** * Compares a single NC to a composite NC. + * + * @throws InvalidNameException */ @Test public void testRDNCompareToNC2NCS() throws InvalidNameException @@ -318,6 +352,8 @@ /** * Compares a composite NCS to a composite NCS in the same order. + * + * @throws InvalidNameException */ @Test public void testRDNCompareToNCS2NCSOrdered() throws InvalidNameException @@ -331,6 +367,8 @@ /** * Compares a composite NCS to a composite NCS in a different order. + * + * @throws InvalidNameException */ @Test public void testRDNCompareToNCS2NCSUnordered() throws InvalidNameException @@ -344,6 +382,8 @@ /** * Compares a composite NCS to a different composite NCS. + * + * @throws InvalidNameException */ @Test public void testRDNCompareToNCS2NCSNotEquals() throws InvalidNameException @@ -351,13 +391,16 @@ Rdn rdn1 = new Rdn( " a = f + g = h + c = d " ); Rdn rdn2 = new Rdn( " c = d + a = h + g = h " ); - assertEquals( -1, rdn1.compareTo( rdn2 ) ); + assertEquals( 1, rdn1.compareTo( rdn2 ) ); + assertEquals( 1, rdn2.compareTo( rdn1 ) ); } /** * Test for DIRSHARED-2. * The first ATAV is equal, the second or following ATAV differs. + * + * @throws InvalidNameException */ @Test public void test_DIRSHARED_2() throws InvalidNameException @@ -378,8 +421,37 @@ assertTrue( rdn5.compareTo( rdn6 ) != 0 ); } + + /** + * Test for DIRSHARED-3. + * The compare operation should return a correct value (1 or -1) + * depending on the ATAVs, not on their position. + * + * @throws InvalidNameException + */ + @Test + public void test_DIRSHARED_3() throws InvalidNameException + { + Rdn rdn1 = new Rdn( " a = b + c = d " ); + Rdn rdn2 = new Rdn( " c = d + a = b " ); + assertEquals( 0, rdn1.compareTo( rdn2 ) ); + + rdn1 = new Rdn( " a = b + c = e " ); + rdn2 = new Rdn( " c = d + a = b " ); + assertEquals( 1, rdn1.compareTo( rdn2 ) ); + assertEquals( 1, rdn2.compareTo( rdn1 ) ); + + rdn1 = new Rdn( " a = b + c = d " ); + rdn2 = new Rdn( " e = f + g = h " ); + assertEquals( 1, rdn1.compareTo( rdn2 ) ); + assertEquals( 1, rdn2.compareTo( rdn1 ) ); + + } + /** * Compares with a null RDN. + * + * @throws InvalidNameException */ @Test public void testRDNCompareToNullRdn() throws InvalidNameException @@ -392,6 +464,8 @@ /** * Compares with a bad object + * + * @throws InvalidNameException */ @Test public void testRDNCompareToBadObject() throws InvalidNameException @@ -404,6 +478,8 @@ /** * Compares a simple NC to a simple NC. + * + * @throws InvalidNameException */ @Test public void testRDNCompareToNC2NC() throws InvalidNameException @@ -417,6 +493,8 @@ /** * Compares a simple NC to a simple NC in UperCase. + * + * @throws InvalidNameException */ @Test public void testRDNCompareToNC2NCUperCase() throws InvalidNameException @@ -431,6 +509,8 @@ /** * Compares a simple NC to a different simple NC. + * + * @throws InvalidNameException */ @Test public void testRDNCompareToNC2NCNotEquals() throws InvalidNameException @@ -442,6 +522,13 @@ } + /** + * + * test the ToAttributes method. + * + * @throws InvalidNameException + * @throws NamingException + */ @Test public void testToAttributes() throws InvalidNameException, NamingException { @@ -471,6 +558,12 @@ } + /** + * + * Test the getValue method. + * + * @throws InvalidNameException + */ @Test public void testGetValue() throws InvalidNameException { @@ -480,6 +573,12 @@ } + /** + * + * Test the getType method. + * + * @throws InvalidNameException + */ @Test public void testGetType() throws InvalidNameException { @@ -489,6 +588,11 @@ } + /** + * Test the getSize method. + * + * @throws InvalidNameException + */ @Test public void testGetSize() throws InvalidNameException { @@ -498,6 +602,10 @@ } + /** + * Test the getSize method. + * + */ @Test public void testGetSize0() { @@ -507,6 +615,11 @@ } + /** + * Test the equals method + * + * @throws InvalidNameException + */ @Test public void testEquals() throws InvalidNameException { @@ -640,7 +753,7 @@ @Test - public void testEmptyIterator() throws InvalidNameException + public void testEmptyIterator() { Rdn rdn = new Rdn(); Iterator iterator = rdn.iterator(); @@ -692,7 +805,7 @@ @Test - public void testEscapedAttributeValue() throws InvalidNameException + public void testEscapedAttributeValue() { // space doesn't need to be escaped in the middle of a string assertEquals( "a b", Rdn.escapeValue( "a b" ) ); @@ -749,7 +862,7 @@ @Test - public void testNullRdnSerialization() throws NamingException, IOException, ClassNotFoundException + public void testNullRdnSerialization() throws IOException, ClassNotFoundException { Rdn rdn = new Rdn(); @@ -958,7 +1071,7 @@ @Test - public void testNullRdnStaticSerialization() throws NamingException, IOException, ClassNotFoundException + public void testNullRdnStaticSerialization() throws IOException, ClassNotFoundException { Rdn rdn = new Rdn(); @@ -1144,4 +1257,22 @@ assertEquals( "a=", new Rdn( "a=" ).toString() ); } + /** + * test an RDN with escaped comma + */ + @Test + public void testRdnWithEscapedComa() throws InvalidNameException + { + assertTrue( RdnParser.isValid( "a=b\\,c" ) ); + assertEquals( "a=b\\,c", new Rdn( "a=b\\,c" ).toString() ); + + assertTrue( RdnParser.isValid( "a=\"b,c\"" ) ); + assertEquals( "a=b\\,c", new Rdn( "a=\"b,c\"" ).toString() ); + assertEquals( "a=\"b,c\"", new Rdn( "a=\"b,c\"" ).getUpName() ); + + assertTrue( RdnParser.isValid( "a=\"b\\,c\"" ) ); + Rdn rdn = new Rdn( "a=\"b\\,c\"" ); + assertEquals( "a=\"b\\,c\"", new Rdn( "a=\"b\\,c\"" ).getUpName() ); + assertEquals( "a=b\\,c", new Rdn( "a=\"b\\,c\"" ).toString() ); + } }