directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r580525 - in /directory/shared/trunk/ldap/src: main/antlr/ main/java/org/apache/directory/shared/ldap/codec/util/ main/java/org/apache/directory/shared/ldap/filter/ test/java/org/apache/directory/shared/ldap/filter/ test/java/org/apache/dir...
Date Sat, 29 Sep 2007 01:10:32 GMT
Author: elecharny
Date: Fri Sep 28 18:10:31 2007
New Revision: 580525

URL: http://svn.apache.org/viewvc?rev=580525&view=rev
Log:
Added some missing classes, and renamed the FastFilterParserImpl to FilterParser
Removed some useless grammar files

Added:
    directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParser.java
    directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/filter/FilterParserTest.java
Removed:
    directory/shared/trunk/ldap/src/main/antlr/filter-lexer.g
    directory/shared/trunk/ldap/src/main/antlr/filter-parser.g
    directory/shared/trunk/ldap/src/main/antlr/filter-value-lexer.g
    directory/shared/trunk/ldap/src/main/antlr/filter-value-parser.g
Modified:
    directory/shared/trunk/ldap/src/main/antlr/ACIItem.g
    directory/shared/trunk/ldap/src/main/antlr/SubtreeSpecificationChecker.g
    directory/shared/trunk/ldap/src/main/antlr/subtree-specification.g
    directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/util/LdapURL.java
    directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/filter/BranchNormalizedVisitor.java
    directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/filter/BranchNormalizedVisitorTest.java
    directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/subtree/SubtreeSpecificationParserTest.java

Modified: directory/shared/trunk/ldap/src/main/antlr/ACIItem.g
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/antlr/ACIItem.g?rev=580525&r1=580524&r2=580525&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/main/antlr/ACIItem.g (original)
+++ directory/shared/trunk/ldap/src/main/antlr/ACIItem.g Fri Sep 28 18:10:31 2007
@@ -41,7 +41,7 @@
 import org.apache.directory.shared.ldap.filter.ExprNode;
 import org.apache.directory.shared.ldap.filter.LeafNode;
 import org.apache.directory.shared.ldap.filter.EqualityNode;
-import org.apache.directory.shared.ldap.filter.FastFilterParserImpl;
+import org.apache.directory.shared.ldap.filter.FilterParser;
 import org.apache.directory.shared.ldap.message.AttributeImpl;
 import org.apache.directory.shared.ldap.name.NameComponentNormalizer;
 import org.apache.directory.shared.ldap.subtree.SubtreeSpecification;
@@ -540,7 +540,7 @@
     {
         protectedItemsMap.put( "rangeOfValues",
                 new ProtectedItem.RangeOfValues(
-                        FastFilterParserImpl.parse( token.getText() ) ) );
+                        FilterParser.parse( token.getText() ) ) );
         log.debug( "filterParser parsed " + token.getText() );
     }
     ;

Modified: directory/shared/trunk/ldap/src/main/antlr/SubtreeSpecificationChecker.g
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/antlr/SubtreeSpecificationChecker.g?rev=580525&r1=580524&r2=580525&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/main/antlr/SubtreeSpecificationChecker.g (original)
+++ directory/shared/trunk/ldap/src/main/antlr/SubtreeSpecificationChecker.g Fri Sep 28 18:10:31 2007
@@ -24,7 +24,7 @@
 package org.apache.directory.shared.ldap.subtree;
 
 import org.apache.directory.shared.ldap.name.LdapDN;
-import org.apache.directory.shared.ldap.filter.FastFilterParserImpl;
+import org.apache.directory.shared.ldap.filter.FilterParser;
 import org.apache.directory.shared.ldap.util.ComponentsMonitor;
 import org.apache.directory.shared.ldap.util.OptionalComponentsMonitor;
 
@@ -239,7 +239,7 @@
 	log.debug( "entered filter()" );
 }
 	:
-	( filterToken:FILTER { FastFilterParserImpl.parse( filterToken.getText() ); } )
+	( filterToken:FILTER { FilterParser.parse( filterToken.getText() ); } )
 	;
 	exception
     catch [Exception e]

Modified: directory/shared/trunk/ldap/src/main/antlr/subtree-specification.g
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/antlr/subtree-specification.g?rev=580525&r1=580524&r2=580525&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/main/antlr/subtree-specification.g (original)
+++ directory/shared/trunk/ldap/src/main/antlr/subtree-specification.g Fri Sep 28 18:10:31 2007
@@ -37,7 +37,7 @@
 import org.apache.directory.shared.ldap.filter.OrNode;
 import org.apache.directory.shared.ldap.filter.NotNode;
 import org.apache.directory.shared.ldap.filter.EqualityNode;
-import org.apache.directory.shared.ldap.filter.FastFilterParserImpl;
+import org.apache.directory.shared.ldap.filter.FilterParser;
 import org.apache.directory.shared.ldap.subtree.SubtreeSpecification;
 import org.apache.directory.shared.ldap.subtree.SubtreeSpecificationModifier;
 import org.apache.directory.shared.ldap.schema.NormalizerMappingResolver;
@@ -321,7 +321,7 @@
 	log.debug( "entered filter()" );
 }
 	:
-	( filterToken:FILTER { filterExpr=FastFilterParserImpl.parse( filterToken.getText() ); } )
+	( filterToken:FILTER { filterExpr=FilterParser.parse( filterToken.getText() ); } )
 	;
 	exception
     catch [Exception e]

Modified: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/util/LdapURL.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/util/LdapURL.java?rev=580525&r1=580524&r2=580525&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/util/LdapURL.java (original)
+++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/util/LdapURL.java Fri Sep 28 18:10:31 2007
@@ -21,7 +21,7 @@
 
 
 import org.apache.directory.shared.asn1.codec.DecoderException;
-import org.apache.directory.shared.ldap.filter.FastFilterParserImpl;
+import org.apache.directory.shared.ldap.filter.FilterParser;
 import org.apache.directory.shared.ldap.name.LdapDN;
 import org.apache.directory.shared.ldap.util.StringTools;
 
