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() );
}