You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2016/05/09 17:22:21 UTC

svn commit: r1743011 [6/13] - in /directory/shared/branches/shared-value: dsml/parser/src/main/java/org/apache/directory/api/dsmlv2/request/ dsml/parser/src/main/java/org/apache/directory/api/dsmlv2/response/ dsml/parser/src/test/java/org/apache/direct...

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/FilterParser.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/FilterParser.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/FilterParser.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/FilterParser.java Mon May  9 17:22:19 2016
@@ -26,6 +26,7 @@ import org.apache.directory.api.i18n.I18
 import org.apache.directory.api.ldap.model.entry.AttributeUtils;
 import org.apache.directory.api.ldap.model.entry.Value;
 import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
 import org.apache.directory.api.ldap.model.schema.SchemaManager;
 import org.apache.directory.api.util.Chars;
@@ -46,6 +47,82 @@ public final class FilterParser
     {
     }
 
+    
+    /**
+     * Parses a search filter from it's string representation to an expression node object.
+     * 
+     * @param filter the search filter in it's string representation
+     * @return the expression node object
+     */
+    public static ExprNode parse( String filter ) throws ParseException
+    {
+        return parse( null, filter, false );
+    }
+
+
+    /**
+     * Parses a search filter from it's string representation to an expression node object.
+     * 
+     * In <code>relaxed</code> mode the filter may violate RFC 4515, e.g. the underscore in attribute names is allowed.
+     * 
+     * @param filter the search filter in it's string representation
+     * @param relaxed <code>true</code> to parse the filter in relaxed mode
+     * @return the expression node object
+     */
+    public static ExprNode parse( String filter, boolean relaxed ) throws ParseException
+    {
+        return parse( null, filter, relaxed );
+    }
+
+    
+    /**
+     * Parses a search filter from it's string representation to an expression node object,
+     * using the provided SchemaManager 
+     * 
+     * @param schemaManager The SchemaManager to use
+     * @param filter the search filter in it's string representation
+     * @return the expression node object
+     */
+    public static ExprNode parse( SchemaManager schemaManager, String filter ) throws ParseException
+    {
+        return parse( schemaManager, filter, false );
+    }
+
+
+    /**
+     * Parses a search filter from it's string representation to an expression node object,
+     * using the provided SchemaManager 
+     * 
+     * @param schemaManager The SchemaManager to use
+     * @param filter the search filter in it's string representation
+     * @param relaxed <code>true</code> to parse the filter in relaxed mode
+     * @return the expression node object
+     */
+    public static ExprNode parse( SchemaManager schemaManager, String filter, boolean relaxed ) throws ParseException
+    {
+        if ( Strings.isEmpty( filter ) )
+        {
+            throw new ParseException( I18n.err( I18n.ERR_04158 ), 0 );
+        }
+
+        /** Convert the filter to an array of bytes, as this is what we expect */
+        byte[] filterBytes = Strings.getBytesUtf8( filter );
+        
+        Position pos = new Position();
+        pos.start = 0;
+        pos.end = 0;
+        pos.length = filterBytes.length;
+
+        try
+        {
+            return parseFilterInternal( schemaManager, filterBytes, pos, relaxed );
+        }
+        catch ( LdapException le )
+        {
+            throw new ParseException( le.getMessage(), pos.start );
+        }
+    }
+
 
     /**
      * Parse an extensible
@@ -54,7 +131,7 @@ public final class FilterParser
      *                  / ( [":dn"] ':' oid ":=" assertionvalue )
      * matchingrule   = ":" oid
      */
