You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2004/11/07 02:33:33 UTC

svn commit: rev 56797 - in incubator/directory/ldap/trunk/common/src: antlr test/org/apache/ldap/common/filter

Author: akarasulu
Date: Sat Nov  6 17:33:32 2004
New Revision: 56797

Modified:
   incubator/directory/ldap/trunk/common/src/antlr/filter-value-parser.g
   incubator/directory/ldap/trunk/common/src/test/org/apache/ldap/common/filter/FilterParserImplTest.java
Log:
Found some really interesting implications to filter processing as a result
of the parser and think I fixed them correctly but I still need to confirm
on the LDAPBIS list.  Here's the question:

Are these filters equivalent?

   #1       #2           #3         #4      #5
(ou= * ) (ou=  *) (   ou  =  *  ) (ou=* ) (ou=*)

#1: initial = " ", any is empty, final = " "
#2: initial = "  ", any is empty, final = null
#3: initial = "  ", any is empty, final = "  "
#4: initial = null, any is empty, final = " "

My answer to this question is yes, they are all equal to #5. But
the parser reads it as a substring assertion according to the 
grammar provided from the LDAPBIS group.  We need to confirm this.



Modified: incubator/directory/ldap/trunk/common/src/antlr/filter-value-parser.g
==============================================================================
--- incubator/directory/ldap/trunk/common/src/antlr/filter-value-parser.g	(original)
+++ incubator/directory/ldap/trunk/common/src/antlr/filter-value-parser.g	Sat Nov  6 17:33:32 2004
@@ -159,7 +159,7 @@
     : ASTERISK
     {
         selector.select( lexer );
-        node = new PresenceNode( attribute );
+        node = new PresenceNode( attribute.trim() );
     }
     RPAREN;
 
@@ -168,7 +168,7 @@
  * Parser production that parses the substring expression value immediately
  * after the '=' in a substring filter assertion.
  */
-substring [String attribute] returns [SubstringNode node]
+substring [String attribute] returns [LeafNode node]
 {
     node = null;
     String initial = null;
@@ -180,7 +180,7 @@
         // A L T E R N A T I V E   1:    initial*
         alt1:VALUEENCODING
         {
-            initial = alt1.getText();
+            initial = alt1.getText().trim();
         }
         ASTERISK
     |
@@ -192,14 +192,14 @@
                 any.add( fin );
             }
 
-            fin = alt2.getText();
+            fin = alt2.getText().trim();
         }
         )+
     |
         // A L T E R N A T I V E   3:    initial (*any) *final
         alt3t0:VALUEENCODING
         {
-            initial = alt3t0.getText();
+            initial = alt3t0.getText().trim();
         }
         ( ASTERISK alt3t1:VALUEENCODING
         {
@@ -208,14 +208,59 @@
                 any.add( fin );
             }
 
-            fin = alt3t1.getText();
+            fin = alt3t1.getText().trim();
         }
         )+
     )
     RPAREN
     {
         selector.select( lexer );
-        node = new SubstringNode( any, attribute, initial, fin );
+
+        /*
+         * Under special circumstances a presence string can appear to be a
+         * SubstringNode.  Namely the following too filters are not equal:
+         *
+         * (ou=*) != (ou=* )
+         *
+         * The first on the left hand side has no space between the '*' and the
+         * closing parenthesis.  The 2nd on the right hand side has a space.  So
+         * the question arrises how do we interpret this.  Intuitively both
+         * would be considered the same and that's what we shall do until we ask
+         * on the LDAPBIS mailing list.  However note that the first filter will
+         * be processed by the presence rule while the second will be processed
+         * by this rule the substring rule.  That is because according to the
+         * parser white space is significant as it should be in the value
+         * encoding just not on the periphery.  So as a substring the 2nd filter
+         * would be interpretted as a search for all ou values ending in a
+         * whitespace.  Again intuitively this does not make sense.  I would
+         * imagine it best if this is what was intended that the escape sequence
+         * '\20' be used for white space rather than using actual whitespace on
+         * the periphery.
+         *
+         * So what do we do to solve this problem.  Well we need to characterize
+         * first the range of errors that are possible.  First any one of these
+         * filters are valid presence filters (note whitespace differences):
+         *    #1       #2           #3         #4
+         * (ou= * ) (ou=  *) (   ou  =  *  ) (ou=* )
+         *
+         * #1: initial = " ", any is empty, final = " "
+         * #2: initial = "  ", any is empty, final = null
+         * #3: initial = "  ", any is empty, final = "  "
+         * #4: initial = null, any is empty, final = " "
+         *
+         * To handle this and generate the appropriate node type we check for
+         * null, empty strings, and empty any arrays in the condition below:
+         */
+        if ( any.isEmpty()
+             && ( initial == null || initial.trim().length() == 0 )
+             && ( fin == null || fin.trim().length() == 0 ) )
+        {
+            node = new PresenceNode( attribute );
+        }
+        else
+        {
+            node = new SubstringNode( any, attribute, initial, fin );
+        }
     }
     ;
 