@@ -903,7 +903,7 @@
         try
         {
             filter = decode( new String( chars, pos, end - pos ) );
-            FastFilterParserImpl.parse( filter );
+            FilterParser.parse( filter );
         }
         catch ( URIException ue )
         {

Modified: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/filter/BranchNormalizedVisitor.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/filter/BranchNormalizedVisitor.java?rev=580525&r1=580524&r2=580525&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/filter/BranchNormalizedVisitor.java (original)
+++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/filter/BranchNormalizedVisitor.java Fri Sep 28 18:10:31 2007
@@ -126,7 +126,7 @@
      */
     public static String getNormalizedFilter( String filter ) throws IOException, ParseException
     {
-        ExprNode originalNode = FastFilterParserImpl.parse( filter );
+        ExprNode originalNode = FilterParser.parse( filter );
 
         return getNormalizedFilter( originalNode );
     }

Added: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParser.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParser.java?rev=580525&view=auto
==============================================================================
--- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParser.java (added)
+++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParser.java Fri Sep 28 18:10:31 2007
@@ -0,0 +1,660 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.shared.ldap.filter;
+
+
+import java.text.ParseException;
+
+import org.apache.directory.shared.ldap.util.AttributeUtils;
+import org.apache.directory.shared.ldap.util.Position;
+import org.apache.directory.shared.ldap.util.StringTools;
+
+
+public class FilterParser
+{
+    /**
+     * Creates a filter parser implementation.
+     */
+    public FilterParser()
+    {
+    }
+    
+    /**
+     * Parse an extensible
+     * 
+     * extensible     = ( attr [":dn"] [':' oid] ":=" assertionvalue )
+     *                  / ( [":dn"] ':' oid ":=" assertionvalue )
+     * matchingrule   = ":" oid
+     */
+    private static ExprNode parseExtensible( String attr, String filter, Position pos ) throws ParseException
+    {
+        ExtensibleNode node = new ExtensibleNode( attr );
+
+        if ( attr != null )
+        {
+            // First check if we have a ":dn"
+            if ( StringTools.areEquals( filter, pos.start, "dn" ) )
+            {
+                // Set the dnAttributes flag and move forward in the string
+                node.setDnAttributes( true );
+                pos.start += 2;
+            }
+            else
+            {
+                // Push back the ':' 
+                pos.start--;
+            }
+            
+            // Do we have a MatchingRule ?
+            if ( StringTools.charAt( filter, pos.start ) == ':' )
+            {
+                pos.start++;
+                int start = pos.start;
+                
+                if ( StringTools.charAt( filter, pos.start ) == '=' )
+                {
+                    pos.start++;
+                    
+                    // Get the assertionValue
+                    node.setValue( parseAssertionValue( filter, pos ) );
+                    
+                    return node;
+                }
+                else
+                {
+                    AttributeUtils.parseAttribute( filter, pos, false );
+                    
+                    node.setMatchingRuleId( filter.substring( start, pos.start ) );
+                    
+                    if ( StringTools.areEquals( filter, pos.start, ":=" ) )
+                    {
+                        pos.start += 2;
+                        
+                        // Get the assertionValue
+                        node.setValue( parseAssertionValue( filter, pos ) );
+                        
+                        return node;
+                    }
+                    else
+                    {
+                        throw new ParseException( "AssertionValue expected", pos.start );
+                    }
+                }
+            }
+            else
+            {
+                throw new ParseException( "Expected MatchingRule or assertionValue", pos.start );
+            }
+        }
+        else
+        {
+            boolean oidRequested = false;
+            
+            // First check if we have a ":dn"
+            if ( StringTools.areEquals( filter, pos.start, ":dn" ) )
+            {
+                // Set the dnAttributes flag and move forward in the string
+                node.setDnAttributes( true );
+                pos.start += 3;
+            }
+            else
+            {
+                oidRequested = true;
+            }
+            
+            // Do we have a MatchingRule ?
+            if ( StringTools.charAt( filter, pos.start ) == ':' )
+            {
+                pos.start++;
+                int start = pos.start;
+                
+                if ( StringTools.charAt( filter, pos.start ) == '=' )
+                {
+                    if ( oidRequested )
+                    {
+                        throw new ParseException( "MatchingRule expected", pos.start );
+                    }
+                    
+                    pos.start++;
+                    
+                    // Get the assertionValue
+                    node.setValue( parseAssertionValue( filter, pos ) );
+                    
+                    return node;
+                }
+                else
+                {
+                    AttributeUtils.parseAttribute( filter, pos, false );
+                    
+                    node.setMatchingRuleId( filter.substring( start, pos.start ) );
+                    
+                    if ( StringTools.areEquals( filter, pos.start, ":=" ) )
+                    {
+                        pos.start += 2;
+                        
+                        // Get the assertionValue
+                        node.setValue( parseAssertionValue( filter, pos ) );
+                        
+                        return node;
+                    }
+                    else
+                    {
+                        throw new ParseException( "AssertionValue expected", pos.start );
+                    }
+                }
+            }
+            else
+            {
+                throw new ParseException( "Expected MatchingRule or assertionValue", pos.start );
+            }
+        }
+    }
+    
+    
+    /**
+     * An assertion value : 
+     * assertionvalue = valueencoding
+     * valueencoding  = 0*(normal / escaped)
+     * normal         = UTF1SUBSET / UTFMB
+     * escaped        = '\' HEX HEX
+     * HEX            = '0'-'9' / 'A'-'F' / 'a'-'f'
+     * UTF1SUBSET     = %x01-27 / %x2B-5B / %x5D-7F (Everything but '\0', '*', '(', ')' and '\')
+     * UTFMB          = UTF2 / UTF3 / UTF4
+     * UTF0           = %x80-BF
+     * UTF2           = %xC2-DF UTF0
+     * UTF3           = %xE0 %xA0-BF UTF0 / %xE1-EC UTF0 UTF0 / %xED %x80-9F UTF0 / %xEE-EF UTF0 UTF0
+     * UTF4           = %xF0 %x90-BF UTF0 UTF0 / %xF1-F3 UTF0 UTF0 UTF0 / %xF4 %x80-8F UTF0 UTF0
+     * 
+     * With the specific constraints (RFC 4515):
+     *    "The <valueencoding> rule ensures that the entire filter string is a"
+     *    "valid UTF-8 string and provides that the octets that represent the"
+     *    "ASCII characters "*" (ASCII 0x2a), "(" (ASCII 0x28), ")" (ASCII"
+     *    "0x29), "\" (ASCII 0x5c), and NUL (ASCII 0x00) are represented as a"
+     *    "backslash "\" (ASCII 0x5c) followed by the two hexadecimal digits"
+     *    "representing the value of the encoded octet."
+
+     * 
+     * The incomming String is already transformed from UTF-8 to unicode, so we must assume that the 
+     * grammar we have to check is the following :
+     * 
+     * assertionvalue = valueencoding
+     * valueencoding  = 0*(normal / escaped)
+     * normal         = unicodeSubset
+     * escaped        = '\' HEX HEX
+     * HEX            = '0'-'9' / 'A'-'F' / 'a'-'f'
+     * unicodeSubset     = %x01-27 / %x2B-5B / %x5D-FFFF
+     */
+    private static String parseAssertionValue( String filter, Position pos ) throws ParseException
+    {
+        int start = pos.start;
+        
+        char c = StringTools.charAt( filter, pos.start );
+        
+        do
+        {
+            if ( StringTools.isUnicodeSubset( c ) )
+            {
+                pos.start++;
+            }
+            else if ( StringTools.isCharASCII( filter, pos.start, '\\' ) )
+            {
+                // Maybe an escaped 
+                pos.start++;
+                
+                // First hex
+                if ( StringTools.isHex( filter, pos.start ) )
+                {
+                    pos.start++;
+                }
+                else
+                {
+                    throw new ParseException( "Not a valid escaped value", pos.start );
+                }
+
+                // second hex
+                if ( StringTools.isHex( filter, pos.start ) )
+                {
+                    pos.start++;
+                }
+                else
+                {
+                    throw new ParseException( "Not a valid escaped value", pos.start );
+                }
+            }
+            else
+            {
+                // not a valid char, so let's get out
+                return filter.substring( start, pos.start );
+            }
+        } while ( ( c = StringTools.charAt( filter, pos.start ) ) != '\0' );
+        
+        return filter.substring( start, pos.start );
+    }
+
+    /**
+     * Parse a substring
+     */
+    private static ExprNode parseSubstring( String attr, String initial, String filter, Position pos ) throws ParseException
+    {
+        if ( StringTools.isCharASCII( filter, pos.start, '*' ) )
+        {
+            // We have found a '*' : this is a substring
+            SubstringNode node = new SubstringNode( attr );
+            
+            if ( !StringTools.isEmpty( initial ) )
+            {
+                // We have a substring starting with a value : val*...
+                // Set the initial value
+                node.setInitial( initial );
+            }
+            
+            pos.start++;
+            
+            // 
+            while ( true )
+            {
+                String assertionValue = parseAssertionValue( filter, pos );
+                
+                // Is there anything else but a ')' after the value ?
+                if ( StringTools.isCharASCII( filter, pos.start, ')' ) )
+                {
+                    // Nope : as we have had [initial] '*' (any '*' ) *,
+                    // this is the final
+                    if ( !StringTools.isEmpty( assertionValue ) )
+                    {
+                        node.setFinal( assertionValue );
+                    }
+
+                    return node;
+                }
+                else if ( StringTools.isCharASCII( filter, 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 ( !StringTools.isEmpty( assertionValue ) )
+                    {
+                        node.addAny( assertionValue );
+                    }
+                    
+                    pos.start++;
+                }
+            } 
+        }
+        else
+        {
+            // This is an error
+            throw new ParseException( "Bad substring", pos.start );
+        }
+    }
+    
+    /**
+     * Here is the grammar to parse :
+     * 
+     * simple    ::= '=' assertionValue
+     * present   ::= '=' '*'
+     * substring ::= '=' [initial] any [final]
+     * initial   ::= assertionValue
+     * any       ::= '*' ( assertionValue '*')*
+     * 
+     * As we can see, there is an ambiguity in the grammar : attr=* can be
+     * seen as a present or as a substring. As stated in the RFC :
+     * 
+     * "Note that although both the <substring> and <present> productions in"
+     * "the grammar above can produce the "attr=*" construct, this construct"
+     * "is used only to denote a presence filter." (RFC 4515, 3)
+     * 
+     * We have also to consider the difference between a substring and the
+     * equality node : this last node does not contain a '*'
+     *
+     * @param attr
+     * @param filter
+     * @param pos
+     * @return
+     */
+    private static ExprNode parsePresenceEqOrSubstring( String attr, String filter, Position pos ) throws ParseException
+    {
+        if ( StringTools.isCharASCII( filter, pos.start, '*' ) )
+        {
+            // To be a present node, the next char should be a ')'
+            //StringTools.trimLeft( filter, pos );
+            pos.start++;
+
+            if ( StringTools.isCharASCII( filter, pos.start, ')' ) )
+            {
+                // This is a present node
+                return new PresenceNode( attr );
+            }
+            else
+            {
+                // Definitively a substring with no initial or an error
+                // Push back the '*' on the string
+                pos.start--;
+                return parseSubstring( attr, null, filter, pos );
+            }
+        }
+        else if ( StringTools.isCharASCII( filter, pos.start, ')' ) )
+        {
+            // An empty equality Node
+            return new EqualityNode( attr, "" );
+        }
+        else
+        {
+            // A substring or an equality node
+            String value = parseAssertionValue( filter, pos );
+            
+            // Is there anything else but a ')' after the value ?
+            if ( StringTools.isCharASCII( filter, pos.start, ')' ) )
+            {
+                // This is an equality node
+                return new EqualityNode( attr, value );
+            }
+            
+            return parseSubstring( attr, value, filter, pos );
+        }
+    }
+    
+    
+    /**
+     * Parse the following grammar :
+     * item           = simple / present / substring / extensible
+     * simple         = attr filtertype assertionvalue
+     * filtertype     = '=' / '~=' / '>=' / '<='
+     * present        = attr '=' '*'
+     * substring      = attr '=' [initial] any [final]
+     * extensible     = ( attr [":dn"] [':' oid] ":=" assertionvalue )
+     *                  / ( [":dn"] ':' oid ":=" assertionvalue )
+     * matchingrule   = ":" oid
+     *                  
+     * An item starts with an attribute or a colon.
+     */
+    private static ExprNode parseItem( String filter, Position pos, char c ) throws ParseException
+    {
+        LeafNode node = null;
+        String attr = null;
+        
+        // Relax the grammar a bit : we can have spaces 
+        // StringTools.trimLeft( filter, pos );
+        
+        if ( c == '\0' )
+        {
+            throw new ParseException( "Bad char", pos.start );
+        }
+        
+        if ( c == ':' )
+        {
+            // If we have a colon, then the item is an extensible one
+            return parseExtensible( null, filter, pos );
+        }
+        else
+        {
+            // We must have an attribute
+            attr = AttributeUtils.parseAttribute( filter, pos, true );
+            
+            // Relax the grammar a bit : we can have spaces 
+            // StringTools.trimLeft( filter, pos );
+
+            // Now, we may have a present, substring, simple or an extensible
+            c = StringTools.charAt( filter, pos.start );
+            
+            switch ( c )
+            {
+                case '=' :
+                    // It can be a presence, an equal or a substring
+                    pos.start++;
+                    return parsePresenceEqOrSubstring( attr, filter, pos );
+                    
+                case '~' :
+                    // Approximate node
+                    pos.start++;
+                    
+                    // Check that we have a '='
+                    if ( !StringTools.isCharASCII( filter, pos.start, '=' ) )
+                    {
+                        throw new ParseException( "Expecting a '=' ", pos.start );
+                    }
+
+                    pos.start++;
+                    
+                    // Parse the value and create the node
+                    node = new ApproximateNode( attr, parseAssertionValue( filter, pos ) );
+                    return node;
+                    
+                case '>' :
+                    // Greater or equal node
+                    pos.start++;
+                    
+                    // Check that we have a '='
+                    if ( !StringTools.isCharASCII( filter, pos.start, '=' ) )
+                    {
+                        throw new ParseException( "Expecting a '=' ", pos.start );
+                    }
+
+                    pos.start++;
+                    
+                    // Parse the value and create the node
+                    node = new GreaterEqNode( attr, parseAssertionValue( filter, pos ) );
+                    return node;
+                    
+                case '<' :
+                    // Less or equal node
+                    pos.start++;
+                    
+                    // Check that we have a '='
+                    if ( !StringTools.isCharASCII( filter, pos.start, '=' ) )
+                    {
+                        throw new ParseException( "Expecting a '=' ", pos.start );
+                    }
+
+                    pos.start++;
+                    
+                    // Parse the value and create the node
+                    node = new LessEqNode( attr, parseAssertionValue( filter, pos ) );
+                    return node;
+                    
+                case ':' :
+                    // An extensible node
+                    pos.start++;
+                    return parseExtensible( attr, filter, pos );
+                    
+                default :
+                    // This is an error
+                    throw new ParseException( "An item is expected", pos.start );
+            }
+        }
+    }
+
+    /**
+     * Parse AND, OR and NOT nodes :
+     * 
+     * and            = '&' filterlist
+     * or             = '|' filterlist
+     * not            = '!' filter
+     * filterlist     = 1*filter
+     * 
+     * @return
+     */
+    private static ExprNode parseBranchNode( ExprNode node, String filter, Position pos ) throws ParseException
+    {
+        BranchNode bNode = (BranchNode)node;
+        
+        // Relax the grammar a bit : we can have spaces 
+        // StringTools.trimLeft( filter, pos );
+        
+        // We must have at least one filter
+        ExprNode child = parseFilterInternal( filter, pos );
+        
+        // Add the child to the node children
+        bNode.addNode( child );
+
+        // Relax the grammar a bit : we can have spaces 
+        // StringTools.trimLeft( filter, pos );
+        
+        // Now, iterate though all the remaining filters, if any
+        while ( ( child = parseFilterInternal( filter, pos ) ) != null )
+        {
+            // Add the child to the node children
+            bNode.addNode( child );
+
+            // Relax the grammar a bit : we can have spaces 
+            // StringTools.trimLeft( filter, pos );
+        }
+        
+        // Relax the grammar a bit : we can have spaces 
+        // StringTools.trimLeft( filter, pos );
+
+        return node;
+    }
+
+    /**
+     * filtercomp     = and / or / not / item
+     * and            = '&' filterlist
+     * or             = '|' filterlist
+     * not            = '!' filter
+     * item           = simple / present / substring / extensible
+     * simple         = attr filtertype assertionvalue
+     * present        = attr EQUALS ASTERISK
+     * substring      = attr EQUALS [initial] any [final]
+     * extensible     = ( attr [dnattrs]
+     *                    [matchingrule] COLON EQUALS assertionvalue )
+     *                    / ( [dnattrs]
+     *                         matchingrule COLON EQUALS assertionvalue )
+     */
+    private static ExprNode parseFilterComp( String filter, Position pos )  throws ParseException
+    {
+        ExprNode node = null;
+
+        // Relax the grammar a bit : we can have spaces 
+        // StringTools.trimLeft( filter, pos );
+        
+        if ( pos.start == pos.length )
+        {
+            throw new ParseException( "Empty filterComp", pos.start );
+        }
+        
+        char c = StringTools.charAt( filter, pos.start );
+        
+        switch ( c )
+        {
+            case '&' :
+                // This is a AND node
+                pos.start++;
+                node = new AndNode();
+                parseBranchNode( node, filter, pos );
+                break;
+                
+            case '|' :
+                // This is an OR node
+                pos.start++;
+                node = new OrNode();
+                parseBranchNode( node, filter, pos );
+                break;
+                
+            case '!' :
+                // This is a NOT node
+                pos.start++;
+                node = new NotNode();
+                parseBranchNode( node, filter, pos );
+                break;
+                
+            default :
+                // This is an item
+                node = parseItem( filter, pos, c );
+                break;
+                    
+        }
+        
+        return node;
+    }
+    
+    /**
+     * Pasre the grammar rule :
+     * filter ::= '(' filterComp ')'
+     */
+    private static ExprNode parseFilterInternal( String filter, Position pos ) throws ParseException
+    {
+        // relax the grammar by allowing spaces
+        // StringTools.trimLeft( filter, pos );
+        
+        // Check for the left '('
+        if ( StringTools.isCharASCII( filter, pos.start, '(' ) == false )
+        {
+            // No more node, get out
+            if ( ( pos.start == 0 ) && ( pos.length != 0 ) )
+            {
+                throw new ParseException( "No '(' at the begining of the filter", 0 );
+            }
+            else
+            {
+                return null;
+            }
+        }
+        
+        pos.start++;
+        
+        // relax the grammar by allowing spaces
+        // StringTools.trimLeft( filter, pos );
+        
+        // parse the filter component
+        ExprNode node = parseFilterComp( filter, pos );
+        
+        if ( node == null )
+        {
+            throw new ParseException( "Bad filter", pos.start );
+        }
+        
+        // relax the grammar by allowing spaces
+        // StringTools.trimLeft( filter, pos );
+        
+        // Check that we have a right ')'
+        if ( StringTools.isCharASCII( filter, pos.start, ')' ) == false )
+        {
+            throw new ParseException( "The filter has no right parenthese", pos.start );
+        }
+        
+        pos.start++;
+        
+        return node;
+    }
+    
+    /**
+     * @see FilterParser#parse(String)
+     */
+    public static ExprNode parse( String filter ) throws ParseException
+    {
+        // The filter must not be null. This is a defensive test
+        if ( StringTools.isEmpty( filter ) )
+        {
+            throw new ParseException( "Empty filter", 0 );
+        }
+        
+        Position pos = new Position();
+        pos.start = 0;
+        pos.end = 0;
+        pos.length = filter.length();
+        
+        return parseFilterInternal( filter, pos );
+    }
+
+
+    public void setFilterParserMonitor( FilterParserMonitor monitor )
+    {
+    }
+}

Modified: directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/filter/BranchNormalizedVisitorTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/filter/BranchNormalizedVisitorTest.java?rev=580525&r1=580524&r2=580525&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/filter/BranchNormalizedVisitorTest.java (original)
+++ directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/filter/BranchNormalizedVisitorTest.java Fri Sep 28 18:10:31 2007
@@ -38,9 +38,9 @@
     {
         String filter = "(ou=Human Resources)";
 
-        ExprNode ori = FastFilterParserImpl.parse( filter );
+        ExprNode ori = FilterParser.parse( filter );
 
-        ExprNode altered = FastFilterParserImpl.parse( filter );
+        ExprNode altered = FilterParser.parse( filter );
 
         BranchNormalizedVisitor visitor = new BranchNormalizedVisitor();
 
@@ -54,9 +54,9 @@
     {
         String filter = "(&(ou=Human Resources)(uid=akarasulu))";
 
-        ExprNode ori = FastFilterParserImpl.parse( filter );
+        ExprNode ori = FilterParser.parse( filter );
 
-        ExprNode altered = FastFilterParserImpl.parse( filter );
+        ExprNode altered = FilterParser.parse( filter );
 
         BranchNormalizedVisitor visitor = new BranchNormalizedVisitor();
 
@@ -72,9 +72,9 @@
 
         filter += "(|(uid=akarasulu)(ou=Human Resources))) ";
 
-        ExprNode ori = FastFilterParserImpl.parse( filter );
+        ExprNode ori = FilterParser.parse( filter );
 
-        ExprNode altered = FastFilterParserImpl.parse( filter );
+        ExprNode altered = FilterParser.parse( filter );
 
         BranchNormalizedVisitor visitor = new BranchNormalizedVisitor();
 
@@ -90,9 +90,9 @@
 
         filter += "(|(ou=Human Resources)(uid=akarasulu)))";
 
-        ExprNode ori = FastFilterParserImpl.parse( filter );
+        ExprNode ori = FilterParser.parse( filter );
 
-        ExprNode altered = FastFilterParserImpl.parse( filter );
+        ExprNode altered = FilterParser.parse( filter );
 
         BranchNormalizedVisitor visitor = new BranchNormalizedVisitor();
 

Added: directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/filter/FilterParserTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/filter/FilterParserTest.java?rev=580525&view=auto
==============================================================================
--- directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/filter/FilterParserTest.java (added)
+++ directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/filter/FilterParserTest.java Fri Sep 28 18:10:31 2007
@@ -0,0 +1,665 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.shared.ldap.filter;
+
+
+import java.text.ParseException;
+
+import org.apache.directory.shared.ldap.filter.BranchNode;
+import org.apache.directory.shared.ldap.filter.ExtensibleNode;
+import org.apache.directory.shared.ldap.filter.PresenceNode;
+import org.apache.directory.shared.ldap.filter.SimpleNode;
+import org.apache.directory.shared.ldap.filter.SubstringNode;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNull;
+
+
+/**
+ * Tests the FilterParserImpl class.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 575783 $
+ */
+public class FilterParserTest
+{
+    private boolean checkWrongFilter( String filter )
+    {
+        try
+        {
+            return FilterParser.parse( filter ) == null;
+        }
+        catch ( ParseException pe )
+        {
+            return true;
+        }
+    }
+
+    /**
+     * Tests to avoid deadlocks for invalid filters. 
+     * 
+     */
+    @Test
+    public void testInvalidFilters() 
+    {
+        assertTrue( checkWrongFilter( "" ) );
+        assertTrue( checkWrongFilter( "   " ) );
+        assertTrue( checkWrongFilter( "(" ) );
+        assertTrue( checkWrongFilter( "  (" ) );
+        assertTrue( checkWrongFilter( "(  " ) );
+        assertTrue( checkWrongFilter( ")" ) );
+        assertTrue( checkWrongFilter( "  )" ) );
+        assertTrue( checkWrongFilter( "()" ) );
+        assertTrue( checkWrongFilter( "(  )" ) );
+        assertTrue( checkWrongFilter( "  ()  " ) );
+        assertTrue( checkWrongFilter( "(cn=test(" ) );
+        assertTrue( checkWrongFilter( "(cn=aaaaa" ) );
+        assertTrue( checkWrongFilter( "(&(cn=abc)" ) );
+    }
+
+    @Test
+    public void testItemFilter() throws ParseException
+    {
+        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(ou~=people)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertEquals( "people", node.getValue() );
+        assertTrue( node instanceof ApproximateNode );
+    }
+
+    
+    @Test
+    public void testAndFilter() throws ParseException
+    {
+        BranchNode node = ( BranchNode ) FilterParser.parse( "(&(ou~=people)(age>=30))" );
+        assertEquals( 2, node.getChildren().size() );
+        assertTrue( node instanceof AndNode );
+    }
+
+    
+    @Test
+    public void testAndFilterOneChildOnly() throws ParseException
+    {
+        BranchNode node = ( BranchNode ) FilterParser.parse( "(&(ou~=people))" );
+        assertEquals( 1, node.getChildren().size() );
+        assertTrue( node instanceof AndNode );
+    }
+
+
+    @Test
+    public void testOrFilter() throws ParseException
+    {
+        BranchNode node = ( BranchNode ) FilterParser.parse( "(|(ou~=people)(age>=30))" );
+        assertEquals( 2, node.getChildren().size() );
+        assertTrue( node instanceof OrNode );
+    }
+
+
+    @Test
+    public void testOrFilterOneChildOnly() throws ParseException
+    {
+        BranchNode node = ( BranchNode ) FilterParser.parse( "(|(age>=30))" );
+        assertEquals( 1, node.getChildren().size() );
+        assertTrue( node instanceof OrNode );
+    }
+
+
+    @Test
+    public void testNotFilter() throws ParseException
+    {
+        BranchNode node = ( BranchNode ) FilterParser.parse( "(!(&(ou~= people)(age>=30)))" );
+        assertEquals( 1, node.getChildren().size() );
+        assertTrue( node instanceof NotNode );
+    }
+
+
+    @Test
+    public void testOptionAndEscapesFilter() throws ParseException
+    {
+        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(ou;lang-de>=\\23\\42asdl fkajsd)" );
+        assertEquals( "ou;lang-de", node.getAttribute() );
+        assertEquals( "\\23\\42asdl fkajsd", node.getValue() );
+    }
+
+
+    @Test
+    public void testOptionsAndEscapesFilter() throws ParseException
+    {
+        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(ou;lang-de;version-124>=\\23\\42asdl fkajsd)" );
+        assertEquals( "ou;lang-de;version-124", node.getAttribute() );
+        assertEquals( "\\23\\42asdl fkajsd", node.getValue() );
+    }
+
+
+    @Test
+    public void testNumericoidOptionsAndEscapesFilter() throws ParseException
+    {
+        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(1.3.4.2;lang-de;version-124>=\\23\\42asdl fkajsd)" );
+        assertEquals( "1.3.4.2;lang-de;version-124", node.getAttribute() );
+        assertEquals( "\\23\\42asdl fkajsd", node.getValue() );
+    }
+
+
+    @Test
+    public void testPresentFilter() throws ParseException
+    {
+        PresenceNode node = ( PresenceNode ) FilterParser.parse( "(ou=*)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof PresenceNode );
+    }
+
+
+    @Test
+    public void testNumericoidPresentFilter() throws ParseException
+    {
+        PresenceNode node = ( PresenceNode ) FilterParser.parse( "(1.2.3.4=*)" );
+        assertEquals( "1.2.3.4", node.getAttribute() );
+        assertTrue( node instanceof PresenceNode );
+    }
+
+
+    @Test
+    public void testEqualsFilter() throws ParseException
+    {
+        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(ou=people)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertEquals( "people", node.getValue() );
+        assertTrue( node instanceof EqualityNode );
+    }
+
+
+    @Test
+    public void testBadEqualsFilter()
+    {
+        try
+        {
+            FilterParser.parse( "ou=people" );
+
+            // The parsing should fail
+            fail( "should fail with bad filter" );
+        }
+        catch ( ParseException pe )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    @Test
+    public void testEqualsWithForwardSlashFilter() throws ParseException
+    {
+        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(ou=people/in/my/company)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertEquals( "people/in/my/company", node.getValue() );
+        assertTrue( node instanceof EqualityNode );
+    }
+
+
+    @Test
+    public void testExtensibleFilterForm1() throws ParseException
+    {
+        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(ou:dn:stupidMatch:=dummyAssertion\\23\\ac)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
+        assertEquals( "stupidMatch", node.getMatchingRuleId() );
+        assertTrue( node.hasDnAttributes() );
+        assertTrue( node instanceof ExtensibleNode );
+    }
+
+
+    @Test
+    public void testExtensibleFilterForm1WithNumericOid() throws ParseException
+    {
+        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(1.2.3.4:dn:1.3434.23.2:=dummyAssertion\\23\\ac)" );
+        assertEquals( "1.2.3.4", node.getAttribute() );
+        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
+        assertEquals( "1.3434.23.2", node.getMatchingRuleId() );
+        assertTrue( node.hasDnAttributes() );
+        assertTrue( node instanceof ExtensibleNode );
+    }
+
+
+    @Test
+    public void testExtensibleFilterForm1NoDnAttr() throws ParseException
+    {
+        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(ou:stupidMatch:=dummyAssertion\\23\\ac)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
+        assertEquals( "stupidMatch", node.getMatchingRuleId() );
+        assertFalse( node.hasDnAttributes() );
+        assertTrue( node instanceof ExtensibleNode );
+    }
+
+
+    @Test
+    public void testExtensibleFilterForm1OptionOnRule()
+    {
+        try
+        {
+            FilterParser.parse( "(ou:stupidMatch;lang-de:=dummyAssertion\\23\\ac)" );
+            fail( "we should never get here" );
+        }
+        catch ( ParseException e )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    @Test
+    public void testExtensibleFilterForm1NoAttrNoMatchingRule() throws ParseException
+    {
+        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(ou:=dummyAssertion\\23\\ac)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
+        assertEquals( null, node.getMatchingRuleId() );
+        assertFalse( node.hasDnAttributes() );
+        assertTrue( node instanceof ExtensibleNode );
+    }
+
+
+    @Test
+    public void testExtensibleFilterForm2() throws ParseException
+    {
+        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(:dn:stupidMatch:=dummyAssertion\\23\\ac)" );
+        assertEquals( null, node.getAttribute() );
+        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
+        assertEquals( "stupidMatch", node.getMatchingRuleId() );
+        assertTrue( node.hasDnAttributes() );
+        assertTrue( node instanceof ExtensibleNode );
+    }
+
+
+    @Test
+    public void testExtensibleFilterForm2OptionOnRule()
+    {
+        try
+        {
+            FilterParser.parse( "(:dn:stupidMatch;lang-en:=dummyAssertion\\23\\ac)" );
+            fail( "we should never get here" );
+        }
+        catch ( ParseException e )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    @Test
+    public void testExtensibleFilterForm2WithNumericOid() throws ParseException
+    {
+        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(:dn:1.3434.23.2:=dummyAssertion\\23\\ac)" );
+        assertEquals( null, node.getAttribute() );
+        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
+        assertEquals( "1.3434.23.2", node.getMatchingRuleId() );
+        assertTrue( node.hasDnAttributes() );
+        assertTrue( node instanceof ExtensibleNode );
+    }
+
+
+    @Test
+    public void testExtensibleFilterForm2NoDnAttr() throws ParseException
+    {
+        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(:stupidMatch:=dummyAssertion\\23\\ac)" );
+        assertEquals( null, node.getAttribute() );
+        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
+        assertEquals( "stupidMatch", node.getMatchingRuleId() );
+        assertFalse( node.hasDnAttributes() );
+        assertTrue( node instanceof ExtensibleNode );
+    }
+
+
+    @Test
+    public void testExtensibleFilterForm2NoDnAttrWithNumericOidNoAttr() throws ParseException
+    {
+        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(:1.3434.23.2:=dummyAssertion\\23\\ac)" );
+        assertEquals( null, node.getAttribute() );
+        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
+        assertEquals( "1.3434.23.2", node.getMatchingRuleId() );
+        assertFalse( node.hasDnAttributes() );
+        assertTrue( node instanceof ExtensibleNode );
+    }
+
+
+    @Test
+    public void testExtensibleFilterForm3() throws ParseException
+    {
+        try
+        {
+            FilterParser.parse( "(:=dummyAssertion)" );
+            fail( "Should never reach this point" );
+        }
+        catch ( ParseException pe )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    @Test
+    public void testReuseParser() throws ParseException
+    {
+        FilterParser.parse( "(ou~=people)" );
+        FilterParser.parse( "(&(ou~=people)(age>=30)) " );
+        FilterParser.parse( "(|(ou~=people)(age>=30)) " );
+        FilterParser.parse( "(!(&(ou~=people)(age>=30)))" );
+        FilterParser.parse( "(ou;lang-de>=\\23\\42asdl fkajsd)" );
+        FilterParser.parse( "(ou;lang-de;version-124>=\\23\\42asdl fkajsd)" );
+        FilterParser.parse( "(1.3.4.2;lang-de;version-124>=\\23\\42asdl fkajsd)" );
+        FilterParser.parse( "(ou=*)" );
+        FilterParser.parse( "(1.2.3.4=*)" );
+        FilterParser.parse( "(ou=people)" );
+        FilterParser.parse( "(ou=people/in/my/company)" );
+        FilterParser.parse( "(ou:dn:stupidMatch:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(1.2.3.4:dn:1.3434.23.2:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(ou:stupidMatch:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(ou:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(1.2.3.4:1.3434.23.2:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(:dn:stupidMatch:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(:dn:1.3434.23.2:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(:stupidMatch:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(:1.3434.23.2:=dummyAssertion\\23\\ac)" );
+    }
+
+
+    @Test
+    public void testReuseParserAfterFailures() throws ParseException
+    {
+        FilterParser.parse( "(ou~=people)" );
+        FilterParser.parse( "(&(ou~=people)(age>=30)) " );
+        FilterParser.parse( "(|(ou~=people)(age>=30)) " );
+        FilterParser.parse( "(!(&(ou~=people)(age>=30)))" );
+        FilterParser.parse( "(ou;lang-de>=\\23\\42asdl fkajsd)" );
+        FilterParser.parse( "(ou;lang-de;version-124>=\\23\\42asdl fkajsd)" );
+        FilterParser.parse( "(1.3.4.2;lang-de;version-124>=\\23\\42asdl fkajsd)" );
+        
+        try
+        {
+            FilterParser.parse( "(ou:stupidMatch;lang-de:=dummyAssertion\\23\\ac)" );
+            fail( "we should never get here" );
+        }
+        catch ( ParseException e )
+        {
+            assertTrue( true );
+        }
+
+        FilterParser.parse( "(ou=*)" );
+        FilterParser.parse( "(1.2.3.4=*)" );
+        FilterParser.parse( "(ou=people)" );
+        FilterParser.parse( "(ou=people/in/my/company)" );
+        FilterParser.parse( "(ou:dn:stupidMatch:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(1.2.3.4:dn:1.3434.23.2:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(ou:stupidMatch:=dummyAssertion\\23\\ac)" );
+
+        try
+        {
+            FilterParser.parse( "(:dn:stupidMatch;lang-en:=dummyAssertion\\23\\ac)" );
+            fail( "we should never get here" );
+        }
+        catch ( ParseException e )
+        {
+            assertTrue( true );
+        }
+
+        FilterParser.parse( "(ou:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(1.2.3.4:1.3434.23.2:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(:dn:stupidMatch:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(:dn:1.3434.23.2:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(:stupidMatch:=dummyAssertion\\23\\ac)" );
+        FilterParser.parse( "(:1.3434.23.2:=dummyAssertion\\23\\ac)" );
+    }
+
+
+    @Test
+    public void testNullOrEmptyString() throws ParseException
+    {
+        try
+        {
+            FilterParser.parse( null );
+            fail( "Should not reach this point " );
+        }
+        catch( ParseException pe )
+        {
+            assertTrue( true );
+        }
+
+        try
+        {
+            FilterParser.parse( "" );
+            fail( "Should not reach this point " );
+        }
+        catch( ParseException pe )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    @Test
+    public void testSubstringNoAnyNoFinal() throws ParseException
+    {
+        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=foo*)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof SubstringNode );
+
+        assertEquals( 0, node.getAny().size() );
+        assertFalse( node.getAny().contains( "" ) );
+        assertEquals( "foo", node.getInitial() );
+        assertEquals( null, node.getFinal() );
+    }
+
+
+    @Test
+    public void testSubstringNoAny() throws ParseException
+    {
+        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=foo*bar)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof SubstringNode );
+
+        assertEquals( 0, node.getAny().size() );
+        assertFalse( node.getAny().contains( "" ) );
+        assertEquals( "foo", node.getInitial() );
+        assertEquals( "bar", node.getFinal() );
+    }
+
+
+    @Test
+    public void testSubstringNoAnyNoIni() throws ParseException
+    {
+        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=*bar)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof SubstringNode );
+
+        assertEquals( 0, node.getAny().size() );
+        assertFalse( node.getAny().contains( "" ) );
+        assertEquals( null, node.getInitial() );
+        assertEquals( "bar", node.getFinal() );
+    }
+
+
+    @Test
+    public void testSubstringOneAny() throws ParseException
+    {
+        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=foo*guy*bar)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof SubstringNode );
+
+        assertEquals( 1, node.getAny().size() );
+        assertFalse( node.getAny().contains( "" ) );
+        assertTrue( node.getAny().contains( "guy" ) );
+        assertEquals( "foo", node.getInitial() );
+        assertEquals( "bar", node.getFinal() );
+    }
+
+
+    @Test
+    public void testSubstringManyAny() throws ParseException
+    {
+        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=a*b*c*d*e*f)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof SubstringNode );
+
+        assertEquals( 4, node.getAny().size() );
+        assertFalse( node.getAny().contains( "" ) );
+        assertTrue( node.getAny().contains( "b" ) );
+        assertTrue( node.getAny().contains( "c" ) );
+        assertTrue( node.getAny().contains( "d" ) );
+        assertTrue( node.getAny().contains( "e" ) );
+        assertEquals( "a", node.getInitial() );
+        assertEquals( "f", node.getFinal() );
+    }
+
+
+    @Test
+    public void testSubstringNoIniManyAny() throws ParseException
+    {
+        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=*b*c*d*e*f)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof SubstringNode );
+
+        assertEquals( 4, node.getAny().size() );
+        assertFalse( node.getAny().contains( "" ) );
+        assertTrue( node.getAny().contains( "e" ) );
+        assertTrue( node.getAny().contains( "b" ) );
+        assertTrue( node.getAny().contains( "c" ) );
+        assertTrue( node.getAny().contains( "d" ) );
+        assertEquals( null, node.getInitial() );
+        assertEquals( "f", node.getFinal() );
+    }
+
+
+    @Test
+    public void testSubstringManyAnyNoFinal() throws ParseException
+    {
+        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=a*b*c*d*e*)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof SubstringNode );
+
+        assertEquals( 4, node.getAny().size() );
+        assertFalse( node.getAny().contains( "" ) );
+        assertTrue( node.getAny().contains( "e" ) );
+        assertTrue( node.getAny().contains( "b" ) );
+        assertTrue( node.getAny().contains( "c" ) );
+        assertTrue( node.getAny().contains( "d" ) );
+        assertEquals( "a", node.getInitial() );
+        assertEquals( null, node.getFinal() );
+    }
+
+
+    @Test
+    public void testSubstringNoIniManyAnyNoFinal() throws ParseException
+    {
+        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=*b*c*d*e*)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof SubstringNode );
+
+        assertEquals( 4, node.getAny().size() );
+        assertFalse( node.getAny().contains( "" ) );
+        assertTrue( node.getAny().contains( "e" ) );
+        assertTrue( node.getAny().contains( "b" ) );
+        assertTrue( node.getAny().contains( "c" ) );
+        assertTrue( node.getAny().contains( "d" ) );
+        assertEquals( null, node.getInitial() );
+        assertEquals( null, node.getFinal() );
+    }
+
+
+    @Test
+    public void testSubstringNoAnyDoubleSpaceStar() throws ParseException
+    {
+        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=foo* *bar)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof SubstringNode );
+
+        assertEquals( 1, node.getAny().size() );
+        assertFalse( node.getAny().contains( "" ) );
+        assertTrue( node.getAny().contains( " " ) );
+        assertEquals( "foo", node.getInitial() );
+        assertEquals( "bar", node.getFinal() );
+    }
+
+
+    @Test
+    public void testSubstringAnyDoubleSpaceStar() throws ParseException
+    {
+        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=foo* a *bar)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof SubstringNode );
+
+        assertEquals( 1, node.getAny().size() );
+        assertFalse( node.getAny().contains( "" ) );
+        assertTrue( node.getAny().contains( " a " ) );
+        assertEquals( "foo", node.getInitial() );
+        assertEquals( "bar", node.getFinal() );
+    }
+
+
+    /**
+     * Enrique just found this bug with the filter parser when parsing substring
+     * expressions like *any*. Here's the JIRA issue: <a
+     * href="http://nagoya.apache.org/jira/browse/DIRLDAP-21">DIRLDAP-21</a>.
+     */
+    @Test
+    public void testSubstringStarAnyStar() throws ParseException
+    {
+        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=*foo*)" );
+        assertEquals( "ou", node.getAttribute() );
+        assertTrue( node instanceof SubstringNode );
+
+        assertEquals( 1, node.getAny().size() );
+        assertTrue( node.getAny().contains( "foo" ) );
+        assertNull( node.getInitial() );
+        assertNull( node.getFinal() );
+    }
+    
+    /*
+    @Test
+    public void testPerf() throws ParseException
+    {
+        String filter = "(&(ou=abcdefg)(!(ou=hijkl))(&(a=bcd)(ew=fgh)))";
+        FilterParser parser = new FilterParserImpl();
+        
+        long t0 = System.currentTimeMillis();
+        
+        for ( int i = 0; i < 1000000; i++ )
+        {
+            parser.parse( filter );
+        }
+        
+        long t1 = System.currentTimeMillis();
+        
+        System.out.println( " Delta = " + (t1 - t0) );
+
+        long t2 = System.currentTimeMillis();
+        
+        for ( int i = 0; i < 10000000; i++ )
+        {
+            FastFilterParserImpl.parse( filter );
+        }
+        
+        long t3 = System.currentTimeMillis();
+        
+        System.out.println( " Delta = " + (t3 - t2) );
+    }
+    */
+}