-    private static ExprNode parseExtensible( SchemaManager schemaManager, String attribute, byte[] filter,
+    private static ExprNode parseExtensible( SchemaManager schemaManager, String attribute, byte[] filterBytes,
         Position pos, boolean relaxed ) throws LdapException, ParseException
     {
         ExtensibleNode node = null;
@@ -80,7 +157,7 @@ public final class FilterParser
         if ( attribute != null )
         {
             // First check if we have a ":dn"
-            if ( Strings.areEquals( filter, pos.start, "dn" ) >= 0 )
+            if ( Strings.isCharASCII( filterBytes, pos.start, 'd' ) && Strings.isCharASCII( filterBytes, pos.start + 1, 'n' ) )
             {
                 // Set the dnAttributes flag and move forward in the string
                 node.setDnAttributes( true );
@@ -93,31 +170,31 @@ public final class FilterParser
             }
 
             // Do we have a MatchingRule ?
-            if ( Strings.byteAt( filter, pos.start ) == ':' )
+            if ( Strings.byteAt( filterBytes, pos.start ) == ':' )
             {
                 pos.start++;
 
-                if ( Strings.byteAt( filter, pos.start ) == '=' )
+                if ( Strings.byteAt( filterBytes, pos.start ) == '=' )
                 {
                     pos.start++;
 
                     // Get the assertionValue
-                    node.setValue( parseAssertionValue( schemaManager, filter, pos ) );
+                    node.setValue( parseAssertionValue( schemaManager, filterBytes, pos ) );
 
                     return node;
                 }
                 else
                 {
-                    String matchingRuleId = AttributeUtils.parseAttribute( filter, pos, false, relaxed );
+                    String matchingRuleId = AttributeUtils.parseAttribute( filterBytes, pos, false, relaxed );
 
                     node.setMatchingRuleId( matchingRuleId );
 
-                    if ( Strings.areEquals( filter, pos.start, ":=" ) >= 0 )
+                    if ( Strings.isCharASCII( filterBytes, pos.start, ':' ) && Strings.isCharASCII( filterBytes, pos.start + 1, '=' ) )
                     {
                         pos.start += 2;
 
                         // Get the assertionValue
-                        node.setValue( parseAssertionValue( schemaManager, filter, pos ) );
+                        node.setValue( parseAssertionValue( schemaManager, filterBytes, pos ) );
 
                         return node;
                     }
@@ -138,7 +215,9 @@ public final class FilterParser
             boolean oidRequested = false;
 
             // First check if we have a ":dn"
-            if ( Strings.areEquals( filter, pos.start, ":dn" ) >= 0 )
+            if ( Strings.isCharASCII( filterBytes, pos.start, ':' )
+                 && Strings.isCharASCII( filterBytes, pos.start + 1, 'd' )
+                 && Strings.isCharASCII( filterBytes, pos.start + 2, 'n' ) )
             {
                 // Set the dnAttributes flag and move forward in the string
                 node.setDnAttributes( true );
@@ -150,36 +229,36 @@ public final class FilterParser
             }
 
             // Do we have a MatchingRule ?
-            if ( Strings.byteAt( filter, pos.start ) == ':' )
+            if ( Strings.byteAt( filterBytes, pos.start ) == ':' )
             {
                 pos.start++;
 
-                if ( Strings.byteAt( filter, pos.start ) == '=' )
+                if ( Strings.byteAt( filterBytes, pos.start ) == '=' )
                 {
                     if ( oidRequested )
                     {
-                        throw new ParseException( I18n.err( I18n.ERR_04148 ), pos.start );
+                        throw new ParseException( I18n.err( I18n.ERR_04148_MATCHING_RULE_EXPECTED ), pos.start );
                     }
 
                     pos.start++;
 
                     // Get the assertionValue
-                    node.setValue( parseAssertionValue( schemaManager, null, filter, pos ) );
+                    node.setValue( parseAssertionValue( schemaManager, null, filterBytes, pos ) );
 
                     return node;
                 }
                 else
                 {
-                    String matchingRuleId = AttributeUtils.parseAttribute( filter, pos, false, relaxed );
+                    String matchingRuleId = AttributeUtils.parseAttribute( filterBytes, pos, false, relaxed );
 
                     node.setMatchingRuleId( matchingRuleId );
 
-                    if ( Strings.areEquals( filter, pos.start, ":=" ) >= 0 )
+                    if ( Strings.isCharASCII( filterBytes, pos.start, ':' ) && Strings.isCharASCII( filterBytes, pos.start + 1, '=' ) )
                     {
                         pos.start += 2;
 
                         // Get the assertionValue
-                        node.setValue( parseAssertionValue( schemaManager, null, filter, pos ) );
+                        node.setValue( parseAssertionValue( schemaManager, null, filterBytes, pos ) );
 
                         return node;
                     }
@@ -230,13 +309,13 @@ public final class FilterParser
      * unicodeSubset     = %x01-27 / %x2B-5B / %x5D-FFFF
      * @throws LdapInvalidAttributeValueException 
      */
-    private static Value parseAssertionValue( SchemaManager schemaManager, String attribute, byte[] filter,
-        Position pos ) throws ParseException
+    private static Value parseAssertionValue( SchemaManager schemaManager, String attribute, byte[] filterBytes,
+        Position pos ) throws ParseException, LdapInvalidAttributeValueException
     {
-        byte b = Strings.byteAt( filter, pos.start );
+        byte b = Strings.byteAt( filterBytes, pos.start );
 
         // Create a buffer big enough to contain the value once converted
-        byte[] value = new byte[filter.length - pos.start];
+        byte[] value = new byte[filterBytes.length - pos.start];
         int current = 0;
 
         do
@@ -246,13 +325,13 @@ public final class FilterParser
                 value[current++] = b;
                 pos.start++;
             }
-            else if ( Strings.isCharASCII( filter, pos.start, '\\' ) )
+            else if ( Strings.isCharASCII( filterBytes, pos.start, '\\' ) )
             {
                 // Maybe an escaped
                 pos.start++;
 
                 // First hex
-                if ( Chars.isHex( filter, pos.start ) )
+                if ( Chars.isHex( filterBytes, pos.start ) )
                 {
                     pos.start++;
                 }
@@ -262,9 +341,9 @@ public final class FilterParser
                 }
 
                 // second hex
-                if ( Chars.isHex( filter, pos.start ) )
+                if ( Chars.isHex( filterBytes, pos.start ) )
                 {
-                    value[current++] = Hex.getHexValue( filter[pos.start - 1], filter[pos.start] );
+                    value[current++] = Hex.getHexValue( filterBytes[pos.start - 1], filterBytes[pos.start] );
                     pos.start++;
                 }
                 else
@@ -278,36 +357,36 @@ public final class FilterParser
                 break;
             }
 
-            b = Strings.byteAt( filter, pos.start );
+            b = Strings.byteAt( filterBytes, pos.start );
         }
         while ( b != '\0' );
 
         if ( current != 0 )
         {
-            byte[] result = new byte[current];
-            System.arraycopy( value, 0, result, 0, current );
-
             if ( schemaManager != null )
             {
                 AttributeType attributeType = schemaManager.getAttributeType( attribute );
 
                 if ( attributeType == null )
                 {
-                    return new Value( result );
+                    return new Value( Strings.utf8ToString( value, current ) );
                 }
 
                 if ( attributeType.getSyntax().isHumanReadable() )
                 {
-                    return new Value( Strings.utf8ToString( result ) );
+                    return new Value( attributeType, Strings.utf8ToString( value, current ) );
                 }
                 else
                 {
-                    return new Value( result );
+                    byte[] bytes = new byte[value.length];
+                    System.arraycopy( value, 0, bytes, 0, current );
+                    
+                    return new Value( attributeType, Strings.utf8ToString( bytes ) );
                 }
             }
             else
             {
-                return new Value( result );
+                return new Value( Strings.utf8ToString( value, current ) );
             }
         }
         else
@@ -318,11 +397,11 @@ public final class FilterParser
 
                 if ( attributeType.getEquality().getSyntax().isHumanReadable() )
                 {
-                    return new Value( ( String ) null );
+                    return new Value( attributeType, ( String ) null );
                 }
                 else
                 {
-                    return new Value( ( byte[] ) null );
+                    return new Value( attributeType, ( byte[] ) null );
                 }
             }
             else
@@ -365,13 +444,13 @@ public final class FilterParser
      * HEX            = '0'-'9' / 'A'-'F' / 'a'-'f'
      * unicodeSubset     = %x01-27 / %x2B-5B / %x5D-FFFF
      */
-    private static Value parseAssertionValue( SchemaManager schemaManager, byte[] filter, Position pos )
+    private static Value parseAssertionValue( SchemaManager schemaManager, byte[] filterBytes, Position pos )
         throws ParseException
     {
-        byte b = Strings.byteAt( filter, pos.start );
+        byte b = Strings.byteAt( filterBytes, pos.start );
 
         // Create a buffer big enough to contain the value once converted
-        byte[] value = new byte[filter.length - pos.start];
+        byte[] value = new byte[filterBytes.length - pos.start];
         int current = 0;
 
         do
@@ -381,13 +460,13 @@ public final class FilterParser
                 value[current++] = b;
                 pos.start++;
             }
-            else if ( Strings.isCharASCII( filter, pos.start, '\\' ) )
+            else if ( Strings.isCharASCII( filterBytes, pos.start, '\\' ) )
             {
                 // Maybe an escaped
                 pos.start++;
 
                 // First hex
-                if ( Chars.isHex( filter, pos.start ) )
+                if ( Chars.isHex( filterBytes, pos.start ) )
                 {
                     pos.start++;
                 }
@@ -397,9 +476,9 @@ public final class FilterParser
                 }
 
                 // second hex
-                if ( Chars.isHex( filter, pos.start ) )
+                if ( Chars.isHex( filterBytes, pos.start ) )
                 {
-                    value[current++] = Hex.getHexValue( filter[pos.start - 1], filter[pos.start] );
+                    value[current++] = Hex.getHexValue( filterBytes[pos.start - 1], filterBytes[pos.start] );
                     pos.start++;
                 }
                 else
@@ -413,7 +492,7 @@ public final class FilterParser
                 break;
             }
 
-            b = Strings.byteAt( filter, pos.start );
+            b = Strings.byteAt( filterBytes, pos.start );
         }
         while ( b != '\0' );
 
@@ -435,10 +514,9 @@ public final class FilterParser
      * Parse a substring
      */
     private static ExprNode parseSubstring( SchemaManager schemaManager, String attribute, Value initial,
-        byte[] filter, Position pos )
-        throws ParseException, LdapException
+        byte[] filterBytes, Position pos ) throws ParseException, LdapException
     {
-        if ( Strings.isCharASCII( filter, pos.start, '*' ) )
+        if ( Strings.isCharASCII( filterBytes, pos.start, '*' ) )
         {
             // We have found a '*' : this is a substring
             SubstringNode node = null;
@@ -465,7 +543,7 @@ public final class FilterParser
             {
                 // We have a substring starting with a value : val*...
                 // Set the initial value. It must be a String
-                String initialStr = initial.getString();
+                String initialStr = initial.getValue();
                 node.setInitial( initialStr );
             }
 
@@ -474,29 +552,29 @@ public final class FilterParser
             //
             while ( true )
             {
-                Value assertionValue = parseAssertionValue( schemaManager, attribute, filter, pos );
+                Value assertionValue = parseAssertionValue( schemaManager, attribute, filterBytes, pos );
 
                 // Is there anything else but a ')' after the value ?
-                if ( Strings.isCharASCII( filter, pos.start, ')' ) )
+                if ( Strings.isCharASCII( filterBytes, pos.start, ')' ) )
                 {
                     // Nope : as we have had [initial] '*' (any '*' ) *,
                     // this is the final
                     if ( !assertionValue.isNull() )
                     {
-                        String finalStr = assertionValue.getString();
+                        String finalStr = assertionValue.getValue();
                         node.setFinal( finalStr );
                     }
 
                     return node;
                 }
-                else if ( Strings.isCharASCII( filter, pos.start, '*' ) )
+                else if ( Strings.isCharASCII( filterBytes, pos.start, '*' ) )
                 {
                     // We have a '*' : it's an any
                     // If the value is empty, that means we have more than
                     // one consecutive '*' : do nothing in this case.
                     if ( !assertionValue.isNull() )
                     {
-                        String anyStr = assertionValue.getString();
+                        String anyStr = assertionValue.getValue();
                         node.addAny( anyStr );
                     }
 
@@ -541,18 +619,15 @@ public final class FilterParser
      * @param pos
      * @return
      */
-    @SuppressWarnings(
-        { "rawtypes", "unchecked" })
-    private static ExprNode parsePresenceEqOrSubstring( SchemaManager schemaManager, String attribute, byte[] filter,
-        Position pos )
-        throws ParseException, LdapException
+    private static ExprNode parsePresenceEqOrSubstring( SchemaManager schemaManager, String attribute, byte[] filterBytes,
+        Position pos ) throws ParseException, LdapException
     {
-        if ( Strings.isCharASCII( filter, pos.start, '*' ) )
+        if ( Strings.isCharASCII( filterBytes, pos.start, '*' ) )
         {
             // To be a present node, the next char should be a ')'
             pos.start++;
 
-            if ( Strings.isCharASCII( filter, pos.start, ')' ) )
+            if ( Strings.isCharASCII( filterBytes, pos.start, ')' ) )
             {
                 // This is a present node
                 if ( schemaManager != null )
@@ -578,10 +653,10 @@ public final class FilterParser
                 // Definitively a substring with no initial or an error
                 // Push back the '*' on the string
                 pos.start--;
-                return parseSubstring( schemaManager, attribute, null, filter, pos );
+                return parseSubstring( schemaManager, attribute, null, filterBytes, pos );
             }
         }
-        else if ( Strings.isCharASCII( filter, pos.start, ')' ) )
+        else if ( Strings.isCharASCII( filterBytes, pos.start, ')' ) )
         {
             // An empty equality Node
             if ( schemaManager != null )
@@ -600,16 +675,16 @@ public final class FilterParser
             }
             else
             {
-                return new EqualityNode( attribute, new Value( ( byte[] ) null ) );
+                return new EqualityNode( attribute, ( byte[] ) null );
             }
         }
         else
         {
             // A substring or an equality node
-            Value value = parseAssertionValue( schemaManager, attribute, filter, pos );
+            Value value = parseAssertionValue( schemaManager, attribute, filterBytes, pos );
 
             // Is there anything else but a ')' after the value ?
-            if ( Strings.isCharASCII( filter, pos.start, ')' ) )
+            if ( Strings.isCharASCII( filterBytes, pos.start, ')' ) )
             {
                 // This is an equality node
                 if ( schemaManager != null )
@@ -627,11 +702,11 @@ public final class FilterParser
                 }
                 else
                 {
-                    return new EqualityNode( attribute, value );
+                    return new EqualityNode( attribute, value.getValue() );
                 }
             }
 
-            return parseSubstring( schemaManager, attribute, value, filter, pos );
+            return parseSubstring( schemaManager, attribute, value, filterBytes, pos );
         }
     }
 
@@ -651,7 +726,7 @@ public final class FilterParser
      */
     @SuppressWarnings(
         { "rawtypes", "unchecked" })
-    private static ExprNode parseItem( SchemaManager schemaManager, byte[] filter, Position pos, byte b,
+    private static ExprNode parseItem( SchemaManager schemaManager, byte[] filterBytes, Position pos, byte b,
         boolean relaxed ) throws ParseException, LdapException
     {
         String attribute = null;
@@ -664,29 +739,29 @@ public final class FilterParser
         if ( b == ':' )
         {
             // If we have a colon, then the item is an extensible one
-            return parseExtensible( schemaManager, null, filter, pos, relaxed );
+            return parseExtensible( schemaManager, null, filterBytes, pos, relaxed );
         }
         else
         {
             // We must have an attribute
-            attribute = AttributeUtils.parseAttribute( filter, pos, true, relaxed );
+            attribute = AttributeUtils.parseAttribute( filterBytes, pos, true, relaxed );
 
             // Now, we may have a present, substring, simple or an extensible
-            b = Strings.byteAt( filter, pos.start );
+            b = Strings.byteAt( filterBytes, pos.start );
 
             switch ( b )
             {
                 case '=':
                     // It can be a presence, an equal or a substring
                     pos.start++;
-                    return parsePresenceEqOrSubstring( schemaManager, attribute, filter, pos );
+                    return parsePresenceEqOrSubstring( schemaManager, attribute, filterBytes, pos );
 
                 case '~':
                     // Approximate node
                     pos.start++;
 
                     // Check that we have a '='
-                    if ( !Strings.isCharASCII( filter, pos.start, '=' ) )
+                    if ( !Strings.isCharASCII( filterBytes, pos.start, '=' ) )
                     {
                         throw new ParseException( I18n.err( I18n.ERR_04152 ), pos.start );
                     }
@@ -696,8 +771,8 @@ public final class FilterParser
                     // Parse the value and create the node
                     if ( schemaManager == null )
                     {
-                        return new ApproximateNode( attribute, parseAssertionValue( schemaManager, attribute, filter,
-                            pos ) );
+                        return new ApproximateNode( attribute, parseAssertionValue( schemaManager, attribute, filterBytes,
+                            pos ).getBytes() );
                     }
                     else
                     {
@@ -706,7 +781,7 @@ public final class FilterParser
                         if ( attributeType != null )
                         {
                             return new ApproximateNode( attributeType, parseAssertionValue( schemaManager, attribute,
-                                filter, pos ) );
+                                filterBytes, pos ) );
                         }
                         else
                         {
@@ -719,7 +794,7 @@ public final class FilterParser
                     pos.start++;
 
                     // Check that we have a '='
-                    if ( !Strings.isCharASCII( filter, pos.start, '=' ) )
+                    if ( !Strings.isCharASCII( filterBytes, pos.start, '=' ) )
                     {
                         throw new ParseException( I18n.err( I18n.ERR_04152 ), pos.start );
                     }
@@ -730,7 +805,7 @@ public final class FilterParser
                     if ( schemaManager == null )
                     {
                         return new GreaterEqNode( attribute,
-                            parseAssertionValue( schemaManager, attribute, filter, pos ) );
+                            parseAssertionValue( schemaManager, attribute, filterBytes, pos ).getBytes() );
                     }
                     else
                     {
@@ -739,7 +814,7 @@ public final class FilterParser
                         if ( attributeType != null )
                         {
                             return new GreaterEqNode( attributeType, parseAssertionValue( schemaManager, attribute,
-                                filter, pos ) );
+                                filterBytes, pos ) );
                         }
                         else
                         {
@@ -752,7 +827,7 @@ public final class FilterParser
                     pos.start++;
 
                     // Check that we have a '='
-                    if ( !Strings.isCharASCII( filter, pos.start, '=' ) )
+                    if ( !Strings.isCharASCII( filterBytes, pos.start, '=' ) )
                     {
                         throw new ParseException( I18n.err( I18n.ERR_04152 ), pos.start );
                     }
@@ -762,7 +837,8 @@ public final class FilterParser
                     // Parse the value and create the node
                     if ( schemaManager == null )
                     {
-                        return new LessEqNode( attribute, parseAssertionValue( schemaManager, attribute, filter, pos ) );
+                        return new LessEqNode( attribute, 
+                            parseAssertionValue( schemaManager, attribute, filterBytes, pos ).getBytes() );
                     }
                     else
                     {
@@ -771,7 +847,7 @@ public final class FilterParser
                         if ( attributeType != null )
                         {
                             return new LessEqNode( attributeType, parseAssertionValue( schemaManager, attribute,
-                                filter, pos ) );
+                                filterBytes, pos ) );
                         }
                         else
                         {
@@ -782,7 +858,7 @@ public final class FilterParser
                 case ':':
                     // An extensible node
                     pos.start++;
-                    return parseExtensible( schemaManager, attribute, filter, pos, relaxed );
+                    return parseExtensible( schemaManager, attribute, filterBytes, pos, relaxed );
 
                 default:
                     // This is an error
@@ -802,14 +878,14 @@ public final class FilterParser
      *
      * @return
      */
-    private static ExprNode parseBranchNode( SchemaManager schemaManager, ExprNode node, byte[] filter, Position pos,
+    private static ExprNode parseBranchNode( SchemaManager schemaManager, ExprNode node, byte[] filterBytes, Position pos,
         boolean relaxed ) throws ParseException, LdapException
     {
         BranchNode branchNode = ( BranchNode ) node;
         int nbChildren = 0;
 
         // We must have at least one filter
-        ExprNode child = parseFilterInternal( schemaManager, filter, pos, relaxed );
+        ExprNode child = parseFilterInternal( schemaManager, filterBytes, pos, relaxed );
 
         if ( child != UndefinedNode.UNDEFINED_NODE )
         {
@@ -829,7 +905,7 @@ public final class FilterParser
         }
 
         // Now, iterate recusively though all the remaining filters, if any
-        while ( ( child = parseFilterInternal( schemaManager, filter, pos, relaxed ) ) != UndefinedNode.UNDEFINED_NODE )
+        while ( ( child = parseFilterInternal( schemaManager, filterBytes, pos, relaxed ) ) != UndefinedNode.UNDEFINED_NODE )
         {
             // Add the child to the node children if not null
             if ( child != null )
@@ -868,7 +944,7 @@ public final class FilterParser
      *                    / ( [dnattrs]
      *                         matchingrule COLON EQUALS assertionvalue )
      */
-    private static ExprNode parseFilterComp( SchemaManager schemaManager, byte[] filter, Position pos,
+    private static ExprNode parseFilterComp( SchemaManager schemaManager, byte[] filterBytes, Position pos,
         boolean relaxed ) throws ParseException, LdapException
     {
         ExprNode node = null;
@@ -878,34 +954,34 @@ public final class FilterParser
             throw new ParseException( I18n.err( I18n.ERR_04154 ), pos.start );
         }
 
-        byte c = Strings.byteAt( filter, pos.start );
+        byte b = Strings.byteAt( filterBytes, pos.start );
 
-        switch ( c )
+        switch ( b )
         {
             case '&':
                 // This is a AND node
                 pos.start++;
                 node = new AndNode();
-                node = parseBranchNode( schemaManager, node, filter, pos, relaxed );
+                node = parseBranchNode( schemaManager, node, filterBytes, pos, relaxed );
                 break;
 
             case '|':
                 // This is an OR node
                 pos.start++;
                 node = new OrNode();
-                node = parseBranchNode( schemaManager, node, filter, pos, relaxed );
+                node = parseBranchNode( schemaManager, node, filterBytes, pos, relaxed );
                 break;
 
             case '!':
                 // This is a NOT node
                 pos.start++;
                 node = new NotNode();
-                node = parseBranchNode( schemaManager, node, filter, pos, relaxed );
+                node = parseBranchNode( schemaManager, node, filterBytes, pos, relaxed );
                 break;
 
             default:
                 // This is an item
-                node = parseItem( schemaManager, filter, pos, c, relaxed );
+                node = parseItem( schemaManager, filterBytes, pos, b, relaxed );
                 break;
 
         }
@@ -915,14 +991,14 @@ public final class FilterParser
 
 
     /**
-     * Pasre the grammar rule :
+     * Parse the grammar rule :
      * filter ::= '(' filterComp ')'
      */
-    private static ExprNode parseFilterInternal( SchemaManager schemaManager, byte[] filter, Position pos,
+    private static ExprNode parseFilterInternal( SchemaManager schemaManager, byte[] filterBytes, Position pos,
         boolean relaxed ) throws ParseException, LdapException
     {
         // Check for the left '('
-        if ( !Strings.isCharASCII( filter, pos.start, '(' ) )
+        if ( !Strings.isCharASCII( filterBytes, pos.start, '(' ) )
         {
             // No more node, get out
             if ( ( pos.start == 0 ) && ( pos.length != 0 ) )
@@ -938,7 +1014,7 @@ public final class FilterParser
         pos.start++;
 
         // parse the filter component
-        ExprNode node = parseFilterComp( schemaManager, filter, pos, relaxed );
+        ExprNode node = parseFilterComp( schemaManager, filterBytes, pos, relaxed );
 
         if ( node == UndefinedNode.UNDEFINED_NODE )
         {
@@ -946,7 +1022,7 @@ public final class FilterParser
         }
 
         // Check that we have a right ')'
-        if ( !Strings.isCharASCII( filter, pos.start, ')' ) )
+        if ( !Strings.isCharASCII( filterBytes, pos.start, ')' ) )
         {
             throw new ParseException( I18n.err( I18n.ERR_04157 ), pos.start );
         }
@@ -955,109 +1031,4 @@ public final class FilterParser
 
         return node;
     }
-
-
-    /**
-     * Parses a search filter from it's string representation to an expression node object.
-     * 
-     * @param filter the search filter in it's string representation
-     * @return the expression node object
-     */
-    public static ExprNode parse( String filter ) throws ParseException
-    {
-        return parse( null, Strings.getBytesUtf8( filter ), false );
-    }
-
-
-    /**
-     * @see FilterParser#parse(String)
-     */
-    public static ExprNode parse( byte[] filter ) throws ParseException
-    {
-        return parse( null, filter, false );
-    }
-
-
-    /**
-     * @see FilterParser#parse(String)
-     */
-    public static ExprNode parse( SchemaManager schemaManager, String filter ) throws ParseException
-    {
-        return parse( schemaManager, Strings.getBytesUtf8( filter ), false );
-    }
-
-
-    /**
-     * @see FilterParser#parse(String)
-     */
-    public static ExprNode parse( SchemaManager schemaManager, byte[] filter ) throws ParseException
-    {
-        return parse( schemaManager, filter, false );
-    }
-
-
-    private static ExprNode parse( SchemaManager schemaManager, byte[] filter, boolean relaxed )
-        throws ParseException
-    {
-        // The filter must not be null. This is a defensive test
-        if ( Strings.isEmpty( filter ) )
-        {
-            throw new ParseException( I18n.err( I18n.ERR_04158 ), 0 );
-        }
-
-        Position pos = new Position();
-        pos.start = 0;
-        pos.end = 0;
-        pos.length = filter.length;
-
-        try
-        {
-            return parseFilterInternal( schemaManager, filter, pos, relaxed );
-        }
-        catch ( LdapException le )
-        {
-            throw new ParseException( le.getMessage(), pos.start );
-        }
-    }
-
-
-    /**
-     * @see FilterParser#parse(String)
-     */
-    public static ExprNode parse( SchemaManager schemaManager, String filter, Position pos ) throws ParseException
-    {
-        // The filter must not be null. This is a defensive test
-        if ( Strings.isEmpty( filter ) )
-        {
-            throw new ParseException( I18n.err( I18n.ERR_04158 ), 0 );
-        }
-
-        pos.start = 0;
-        pos.end = 0;
-        pos.length = filter.length();
-
-        try
-        {
-            return parseFilterInternal( schemaManager, Strings.getBytesUtf8( filter ), pos, false );
-        }
-        catch ( LdapException le )
-        {
-            throw new ParseException( le.getMessage(), pos.start );
-        }
-    }
-
-
-    /**
-     * Parses a search filter from it's string representation to an expression node object.
-     * 
-     * In <code>relaxed</code> mode the filter may violate RFC 4515, e.g. the underscore in attribute names is allowed.
-     * 
-     * @param filter the search filter in it's string representation
-     * @param relaxed <code>true</code> to parse the filter in relaxed mode
-     * @return the expression node object
-     */
-    public static ExprNode parse( String filter, boolean relaxed ) throws ParseException
-    {
-        return parse( null, Strings.getBytesUtf8( filter ), relaxed );
-    }
 }

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/GreaterEqNode.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/GreaterEqNode.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/GreaterEqNode.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/GreaterEqNode.java Mon May  9 17:22:19 2016
@@ -49,7 +49,19 @@ public class GreaterEqNode<T> extends Si
      * @param attribute the attribute name
      * @param value the value to test for
      */
-    public GreaterEqNode( String attribute, Value value )
+    public GreaterEqNode( String attribute, String value )
+    {
+        super( attribute, value, AssertionType.GREATEREQ );
+    }
+
+
+    /**
+     * Creates a new GreaterOrEqual object.
+     * 
+     * @param attribute the attribute name
+     * @param value the value to test for
+     */
+    public GreaterEqNode( String attribute, byte[] value )
     {
         super( attribute, value, AssertionType.GREATEREQ );
     }
@@ -76,8 +88,9 @@ public class GreaterEqNode<T> extends Si
 
         buf.append( ">=" );
 
-        Value escapedValue = getEscapedValue();
-        if ( !escapedValue.isNull() )
+        String escapedValue = getEscapedValue();
+        
+        if ( escapedValue != null )
         {
             buf.append( escapedValue );
         }

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/LeafNode.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/LeafNode.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/LeafNode.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/LeafNode.java Mon May  9 17:22:19 2016
@@ -21,6 +21,7 @@ package org.apache.directory.api.ldap.mo
 
 
 import org.apache.directory.api.ldap.model.schema.AttributeType;
+import org.apache.directory.api.util.Strings;
 
 
 /**
@@ -51,7 +52,6 @@ public abstract class LeafNode extends A
         if ( attributeType != null )
         {
             this.attribute = attributeType.getName();
-            isSchemaAware = true;
         }
         else
         {
@@ -71,7 +71,6 @@ public abstract class LeafNode extends A
         super( assertionType );
         this.attributeType = null;
         this.attribute = attribute;
-        isSchemaAware = false;
     }
 
 
@@ -120,7 +119,6 @@ public abstract class LeafNode extends A
         if ( attributeType != null )
         {
             attribute = attributeType.getName();
-            isSchemaAware = true;
         }
     }
 
@@ -133,7 +131,6 @@ public abstract class LeafNode extends A
     public void setAttribute( String attribute )
     {
         this.attribute = attribute;
-        isSchemaAware = false;
     }
 
 
@@ -158,6 +155,210 @@ public abstract class LeafNode extends A
 
 
     /**
+     * Tells if this Node is Schema aware.
+     * 
+     * @return true if the Node is SchemaAware
+     */
+    public boolean isSchemaAware()
+    {
+        return attributeType != null;
+    }
+    
+    
+    /**
+     * Escape a binary value into a String form that is accepted as a Filter
+     */
+    private static String escapeBytes( byte[] bytes )
+    {
+        // We have to escape all the bytes
+        char[] chars = new char[bytes.length * 3];
+        int pos = 0;
+        
+        for ( byte bb : bytes )
+        {
+            chars[pos++] = '\\';
+            chars[pos++] = Strings.dumpHex( ( byte ) ( bb >> 4 ) );
+            chars[pos++] = Strings.dumpHex( ( byte ) ( bb & 0x0F ) );
+        }
+        
+        return new String( chars, 0, pos );
+    }
+    
+    
+    /**
+     * Escape a String value into a String form that is accepted as a Filter
+     */
+    private static String escapeString( byte[] bytes )
+    {
+        StringBuilder sb = new StringBuilder( bytes.length );
+        
+        for ( byte b : bytes )
+        {
+            switch ( b )
+            {
+                case 0x20 : case 0x21 : case 0x22 : case 0x23 : case 0x24 : case 0x25 : case 0x26 : case 0x27 :
+                    sb.append( ( char ) b );
+                    break;
+                    
+                case 0x28 : 
+                    // '('
+                    sb.append( "\\28" );
+                    break;
+                    
+                case 0x29 :
+                    sb.append( "\\29" );
+                    // ')'
+                    break;
+                    
+                case 0x2A :
+                    // '*'
+                    sb.append( "\\2A" );
+                    break;
+                    
+                case 0x2B : case 0x2C : case 0x2D : case 0x2E : case 0x2F : 
+                case 0x30 : case 0x31 : case 0x32 : case 0x33 : case 0x34 : case 0x35 : case 0x36 : case 0x37 : 
+                case 0x38 : case 0x39 : case 0x3A : case 0x3B : case 0x3C : case 0x3D : case 0x3E : case 0x3F : 
+                case 0x40 : case 0x41 : case 0x42 : case 0x43 : case 0x44 : case 0x45 : case 0x46 : case 0x47 : 
+                case 0x48 : case 0x49 : case 0x4A : case 0x4B : case 0x4C : case 0x4D : case 0x4E : case 0x4F : 
+                case 0x50 : case 0x51 : case 0x52 : case 0x53 : case 0x54 : case 0x55 : case 0x56 : case 0x57 : 
+                case 0x58 : case 0x59 : case 0x5A : case 0x5B : 
+                    sb.append( ( char ) b );
+                    break;
+
+                case 0x5C :
+                    // '\' 
+                    sb.append( "\\5C" );
+                    break;
+                    
+                case 0x5D : case 0x5E : case 0x5F : 
+                case 0x60 : case 0x61 : case 0x62 : case 0x63 : case 0x64 : case 0x65 : case 0x66 : case 0x67 : 
+                case 0x68 : case 0x69 : case 0x6A : case 0x6B : case 0x6C : case 0x6D : case 0x6E : case 0x6F : 
+                case 0x70 : case 0x71 : case 0x72 : case 0x73 : case 0x74 : case 0x75 : case 0x76 : case 0x77 : 
+                case 0x78 : case 0x79 : case 0x7A : case 0x7B : case 0x7C : case 0x7D : case 0x7E : case 0x7F :
+                    sb.append( ( char ) b );
+                    break;
+                    
+                default : 
+                    // This is a binary value
+                    return null;
+            }
+        }
+        
+        return sb.toString();
+    }
+
+
+    /**
+     * Handles the escaping of special characters in LDAP search filter assertion values using the
+     * &lt;valueencoding&gt; rule as described in
+     * <a href="http://www.ietf.org/rfc/rfc4515.txt">RFC 4515</a>. Needed so that
+     * {@link ExprNode#printToBuffer(StringBuffer)} results in a valid filter string that can be parsed
+     * again (as a way of cloning filters).
+     *
+     * @param value Right hand side of "attrId=value" assertion occurring in an LDAP search filter.
+     * @return Escaped version of <code>value</code>
+     */
+    protected static String escapeFilterValue( AttributeType attributeType, byte[] value )
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+
+        if ( attributeType != null )
+        {
+            if ( attributeType.isHR() )
+            {
+                String result = escapeString( value );
+                
+                if ( result == null )
+                {
+                    return escapeBytes( value );
+                }
+                else
+                {
+                    return result;
+                }
+            }
+            else
+            {
+                return escapeBytes( value );
+            }
+        }
+        else
+        {
+            String result = escapeString( value );
+            
+            if ( result == null )
+            {
+                return escapeBytes( value );
+            }
+            else
+            {
+                return result;
+            }
+        }
+    }
+
+
+    /**
+     * Handles the escaping of special characters in LDAP search filter assertion values using the
+     * &lt;valueencoding&gt; rule as described in
+     * <a href="http://www.ietf.org/rfc/rfc4515.txt">RFC 4515</a>. Needed so that
+     * {@link ExprNode#printToBuffer(StringBuffer)} results in a valid filter string that can be parsed
+     * again (as a way of cloning filters).
+     *
+     * @param value Right hand side of "attrId=value" assertion occurring in an LDAP search filter.
+     * @return Escaped version of <code>value</code>
+     */
+    protected static String escapeFilterValue( String value )
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+        
+        StringBuilder sb = new StringBuilder( value.length() );
+        
+        for ( int i = 0; i < value.length(); i++ )
+        {
+            char c = value.charAt( i );
+            
+            switch ( c )
+            {
+                case 0x00:
+                    sb.append( "\\00" );
+                    break;
+                    
+                case '(' :
+                    sb.append( "\\28" );
+                    break;
+                    
+                case ')' :
+                    sb.append( "\\29" );
+                    break;
+                    
+                case '*' :
+                    sb.append( "\\2A" );
+                    break;
+                    
+                case '\\' :
+                    sb.append( "\\5C" );
+                    break;
+                    
+                default :
+                    sb.append( c );
+                    break;
+                    
+            }
+        }
+        
+        return sb.toString();
+    }
+
+
+
+    /**
      * @see Object#hashCode()
      * @return the instance's hash code 
      */

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/LessEqNode.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/LessEqNode.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/LessEqNode.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/LessEqNode.java Mon May  9 17:22:19 2016
@@ -49,7 +49,19 @@ public class LessEqNode<T> extends Simpl
      * @param attribute the attribute name
      * @param value the value to test for
      */
-    public LessEqNode( String attribute, Value value )
+    public LessEqNode( String attribute, byte[] value )
+    {
+        super( attribute, value, AssertionType.LESSEQ );
+    }
+
+
+    /**
+     * Creates a new LessEqNode object.
+     * 
+     * @param attribute the attribute name
+     * @param value the value to test for
+     */
+    public LessEqNode( String attribute, String value )
     {
         super( attribute, value, AssertionType.LESSEQ );
     }
@@ -76,8 +88,9 @@ public class LessEqNode<T> extends Simpl
 
         buf.append( "<=" );
 
-        Value escapedValue = getEscapedValue();
-        if ( !escapedValue.isNull() )
+        String escapedValue = getEscapedValue();
+        
+        if ( escapedValue != null )
         {
             buf.append( escapedValue );
         }

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/ObjectClassNode.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/ObjectClassNode.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/ObjectClassNode.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/ObjectClassNode.java Mon May  9 17:22:19 2016
@@ -19,7 +19,6 @@
  */
 package org.apache.directory.api.ldap.model.filter;
 
-
 /**
  * An empty class used for the (ObjectClass=*) node.
  *
@@ -63,6 +62,17 @@ public final class ObjectClassNode exten
     }
 
 
+    /**
+     * Tells if this Node is Schema aware.
+     * 
+     * @return true if the Node is SchemaAware
+     */
+    public boolean isSchemaAware()
+    {
+        return true;
+    }
+
+
     /**
      * {@inheritDoc}
      */

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/ScopeNode.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/ScopeNode.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/ScopeNode.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/ScopeNode.java Mon May  9 17:22:19 2016
@@ -60,7 +60,6 @@ public class ScopeNode extends AbstractE
         this.baseDn = baseDn;
         this.aliasDerefAliases = aliasDerefAliases;
         this.baseId = baseId;
-        isSchemaAware = true;
     }
 
 
@@ -140,6 +139,17 @@ public class ScopeNode extends AbstractE
     }
 
 
+    /**
+     * Tells if this Node is Schema aware.
+     * 
+     * @return true if the Node is SchemaAware
+     */
+    public boolean isSchemaAware()
+    {
+        return true;
+    }
+
+
     /**
      * {@inheritDoc}
      */

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/SimpleNode.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/SimpleNode.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/SimpleNode.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/SimpleNode.java Mon May  9 17:22:19 2016
@@ -20,10 +20,14 @@
 package org.apache.directory.api.ldap.model.filter;
 
 
+import java.util.Arrays;
+
 import org.apache.directory.api.i18n.I18n;
 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
 import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
+import org.apache.directory.api.util.Strings;
 
 
 /**
@@ -35,6 +39,9 @@ public abstract class SimpleNode<T> exte
 {
     /** the value */
     protected Value value;
+    
+    /** The value as a byte[] */
+    protected byte[] bytes;
 
     /** Constants for comparisons : > */
     public static final boolean EVAL_GREATER = true;
@@ -50,10 +57,73 @@ public abstract class SimpleNode<T> exte
      * @param value the value to test for
      * @param assertionType the type of assertion represented by this ExprNode
      */
-    protected SimpleNode( String attribute, Value value, AssertionType assertionType )
+    protected SimpleNode( String attribute, byte[] bytes, AssertionType assertionType )
     {
         super( attribute, assertionType );
-        this.value = value;
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * Creates a new SimpleNode object.
+     * 
+     * @param attribute the attribute name
+     * @param value the value to test for
+     * @param assertionType the type of assertion represented by this ExprNode
+     */
+    protected SimpleNode( AttributeType attributeType, byte[] bytes, AssertionType assertionType )
+    {
+        super( attributeType, assertionType );
+        this.bytes = bytes;
+        
+        try
+        {
+            if ( attributeType.isHR() )
+            {
+                value = new Value( attributeType, Strings.utf8ToString( bytes ) );
+            }
+            else
+            {
+                    value = new Value( attributeType, bytes );
+            }
+        }
+        catch ( LdapInvalidAttributeValueException e )
+        {
+            throw new RuntimeException( e.getMessage() );
+        }
+    }
+
+
+    /**
+     * Creates a new SimpleNode object.
+     * 
+     * @param attribute the attribute name
+     * @param value the value to test for
+     * @param assertionType the type of assertion represented by this ExprNode
+     */
+    protected SimpleNode( String attribute, String string, AssertionType assertionType )
+    {
+        super( attribute, assertionType );
+        bytes = Strings.getBytesUtf8( string );
+        
+        if ( attributeType != null )
+        {
+            try
+            {
+                if ( attributeType.isHR() )
+                {
+                    value = new Value( attributeType, string );
+                }
+                else
+                {
+                    value = new Value( attributeType, bytes );
+                }
+            }
+            catch ( LdapInvalidAttributeValueException e )
+            {
+                throw new RuntimeException( e.getMessage() );
+            }
+        }
     }
 
 
@@ -80,8 +150,20 @@ public abstract class SimpleNode<T> exte
     {
         ExprNode clone = super.clone();
 
-        // Clone the value
-        ( ( SimpleNode<T> ) clone ).value = value.clone();
+        // Clone the value, if we have one
+        if ( value != null )
+        {
+            ( ( SimpleNode<T> ) clone ).value = value.clone();
+        }
+        else
+        {
+            // clone the bytes if any
+            if ( bytes != null )
+            {
+                ( ( SimpleNode<T> ) clone ).bytes = new byte[bytes.length];
+                System.arraycopy( bytes, 0, ( ( SimpleNode<T> ) clone ).bytes, 0, bytes.length );
+            }
+        }
 
         return clone;
     }
@@ -94,16 +176,30 @@ public abstract class SimpleNode<T> exte
      */
     public final Value getValue()
     {
-        return value;
+        if ( value == null )
+        {
+            return new Value( bytes );
+        }
+        else
+        {
+            return value;
+        }
     }
 
 
     /** 
      * @return representation of value, escaped for use in a filter if required 
      */
-    public Value getEscapedValue()
+    public String getEscapedValue()
     {
-        return escapeFilterValue( value );
+        if ( value != null )
+        {
+            return escapeFilterValue( value.getAttributeType(), bytes );
+        }
+        else
+        {
+            return escapeFilterValue( null, bytes );
+        }
     }
 
 
@@ -115,6 +211,7 @@ public abstract class SimpleNode<T> exte
     public void setValue( Value value )
     {
         this.value = value;
+        this.bytes = value.getBytes();
     }
 
 
@@ -148,7 +245,7 @@ public abstract class SimpleNode<T> exte
      */
     public StringBuilder printRefinementToBuffer( StringBuilder buf )
     {
-        if ( isSchemaAware )
+        if ( isSchemaAware() )
         {
             if ( !attributeType.getOid().equals( SchemaConstants.OBJECT_CLASS_AT_OID ) )
             {
@@ -215,7 +312,14 @@ public abstract class SimpleNode<T> exte
 
         if ( value == null )
         {
-            return otherNode.value == null;
+            if ( bytes == null )
+            {
+                return otherNode.bytes == null;
+            }
+            else
+            {
+                return Arrays.equals( bytes,  otherNode.bytes );
+            }
         }
         else
         {

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/SubstringNode.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/SubstringNode.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/SubstringNode.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/SubstringNode.java Mon May  9 17:22:19 2016
@@ -25,7 +25,6 @@ import java.util.List;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
-import org.apache.directory.api.ldap.model.entry.Value;
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
 import org.apache.directory.api.ldap.model.schema.Normalizer;
@@ -452,7 +451,7 @@ public class SubstringNode extends LeafN
 
         if ( null != initialPattern )
         {
-            buf.append( escapeFilterValue( new Value( initialPattern ) ) ).append( '*' );
+            buf.append( escapeFilterValue( initialPattern ) ).append( '*' );
         }
         else
         {
@@ -463,14 +462,14 @@ public class SubstringNode extends LeafN
         {
             for ( String any : anyPattern )
             {
-                buf.append( escapeFilterValue( new Value( any ) ) );
+                buf.append( escapeFilterValue( any ) );
                 buf.append( '*' );
             }
         }
 
         if ( null != finalPattern )
         {
-            buf.append( escapeFilterValue( new Value( finalPattern ) ) );
+            buf.append( escapeFilterValue( finalPattern ) );
         }
 
         buf.append( super.toString() );

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/UndefinedNode.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/UndefinedNode.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/UndefinedNode.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/filter/UndefinedNode.java Mon May  9 17:22:19 2016
@@ -19,7 +19,6 @@
  */
 package org.apache.directory.api.ldap.model.filter;
 
-
 /**
  * An empty class used for Undefined Nodes.
  *
@@ -63,6 +62,17 @@ public final class UndefinedNode extends
     }
 
 
+    /**
+     * Tells if this Node is Schema aware.
+     * 
+     * @return true if the Node is SchemaAware
+     */
+    public boolean isSchemaAware()
+    {
+        return false;
+    }
+
+
     /**
      * {@inheritDoc}
      */

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/LdifRevertor.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/LdifRevertor.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/LdifRevertor.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/LdifRevertor.java Mon May  9 17:22:19 2016
@@ -327,7 +327,7 @@ public final class LdifRevertor
         // Is the newRdn's value present in the entry ?
         // ( case 3, 4 and 5)
         // If keepOldRdn = true, we cover case 4 and 5
-        boolean keepOldRdn = entry.contains( newRdn.getNormType(), newRdn.getNormValue() );
+        boolean keepOldRdn = entry.contains( newRdn.getNormType(), newRdn.getValue() );
 
         reverted.setDeleteOldRdn( !keepOldRdn );
 
@@ -359,13 +359,13 @@ public final class LdifRevertor
         {
             // No need to add something which has already been added
             // in the previous modification
-            if ( !entry.contains( ava.getNormType(), ava.getValue().getString() )
-                && !( ava.getNormType().equals( oldRdn.getNormType() ) && ava.getValue().getString().equals(
-                    oldRdn.getNormValue() ) ) )
+            if ( !entry.contains( ava.getNormType(), ava.getValue().getValue() )
+                && !( ava.getNormType().equals( oldRdn.getNormType() ) && ava.getValue().getValue().equals(
+                    oldRdn.getValue() ) ) )
             {
                 // Create the modification, which is an Remove
                 Modification modification = new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE,
-                    new DefaultAttribute( ava.getType(), ava.getValue().getString() ) );
+                    new DefaultAttribute( ava.getType(), ava.getValue().getValue() ) );
 
                 restored.addModification( modification );
             }
@@ -493,7 +493,7 @@ public final class LdifRevertor
                 for ( Ava atav : newRdn )
                 {
                     if ( !atav.equals( oldRdn.getAva() )
-                        && ( entry.contains( atav.getNormType(), atav.getValue().getString() ) ) )
+                        && ( entry.contains( atav.getNormType(), atav.getValue().getValue() ) ) )
                     {
                         existInEntry = true;
                     }
@@ -546,7 +546,7 @@ public final class LdifRevertor
                     {
                         overlapping = true;
                     }
-                    else if ( entry.contains( atav.getNormType(), atav.getValue().getString() ) )
+                    else if ( entry.contains( atav.getNormType(), atav.getValue().getValue() ) )
                     {
                         existInEntry = true;
                     }

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/LdifUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/LdifUtils.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/LdifUtils.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/LdifUtils.java Mon May  9 17:22:19 2016
@@ -160,7 +160,7 @@ public final class LdifUtils
         }
 
         // The String cannot end with a space
-        return ( currentChar != ' ' );
+        return currentChar != ' ';
     }
 
 
@@ -276,10 +276,12 @@ public final class LdifUtils
      */
     public static Attributes getJndiAttributesFromLdif( String ldif ) throws LdapLdifException
     {
-        LdifAttributesReader reader = new LdifAttributesReader();
+        LdifAttributesReader reader;
 
         try
         {
+            reader = new LdifAttributesReader();
+            
             Attributes attributes = AttributeUtils.toAttributes( reader.parseEntry( ldif ) );
 
             reader.close();
@@ -288,7 +290,7 @@ public final class LdifUtils
         }
         catch ( IOException ioe )
         {
-            throw new LdapLdifException( ioe.getMessage() );
+            throw new LdapLdifException( ioe.getMessage(), ioe );
         }
     }
 
@@ -595,7 +597,7 @@ public final class LdifUtils
             else if ( value.isHumanReadable() )
             {
                 // It's a String but, we have to check if encoding isn't required
-                String str = value.getString();
+                String str = value.getValue();
 
                 if ( !LdifUtils.isLDIFSafe( str ) )
                 {
@@ -716,7 +718,7 @@ public final class LdifUtils
                 if ( !( ava instanceof String ) )
                 {
                     throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err(
-                        I18n.ERR_12085, ( pos + 1 ) ) );
+                        I18n.ERR_12085, pos + 1 ) );
                 }
 
                 String attribute = ( String ) ava;
@@ -746,7 +748,7 @@ public final class LdifUtils
                 else
                 {
                     throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err(
-                        I18n.ERR_12086, ( pos + 1 ) ) );
+                        I18n.ERR_12086, pos + 1 ) );
                 }
 
                 valueExpected = false;
@@ -759,18 +761,18 @@ public final class LdifUtils
                 .err( I18n.ERR_12087 ) );
         }
 
-        LdifAttributesReader reader = new LdifAttributesReader();
-        Attributes attributes = AttributeUtils.toAttributes( reader.parseEntry( sb.toString() ) );
-
         try
         {
+            LdifAttributesReader reader = new LdifAttributesReader();
+            Attributes attributes = AttributeUtils.toAttributes( reader.parseEntry( sb.toString() ) );
+    
             reader.close();
+
+            return attributes;
         }
-        catch ( IOException e )
+        catch ( IOException ioe )
         {
-            e.printStackTrace();
+            throw new LdapLdifException( ioe.getMessage(), ioe );
         }
-
-        return attributes;
     }
 }

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/CaseSensitiveStringAnonymizer.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/CaseSensitiveStringAnonymizer.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/CaseSensitiveStringAnonymizer.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/CaseSensitiveStringAnonymizer.java Mon May  9 17:22:19 2016
@@ -99,7 +99,7 @@ public class CaseSensitiveStringAnonymiz
                 }
                 else
                 {
-                    String strValue = value.getNormValue();
+                    String strValue = value.getValue();
                     String newValue = computeNewValue( strValue );
                     
                     try

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/IntegerAnonymizer.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/IntegerAnonymizer.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/IntegerAnonymizer.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/IntegerAnonymizer.java Mon May  9 17:22:19 2016
@@ -94,7 +94,7 @@ public class IntegerAnonymizer extends A
                 }
                 else
                 {
-                    String strValue = value.getNormValue().toString();
+                    String strValue = value.getValue().toString();
                     String newValue = computeNewIntegerValue( strValue );
     
                     try

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/StringAnonymizer.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/StringAnonymizer.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/StringAnonymizer.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/anonymizer/StringAnonymizer.java Mon May  9 17:22:19 2016
@@ -99,7 +99,7 @@ public class StringAnonymizer extends Ab
                 }
                 else
                 {
-                    String strValue = value.getNormValue().toString();
+                    String strValue = value.getValue().toString();
                     String newValue = computeNewValue( strValue );
                     
                     try

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/message/BindRequestImpl.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/message/BindRequestImpl.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/message/BindRequestImpl.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/message/BindRequestImpl.java Mon May  9 17:22:19 2016
@@ -464,7 +464,7 @@ public class BindRequestImpl extends Abs
         sb.append( "    BindRequest\n" );
         sb.append( "        Version : '" ).append( isVersion3 ? "3" : "2" ).append( "'\n" );
 
-        if ( ( ( Strings.isEmpty( name ) ) || ( dn == null ) || Strings.isEmpty( dn.getNormName() ) )
+        if ( ( ( Strings.isEmpty( name ) ) || ( dn == null ) || dn.equals( Dn.EMPTY_DN ) )
             && isSimple )
         {
             sb.append( "        Name : anonymous\n" );

Modified: directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/message/SearchRequestImpl.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/message/SearchRequestImpl.java?rev=1743011&r1=1743010&r2=1743011&view=diff
==============================================================================
--- directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/message/SearchRequestImpl.java (original)
+++ directory/shared/branches/shared-value/ldap/model/src/main/java/org/apache/directory/api/ldap/model/message/SearchRequestImpl.java Mon May  9 17:22:19 2016
@@ -32,7 +32,6 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.filter.ExprNode;
 import org.apache.directory.api.ldap.model.filter.FilterParser;
 import org.apache.directory.api.ldap.model.name.Dn;
-import org.apache.directory.api.util.Strings;
 
 
 /**
@@ -169,7 +168,7 @@ public class SearchRequestImpl extends A
     {
         try
         {
-            filterNode = FilterParser.parse( Strings.getBytesUtf8( filter ) );
+            filterNode = FilterParser.parse( filter );
         }
         catch ( ParseException pe )
         {