Index: common/src/test/org/apache/ldap/common/subtree/SubtreeSpecificationParserTest.java =================================================================== --- common/src/test/org/apache/ldap/common/subtree/SubtreeSpecificationParserTest.java (revision 264984) +++ common/src/test/org/apache/ldap/common/subtree/SubtreeSpecificationParserTest.java (working copy) @@ -30,6 +30,8 @@ import org.apache.ldap.common.filter.BranchNode; import org.apache.ldap.common.filter.SimpleNode; import org.apache.ldap.common.name.LdapName; +import org.apache.ldap.common.name.SimpleNameComponentNormalizer; +import org.apache.ldap.common.schema.DeepTrimNormalizer; import org.apache.ldap.common.subtree.SubtreeSpecification; @@ -104,6 +106,9 @@ private static final String INVALID_SILLY_THING = "How much wood would a wood chuck chuck if a wood chuck would chuck wood?"; + /** A valid specification only with base set and normalizing to be applied */ + private static final String SPEC_WITH_BASE_NORMALIZING = + "{ base \"ou=system \" }"; /** the ss parser wrapper */ SubtreeSpecificationParser parser; @@ -405,7 +410,23 @@ } } + /** + * Tests the parser with a valid specification with base set and normalizing active. + */ + public void testSpecWithBaseNormalizing() throws Exception + { + // create a new normalizing parser for this test case + SubtreeSpecificationParser parser = new SubtreeSpecificationParser( + new SimpleNameComponentNormalizer( + new DeepTrimNormalizer())); + SubtreeSpecification ss = parser.parse( SPEC_WITH_BASE_NORMALIZING ); + assertNotNull( ss ); + + // looking for "ou=system" and not "ou=system " due to normalizing + assertEquals( "ou=system" , ss.getBase().toString() ); + } + /** * Tests the multithreaded use of a single parser. */ Index: common/src/antlr/subtree-specification.g =================================================================== --- common/src/antlr/subtree-specification.g (revision 264984) +++ common/src/antlr/subtree-specification.g (working copy) @@ -28,6 +28,7 @@ import javax.naming.NamingException; import org.apache.ldap.common.name.DnParser; +import org.apache.ldap.common.name.NameComponentNormalizer; import org.apache.ldap.common.filter.ExprNode; import org.apache.ldap.common.filter.LeafNode; import org.apache.ldap.common.filter.SimpleNode; @@ -73,23 +74,35 @@ { private static final Logger log = LoggerFactory.getLogger( AntlrSubtreeSpecificationParser.class ); - private final DnParser dnParser = createDnParser(); + private DnParser dnParser; + private boolean isNormalizing = false; + NameComponentNormalizer normalizer; + private Set chopBeforeExclusions = new HashSet(); private Set chopAfterExclusions = new HashSet(); SubtreeSpecificationModifier ssModifier = null; /** - * Creates a subordinate DnParser for parsing LocalNames. + * Creates a (normalizing) subordinate DnParser for parsing LocalNames. + * This method MUST be called for each instance while we cannot do + * constructor overloading for this class. * * @return the DnParser to be used for parsing LocalNames */ - private DnParser createDnParser() + public void init() { try { - return new DnParser(); + if( isNormalizing ) + { + dnParser = new DnParser( normalizer ); + } + else + { + dnParser = new DnParser(); + } } catch ( NamingException e ) { @@ -101,6 +114,15 @@ throw new NullPointerException( "dnParser is null: " + msg ); } } + + /** + * Sets the NameComponentNormalizer for this parser's dnParser. + */ + public void setNormalizer(NameComponentNormalizer normalizer) + { + this.normalizer = normalizer; + this.isNormalizing = true; + } } Index: common/src/java/org/apache/ldap/common/subtree/SubtreeSpecificationParser.java =================================================================== --- common/src/java/org/apache/ldap/common/subtree/SubtreeSpecificationParser.java (revision 264984) +++ common/src/java/org/apache/ldap/common/subtree/SubtreeSpecificationParser.java (working copy) @@ -21,6 +21,8 @@ import java.io.StringReader; import java.text.ParseException; +import org.apache.ldap.common.name.NameComponentNormalizer; + import antlr.RecognitionException; import antlr.TokenStreamException; @@ -42,6 +44,7 @@ /** the antlr generated lexer being wrapped */ private ReusableAntlrSubtreeSpecificationLexer lexer; + private final boolean isNormalizing; /** * Creates a subtree specification parser. @@ -51,7 +54,25 @@ StringReader in = new StringReader(""); // place holder for the first input this.lexer = new ReusableAntlrSubtreeSpecificationLexer( in ); this.parser = new ReusableAntlrSubtreeSpecificationParser( lexer ); + this.parser.init(); // this method MUST be called while we cannot do + // constructor overloading for antlr generated parser + this.isNormalizing = false; } + + /** + * Creates a normalizing subtree specification parser. + */ + public SubtreeSpecificationParser(NameComponentNormalizer normalizer) + { + StringReader in = new StringReader(""); // place holder for the first input + this.lexer = new ReusableAntlrSubtreeSpecificationLexer( in ); + this.parser = new ReusableAntlrSubtreeSpecificationParser( lexer ); + + this.parser.setNormalizer( normalizer ); + this.parser.init(); // this method MUST be called while we cannot do + // constructor overloading for antlr generated parser + this.isNormalizing = true; + } /** @@ -106,4 +127,14 @@ return ss; } + + /** + * Tests to see if this parser is normalizing. + * + * @return true if it normalizes false otherwise + */ + public boolean isNormizing() + { + return this.isNormalizing ; + } }