You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by er...@apache.org on 2005/11/08 19:22:34 UTC
svn commit: r331857 - in /directory/shared/ldap/trunk/common/src:
antlr/subtree-specification.g
test/org/apache/ldap/common/subtree/SubtreeSpecificationParserTest.java
Author: ersiner
Date: Tue Nov 8 10:22:19 2005
New Revision: 331857
URL: http://svn.apache.org/viewcvs?rev=331857&view=rev
Log:
Fix for DIRLDAP-66.
Provided a more flexible grammar for subtreeSpecification where order of components does not matter.
Modified:
directory/shared/ldap/trunk/common/src/antlr/subtree-specification.g
directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/subtree/SubtreeSpecificationParserTest.java
Modified: directory/shared/ldap/trunk/common/src/antlr/subtree-specification.g
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/antlr/subtree-specification.g?rev=331857&r1=331856&r2=331857&view=diff
==============================================================================
--- directory/shared/ldap/trunk/common/src/antlr/subtree-specification.g (original)
+++ directory/shared/ldap/trunk/common/src/antlr/subtree-specification.g Tue Nov 8 10:22:19 2005
@@ -36,6 +36,8 @@
import org.apache.ldap.common.filter.AbstractExprNode;
import org.apache.ldap.common.subtree.SubtreeSpecification;
import org.apache.ldap.common.subtree.SubtreeSpecificationModifier;
+import org.apache.ldap.common.util.ComponentsMonitor;
+import org.apache.ldap.common.util.OptionalComponentsMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -62,8 +64,7 @@
options
{
- k = 2;
-
+ k = 1;
defaultErrorHandler = false;
}
@@ -77,12 +78,14 @@
private DnParser dnParser;
private boolean isNormalizing = false;
- NameComponentNormalizer normalizer;
+ private NameComponentNormalizer normalizer;
private Set chopBeforeExclusions = new HashSet();
private Set chopAfterExclusions = new HashSet();
- SubtreeSpecificationModifier ssModifier = null;
+ private SubtreeSpecificationModifier ssModifier = null;
+
+ private ComponentsMonitor subtreeSpecificationComponentsMonitor = null;
/**
* Creates a (normalizing) subordinate DnParser for parsing LocalNames.
@@ -123,6 +126,24 @@
this.normalizer = normalizer;
this.isNormalizing = true;
}
+
+ private int token2Integer( Token token ) throws RecognitionException
+ {
+ int i = 0;
+
+ try
+ {
+ i = Integer.parseInt( token.getText());
+ }
+ catch ( NumberFormatException e )
+ {
+ throw new RecognitionException( "Value of INTEGER token " +
+ token.getText() +
+ " cannot be converted to an Integer" );
+ }
+
+ return i;
+ }
}
@@ -142,311 +163,596 @@
}
;
-
subtreeSpecification returns [SubtreeSpecification ss]
{
log.debug( "entered subtreeSpecification()" );
- // clear out ss and ssModifier in case something is left from the last parse
+ // clear out ss, ssModifier and subtreeSpecificationComponentsMonitor
+ // in case something is left from the last parse
ss = null;
ssModifier = new SubtreeSpecificationModifier();
-} :
- LBRACKET ( SP )*
- (
- (
- ss_base ss_base_follower
- | ss_specificExclusions ss_specificExclusions_follower
- | ss_minimum ss_minimum_follower
- | ss_maximum ss_maximum_follower
- | ss_specificationFilter
- )
- ( SP )*
- )?
- RBRACKET
+ subtreeSpecificationComponentsMonitor = new OptionalComponentsMonitor(
+ new String [] { "base", "specificExclusions", "minimum", "maximum", "specificationFilter" } );
+}
+ :
+ OPEN_CURLY ( SP )*
+ ( subtreeSpecificationComponent ( SP )*
+ ( SEP ( SP )* subtreeSpecificationComponent ( SP )* )* )?
+ CLOSE_CURLY
{
ss = ssModifier.getSubtreeSpecification();
}
;
-
-ss_base_follower
- :
- ( SEP ( SP )*
- (
- ss_specificExclusions ss_specificExclusions_follower
- | ss_minimum ss_minimum_follower
- | ss_maximum ss_maximum_follower
- | ss_specificationFilter
- )
- )?
- ;
-
-
-ss_specificExclusions_follower
- :
- ( SEP ( SP )*
- (
- ss_minimum ss_minimum_follower
- | ss_maximum ss_maximum_follower
- | ss_specificationFilter
- )
- )?
- ;
-
-
-ss_minimum_follower
- :
- ( SEP ( SP )*
- (
- ss_maximum ss_maximum_follower
- | ss_specificationFilter
- )
- )?
- ;
-
-
-ss_maximum_follower
+subtreeSpecificationComponent
+{
+ log.debug( "entered subtreeSpecification()" );
+}
:
- ( SEP ( SP )*
- (
- ss_specificationFilter
- )
- )?
+ ss_base
+ {
+ subtreeSpecificationComponentsMonitor.useComponent( "base" );
+ }
+ | ss_specificExclusions
+ {
+ subtreeSpecificationComponentsMonitor.useComponent( "specificExclusions" );
+ }
+ | ss_minimum
+ {
+ subtreeSpecificationComponentsMonitor.useComponent( "minimum" );
+ }
+ | ss_maximum
+ {
+ subtreeSpecificationComponentsMonitor.useComponent( "maximum" );
+ }
+ | ss_specificationFilter
+ {
+ subtreeSpecificationComponentsMonitor.useComponent( "specificationFilter" );
+ }
;
-
+ exception
+ catch [IllegalArgumentException e]
+ {
+ throw new RecognitionException( e.getMessage() );
+ }
ss_base
{
log.debug( "entered ss_base()" );
Name base = null;
-} :
- "base" ( SP )+ base=localName
+}
+ :
+ ID_base ( SP )+ base=distinguishedName
{
ssModifier.setBase( base );
}
;
-
ss_specificExclusions
{
log.debug( "entered ss_specificExclusions()" );
-} :
- "specificExclusions" ( SP )+ specificExclusions
+}
+ :
+ ID_specificExclusions ( SP )+ specificExclusions
{
ssModifier.setChopBeforeExclusions( chopBeforeExclusions );
ssModifier.setChopAfterExclusions( chopAfterExclusions );
}
;
-
specificExclusions
{
log.debug( "entered specificExclusions()" );
-} :
- LBRACKET
- ( ( SP )* specificExclusion
- ( SEP ( SP )* specificExclusion )*
+}
+ :
+ OPEN_CURLY ( SP )*
+ ( specificExclusion ( SP )*
+ ( SEP ( SP )* specificExclusion ( SP )* )*
)?
- SP RBRACKET
+ CLOSE_CURLY
;
-
specificExclusion
{
log.debug( "entered specificExclusion()" );
-} :
+}
+ :
chopBefore | chopAfter
;
-
chopBefore
{
log.debug( "entered chopBefore()" );
Name chopBeforeExclusion = null;
-} :
- "chopBefore" COLON chopBeforeExclusion=localName
+}
+ :
+ ID_chopBefore ( SP )* COLON ( SP )* chopBeforeExclusion=distinguishedName
{
chopBeforeExclusions.add( chopBeforeExclusion );
}
;
-
chopAfter
{
log.debug( "entered chopAfter()" );
Name chopAfterExclusion = null;
-} :
- "chopAfter" COLON chopAfterExclusion=localName
+}
+ :
+ ID_chopAfter ( SP )* COLON ( SP )* chopAfterExclusion=distinguishedName
{
chopAfterExclusions.add( chopAfterExclusion );
}
;
-
ss_minimum
{
log.debug( "entered ss_minimum()" );
int minimum = 0;
-} :
- "minimum" ( SP )+ minimum=baseDistance
+}
+ :
+ ID_minimum ( SP )+ minimum=baseDistance
{
ssModifier.setMinBaseDistance( minimum );
}
;
-
ss_maximum
{
log.debug( "entered ss_maximum()" );
int maximum = 0;
-} :
- "maximum" ( SP )+ maximum=baseDistance
+}
+ :
+ ID_maximum ( SP )+ maximum=baseDistance
{
ssModifier.setMaxBaseDistance( maximum );
}
;
-
ss_specificationFilter
{
log.debug( "entered ss_specificationFilter()" );
ExprNode theRefinement = null;
-}:
- "specificationFilter" ( SP )+ theRefinement=refinement
+}
+ :
+ ID_specificationFilter ( SP )+ theRefinement=refinement
{
ssModifier.setRefinement( theRefinement );
}
;
-
-
-localName returns [Name name]
+
+distinguishedName returns [ Name name ]
{
- log.debug( "entered localName()" );
+ log.debug( "entered distinguishedName()" );
name = null;
-} :
- token:DQUOTEDSTRING
+}
+ :
+ token:SAFEUTF8STRING
{
name = dnParser.parse( token.getText() );
+ log.debug( "recognized a DistinguishedName: " + token.getText() );
}
;
exception
catch [Exception e]
{
- throw new RecognitionException( "dnParser failed." + e.getMessage() );
+ throw new RecognitionException( "dnParser failed for " + token.getText() + " " + e.getMessage() );
}
-
-baseDistance returns [int distance]
+baseDistance returns [ int distance ]
{
log.debug( "entered baseDistance()" );
distance = 0;
-} :
- token:NUMBER
+}
+ :
+ token:INTEGER
{
- distance = Integer.parseInt( token.getText() );
+ distance = token2Integer( token );
}
;
+oid returns [ String result ]
+{
+ log.debug( "entered oid()" );
+ result = null;
+ Token token = null;
+}
+ :
+ { token = LT( 1 ); } // an interesting trick goes here ;-)
+ ( DESCR | NUMERICOID )
+ {
+ result = token.getText();
+ log.debug( "recognized an oid: " + result );
+ }
+ ;
-refinement returns [ExprNode node]
+refinement returns [ ExprNode node ]
{
log.debug( "entered refinement()" );
node = null;
-} :
+}
+ :
node=item | node=and | node=or | node=not
;
-
-item returns [LeafNode node]
+item returns [ LeafNode node ]
{
log.debug( "entered item()" );
node = null;
- String oid = null;
-} :
- "item" COLON oid=objectIdentifier
- {
- node = new SimpleNode( "objectClass" , oid , AbstractExprNode.EQUALITY );
- }
- ;
-
-
-objectIdentifier returns [String oid]
-{
- oid = null;
-} :
- token1:DESCR
- {
- oid = token1.getText();
- }
- |
- token2:NUMERICOID
+ String l_oid = null;
+}
+ :
+ ID_item ( SP )* COLON ( SP )* l_oid=oid
{
- oid = token2.getText();
+ node = new SimpleNode( "objectClass" , l_oid , AbstractExprNode.EQUALITY );
}
;
-
-and returns [BranchNode node]
+and returns [ BranchNode node ]
{
log.debug( "entered and()" );
node = null;
ArrayList children = null;
-} :
- "and" COLON children=refinements
+}
+ :
+ ID_and ( SP )* COLON ( SP )* children=refinements
{
node = new BranchNode( AbstractExprNode.AND , children );
}
;
-
-or returns [BranchNode node]
+or returns [ BranchNode node ]
{
log.debug( "entered or()" );
node = null;
ArrayList children = null;
-} :
- "or" COLON children=refinements
+}
+ :
+ ID_or ( SP )* COLON ( SP )* children=refinements
{
node = new BranchNode( AbstractExprNode.OR , children );
}
;
-
-not returns [BranchNode node]
+not returns [ BranchNode node ]
{
log.debug( "entered not()" );
node = null;
ArrayList children = null;
-} :
- "not" COLON children=refinements
+}
+ :
+ ID_not ( SP )* COLON ( SP )* children=refinements
{
node = new BranchNode( AbstractExprNode.NOT , children );
}
;
-
-refinements returns [ArrayList children]
+refinements returns [ ArrayList children ]
{
log.debug( "entered refinements()" );
children = null;
ExprNode child = null;
ArrayList tempChildren = new ArrayList();
-} :
- LBRACKET
- ( SP
- child=refinement
+}
+ :
+ OPEN_CURLY ( SP )*
+ (
+ child=refinement ( SP )*
{
tempChildren.add( child );
}
- ( SEP ( SP )* child=refinement
+ ( SEP ( SP )* child=refinement ( SP )*
{
tempChildren.add( child );
} )*
- )? ( SP )* RBRACKET
+ )? CLOSE_CURLY
{
children = tempChildren;
}
;
+//subtreeSpecification returns [SubtreeSpecification ss]
+//{
+// log.debug( "entered subtreeSpecification()" );
+// // clear out ss and ssModifier in case something is left from the last parse
+// ss = null;
+// ssModifier = new SubtreeSpecificationModifier();
+//} :
+// LBRACKET ( SP )*
+// (
+// (
+// ss_base ss_base_follower
+// | ss_specificExclusions ss_specificExclusions_follower
+// | ss_minimum ss_minimum_follower
+// | ss_maximum ss_maximum_follower
+// | ss_specificationFilter
+// )
+// ( SP )*
+// )?
+// RBRACKET
+// {
+// ss = ssModifier.getSubtreeSpecification();
+// }
+// ;
+//
+//
+//ss_base_follower
+// :
+// ( SEP ( SP )*
+// (
+// ss_specificExclusions ss_specificExclusions_follower
+// | ss_minimum ss_minimum_follower
+// | ss_maximum ss_maximum_follower
+// | ss_specificationFilter
+// )
+// )?
+// ;
+//
+//
+//ss_specificExclusions_follower
+// :
+// ( SEP ( SP )*
+// (
+// ss_minimum ss_minimum_follower
+// | ss_maximum ss_maximum_follower
+// | ss_specificationFilter
+// )
+// )?
+// ;
+//
+//
+//ss_minimum_follower
+// :
+// ( SEP ( SP )*
+// (
+// ss_maximum ss_maximum_follower
+// | ss_specificationFilter
+// )
+// )?
+// ;
+//
+//
+//ss_maximum_follower
+// :
+// ( SEP ( SP )*
+// (
+// ss_specificationFilter
+// )
+// )?
+// ;
+//
+//
+//ss_base
+//{
+// log.debug( "entered ss_base()" );
+// Name base = null;
+//} :
+// "base" ( SP )+ base=localName
+// {
+// ssModifier.setBase( base );
+// }
+// ;
+//
+//
+//ss_specificExclusions
+//{
+// log.debug( "entered ss_specificExclusions()" );
+//} :
+// "specificExclusions" ( SP )+ specificExclusions
+// {
+// ssModifier.setChopBeforeExclusions( chopBeforeExclusions );
+// ssModifier.setChopAfterExclusions( chopAfterExclusions );
+// }
+// ;
+//
+//
+//specificExclusions
+//{
+// log.debug( "entered specificExclusions()" );
+//} :
+// LBRACKET
+// ( ( SP )* specificExclusion
+// ( SEP ( SP )* specificExclusion )*
+// )?
+// SP RBRACKET
+// ;
+//
+//
+//specificExclusion
+//{
+// log.debug( "entered specificExclusion()" );
+//} :
+// chopBefore | chopAfter
+// ;
+//
+//
+//chopBefore
+//{
+// log.debug( "entered chopBefore()" );
+// Name chopBeforeExclusion = null;
+//} :
+// "chopBefore" COLON chopBeforeExclusion=localName
+// {
+// chopBeforeExclusions.add( chopBeforeExclusion );
+// }
+// ;
+//
+//
+//chopAfter
+//{
+// log.debug( "entered chopAfter()" );
+// Name chopAfterExclusion = null;
+//} :
+// "chopAfter" COLON chopAfterExclusion=localName
+// {
+// chopAfterExclusions.add( chopAfterExclusion );
+// }
+// ;
+//
+//
+//ss_minimum
+//{
+// log.debug( "entered ss_minimum()" );
+// int minimum = 0;
+//} :
+// "minimum" ( SP )+ minimum=baseDistance
+// {
+// ssModifier.setMinBaseDistance( minimum );
+// }
+// ;
+//
+//
+//ss_maximum
+//{
+// log.debug( "entered ss_maximum()" );
+// int maximum = 0;
+//} :
+// "maximum" ( SP )+ maximum=baseDistance
+// {
+// ssModifier.setMaxBaseDistance( maximum );
+// }
+// ;
+//
+//
+//ss_specificationFilter
+//{
+// log.debug( "entered ss_specificationFilter()" );
+// ExprNode theRefinement = null;
+//}:
+// "specificationFilter" ( SP )+ theRefinement=refinement
+// {
+// ssModifier.setRefinement( theRefinement );
+// }
+// ;
+//
+//
+//localName returns [Name name]
+//{
+// log.debug( "entered localName()" );
+// name = null;
+//} :
+// token:DQUOTEDSTRING
+// {
+// name = dnParser.parse( token.getText() );
+// }
+// ;
+// exception
+// catch [Exception e]
+// {
+// throw new RecognitionException( "dnParser failed." + e.getMessage() );
+// }
+//
+//
+//baseDistance returns [int distance]
+//{
+// log.debug( "entered baseDistance()" );
+// distance = 0;
+//} :
+// token:NUMBER
+// {
+// distance = Integer.parseInt( token.getText() );
+// }
+// ;
+//
+//
+//refinement returns [ExprNode node]
+//{
+// log.debug( "entered refinement()" );
+// node = null;
+//} :
+// node=item | node=and | node=or | node=not
+// ;
+//
+//
+//item returns [LeafNode node]
+//{
+// log.debug( "entered item()" );
+// node = null;
+// String oid = null;
+//} :
+// "item" COLON oid=objectIdentifier
+// {
+// node = new SimpleNode( "objectClass" , oid , AbstractExprNode.EQUALITY );
+// }
+// ;
+//
+//
+//objectIdentifier returns [String oid]
+//{
+// oid = null;
+//} :
+// token1:DESCR
+// {
+// oid = token1.getText();
+// }
+// |
+// token2:NUMERICOID
+// {
+// oid = token2.getText();
+// }
+// ;
+//
+//
+//and returns [BranchNode node]
+//{
+// log.debug( "entered and()" );
+// node = null;
+// ArrayList children = null;
+//} :
+// "and" COLON children=refinements
+// {
+// node = new BranchNode( AbstractExprNode.AND , children );
+// }
+// ;
+//
+//
+//or returns [BranchNode node]
+//{
+// log.debug( "entered or()" );
+// node = null;
+// ArrayList children = null;
+//} :
+// "or" COLON children=refinements
+// {
+// node = new BranchNode( AbstractExprNode.OR , children );
+// }
+// ;
+//
+//
+//not returns [BranchNode node]
+//{
+// log.debug( "entered not()" );
+// node = null;
+// ArrayList children = null;
+//} :
+// "not" COLON children=refinements
+// {
+// node = new BranchNode( AbstractExprNode.NOT , children );
+// }
+// ;
+//
+//
+//refinements returns [ArrayList children]
+//{
+// log.debug( "entered refinements()" );
+// children = null;
+// ExprNode child = null;
+// ArrayList tempChildren = new ArrayList();
+//} :
+// LBRACKET
+// ( SP
+// child=refinement
+// {
+// tempChildren.add( child );
+// }
+// ( SEP ( SP )* child=refinement
+// {
+// tempChildren.add( child );
+// } )*
+// )? ( SP )* RBRACKET
+// {
+// children = tempChildren;
+// }
+// ;
+
// ----------------------------------------------------------------------------
// lexer class definition
@@ -471,8 +777,21 @@
k = 2;
charVocabulary = '\u0001'..'\u0127';
+}
- testLiterals = false;
+tokens
+{
+ ID_base = "base";
+ ID_specificExclusions = "specificExclusions";
+ ID_chopBefore = "chopBefore";
+ ID_chopAfter = "chopAfter";
+ ID_minimum = "minimum";
+ ID_maximum = "maximum";
+ ID_specificationFilter = "specificationFilter";
+ ID_item = "item";
+ ID_and = "and";
+ ID_or = "or";
+ ID_not = "not";
}
@@ -493,36 +812,32 @@
COLON : ':' { log.debug( "matched COLON(':')" ); } ;
-LBRACKET : '{' { log.debug( "matched LBRACKET('{')" ); } ;
+OPEN_CURLY : '{' { log.debug( "matched LBRACKET('{')" ); } ;
-RBRACKET : '}' { log.debug( "matched RBRACKET('}')" ); } ;
-
-DQUOTE : '"' { log.debug( "matched DQUOTE('\"')" ); } ;
+CLOSE_CURLY : '}' { log.debug( "matched RBRACKET('}')" ); } ;
SEP : ',' { log.debug( "matched SEP(',')" ); } ;
-DQUOTEDSTRING : DQUOTE! ( SAFEUTF8CHAR )* DQUOTE! { log.debug( "matched DQUOTEDSTRING: \"" + getText() + "\"" ); } ;
-
-DESCR options { testLiterals = true; } : ALPHA ( ALPHA | DIGIT | '-' )* { log.debug( "matched DESCR" ); } ;
+SAFEUTF8STRING : '"'! ( SAFEUTF8CHAR )* '"'! { log.debug( "matched SAFEUTF8CHAR: \"" + getText() + "\"" ); } ;
-// This rule is required to prevent nondeterminism problem caused by NUMBER and NUMERICOID rules.
+DESCR : ALPHA ( ALPHA | DIGIT | '-' )* { log.debug( "matched DESCR" ); } ;
-NUMBER_OR_NUMERICOID
+INTEGER_OR_NUMERICOID
:
- ( NUMBER DOT ) => NUMERICOID
+ ( INTEGER DOT ) => NUMERICOID
{
- $setType(NUMERICOID);
+ $setType( NUMERICOID );
}
|
- NUMBER
+ INTEGER
{
- $setType(NUMBER);
+ $setType( INTEGER );
}
;
-protected NUMBER: DIGIT | ( LDIGIT ( DIGIT )+ ) { log.debug( "matched NUMBER: " + getText() ); } ;
+protected INTEGER: DIGIT | ( LDIGIT ( DIGIT )+ ) { log.debug( "matched INTEGER: " + getText() ); } ;
-protected NUMERICOID: NUMBER ( DOT NUMBER )+ { log.debug( "matched NUMERICOID: " + getText() ); } ;
+protected NUMERICOID: INTEGER ( DOT INTEGER )+ { log.debug( "matched NUMERICOID: " + getText() ); } ;
protected DOT: '.' ;
Modified: directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/subtree/SubtreeSpecificationParserTest.java
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/subtree/SubtreeSpecificationParserTest.java?rev=331857&r1=331856&r2=331857&view=diff
==============================================================================
--- directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/subtree/SubtreeSpecificationParserTest.java (original)
+++ directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/subtree/SubtreeSpecificationParserTest.java Tue Nov 8 10:22:19 2005
@@ -90,8 +90,8 @@
", minimum 7, maximum 77" +
", specificationFilter and:{ and:{ item:1.2.3, or:{ item:4.5.6, item:7.8.9 } }, not:{ item:10.11.12 } } }";
- /** An invalid specification with wrong component order */
- private static final String INVALID_SPEC_WITH_WRONG_COMPONENT_ORDER =
+ /** An valid specification with unordinary component order */
+ private static final String SPEC_ORDER_OF_COMPONENTS_DOES_NOT_MATTER =
"{ base \"ou=system\", minimum 3, specificExclusions { chopBefore:\"x=y\" } }";
/** An invalid specification with completely unrelated content */
@@ -316,19 +316,12 @@
/**
- * Tests the parser with an invalid specification with wrong component order.
+ * Tests the parser with a valid specification with unordinary component order.
*/
- public void testInvalidSpecWithWrongComponentOrder() throws Exception
- {
- try
- {
- parser.parse( INVALID_SPEC_WITH_WRONG_COMPONENT_ORDER );
- fail( "testInvalidSpecWithWrongComponentOrder() should never come here..." );
- }
- catch ( ParseException e )
- {
- assertNotNull( e );
- }
+ public void testSpecOrderOfComponentsDoesNotMatter() throws Exception
+ {
+ SubtreeSpecification ss = parser.parse( SPEC_ORDER_OF_COMPONENTS_DOES_NOT_MATTER );
+ assertNotNull( ss );
}