Modified: directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/subtree/SubtreeSpecificationParserTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/subtree/SubtreeSpecificationParserTest.java?rev=580525&r1=580524&r2=580525&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/subtree/SubtreeSpecificationParserTest.java (original)
+++ directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/subtree/SubtreeSpecificationParserTest.java Fri Sep 28 18:10:31 2007
@@ -31,7 +31,7 @@
 import org.apache.directory.shared.ldap.filter.BranchNode;
 import org.apache.directory.shared.ldap.filter.EqualityNode;
 import org.apache.directory.shared.ldap.filter.ExprNode;
-import org.apache.directory.shared.ldap.filter.FastFilterParserImpl;
+import org.apache.directory.shared.ldap.filter.FilterParser;
 import org.apache.directory.shared.ldap.filter.NotNode;
 import org.apache.directory.shared.ldap.filter.OrNode;
 import org.apache.directory.shared.ldap.filter.SimpleNode;
@@ -353,7 +353,7 @@
     {
         SubtreeSpecification ss = parser.parse( SPEC_WITH_FILTER );
 
-        ExprNode filter = FastFilterParserImpl.parse( "(&(cn=test)(sn=test))" );
+        ExprNode filter = FilterParser.parse( "(&(cn=test)(sn=test))" );
 
         assertEquals( filter, ss.getRefinement() );
     }



Mime
View raw message