Modified: incubator/directory/ldap/trunk/common/src/test/org/apache/ldap/common/filter/FilterParserImplTest.java
==============================================================================
--- incubator/directory/ldap/trunk/common/src/test/org/apache/ldap/common/filter/FilterParserImplTest.java	(original)
+++ incubator/directory/ldap/trunk/common/src/test/org/apache/ldap/common/filter/FilterParserImplTest.java	Sat Nov  6 17:33:32 2004
@@ -58,43 +58,71 @@
 
     public void testAndFilter() throws IOException, ParseException
     {
-        parser.parse( "(& ( ou ~= people ) (age>=30) ) " );
+        BranchNode node = ( BranchNode ) parser.parse( "(& ( ou ~= people ) (age>=30) ) " );
+        assertEquals( 2, node.getChildren().size() );
+        assertEquals( AbstractExprNode.AND, node.getOperator() );
     }
 
 
     public void testOrFilter() throws IOException, ParseException
     {
-        parser.parse( "(| ( ou ~= people ) (age>=30) ) " );
+        BranchNode node = ( BranchNode ) parser.parse( "(| ( ou ~= people ) (age>=30) ) " );
+        assertEquals( 2, node.getChildren().size() );
+        assertEquals( AbstractExprNode.OR, node.getOperator() );
     }
 
 
     public void testNotFilter() throws IOException, ParseException
     {
-        parser.parse( "( ! (& ( ou ~= people ) (age>=30) ) )" );
+        BranchNode node = ( BranchNode ) parser.parse( "( ! (& ( ou ~= people ) (age>=30) ) )" );
+        assertEquals( 1, node.getChildren().size() );
+        assertEquals( AbstractExprNode.NOT, node.getOperator() );
     }
 
 
     public void testOptionAndEscapesFilter() throws IOException, ParseException
     {
-        parser.parse( "( ou;lang-de >= \\23\\42asdl fkajsd )" );
+        SimpleNode node = ( SimpleNode ) parser.parse( "( ou;lang-de >= \\23\\42asdl fkajsd )" );
+        assertEquals( "ou;lang-de", node.getAttribute() );
+        assertEquals( "\\23\\42asdl fkajsd", node.getValue() );
     }
 
 
     public void testOptionsAndEscapesFilter() throws IOException, ParseException
     {
-        parser.parse( "( ou;lang-de;version-124 >= \\23\\42asdl fkajsd )" );
+        SimpleNode node = ( SimpleNode ) parser.parse( "( ou;lang-de;version-124 >= \\23\\42asdl fkajsd )" );
+        assertEquals( "ou;lang-de;version-124", node.getAttribute() );
+        assertEquals( "\\23\\42asdl fkajsd", node.getValue() );
     }
 
 
     public void testNumericoidOptionsAndEscapesFilter() throws IOException, ParseException
     {
-        parser.parse( "( 1.3.4.2;lang-de;version-124 >= \\23\\42asdl fkajsd )" );
+        SimpleNode node = ( SimpleNode ) parser.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() );
     }
 
 
     public void testPresentFilter() throws IOException, ParseException
     {
-        parser.parse( "( ou =* )" );
+        PresenceNode node = ( PresenceNode ) parser.parse( "( ou =*)" );
+        assertEquals( "ou", node.getAttribute() );
+
+        node = ( PresenceNode ) parser.parse( "( ou =* )" );
+        assertEquals( "ou", node.getAttribute() );
+
+        node = ( PresenceNode ) parser.parse( "( ou =  * )" );
+        assertEquals( "ou", node.getAttribute() );
+
+        node = ( PresenceNode ) parser.parse( "(  ou = *)" );
+        assertEquals( "ou", node.getAttribute() );
+
+        node = ( PresenceNode ) parser.parse( "( ou =* ) " );
+        assertEquals( "ou", node.getAttribute() );
+
+        node = ( PresenceNode ) parser.parse( "( ou =*)" );
+        assertEquals( "ou", node.getAttribute() );
     }