You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2006/12/20 17:14:56 UTC
svn commit: r489128 - in /directory/trunks/shared/ldap/src: main/antlr/
main/java/org/apache/directory/shared/ldap/aci/
test/java/org/apache/directory/shared/ldap/aci/
Author: elecharny
Date: Wed Dec 20 08:14:55 2006
New Revision: 489128
URL: http://svn.apache.org/viewvc?view=rev&rev=489128
Log:
Added a syntax checker for ACI Item
Added the related tests
the tests don't check that an element is not duplicated nor that it is missing
Added:
directory/trunks/shared/ldap/src/main/antlr/ACIItemChecker.g
directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ACIItemChecker.java
directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ReusableAntlrACIItemChecker.java
directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ReusableAntlrACIItemCheckerLexer.java
directory/trunks/shared/ldap/src/test/java/org/apache/directory/shared/ldap/aci/ACIItemChekerTest.java
Added: directory/trunks/shared/ldap/src/main/antlr/ACIItemChecker.g
URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/main/antlr/ACIItemChecker.g?view=auto&rev=489128
==============================================================================
--- directory/trunks/shared/ldap/src/main/antlr/ACIItemChecker.g (added)
+++ directory/trunks/shared/ldap/src/main/antlr/ACIItemChecker.g Wed Dec 20 08:14:55 2006
@@ -0,0 +1,822 @@
+header
+{
+/*
+ * 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.aci;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Enumeration;
+
+import javax.naming.directory.Attribute;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.NamingException;
+
+import org.apache.directory.shared.ldap.filter.AssertionEnum;
+import org.apache.directory.shared.ldap.filter.BranchNode;
+import org.apache.directory.shared.ldap.filter.ExprNode;
+import org.apache.directory.shared.ldap.filter.FilterParserImpl;
+import org.apache.directory.shared.ldap.filter.LeafNode;
+import org.apache.directory.shared.ldap.filter.SimpleNode;
+import org.apache.directory.shared.ldap.name.NameComponentNormalizer;
+import org.apache.directory.shared.ldap.subtree.SubtreeSpecification;
+import org.apache.directory.shared.ldap.subtree.SubtreeSpecificationModifier;
+import org.apache.directory.shared.ldap.util.ComponentsMonitor;
+import org.apache.directory.shared.ldap.util.MandatoryAndOptionalComponentsMonitor;
+import org.apache.directory.shared.ldap.util.MandatoryComponentsMonitor;
+import org.apache.directory.shared.ldap.util.NamespaceTools;
+import org.apache.directory.shared.ldap.util.NoDuplicateKeysMap;
+import org.apache.directory.shared.ldap.util.OptionalComponentsMonitor;
+import org.apache.directory.shared.ldap.name.LdapDN;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+}
+
+
+// ----------------------------------------------------------------------------
+// parser class definition
+// ----------------------------------------------------------------------------
+
+/**
+ * The antlr generated ACIItem checker.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+class AntlrACIItemChecker extends Parser;
+
+
+// ----------------------------------------------------------------------------
+// parser options
+// ----------------------------------------------------------------------------
+
+options
+{
+ k = 1; // ;-)
+ defaultErrorHandler = false;
+}
+
+
+// ----------------------------------------------------------------------------
+// imaginary tokens
+// ----------------------------------------------------------------------------
+
+tokens
+{
+ ATTRIBUTE_VALUE_CANDIDATE;
+ RANGE_OF_VALUES_CANDIDATE;
+}
+
+
+// ----------------------------------------------------------------------------
+// parser initialization
+// ----------------------------------------------------------------------------
+
+{
+ // subordinate parser instances
+ private final FilterParserImpl filterParser = new FilterParserImpl();
+
+ private boolean isNormalizing = false;
+ NameComponentNormalizer normalizer;
+
+ /**
+ * Creates a (normalizing) subordinate DnParser for parsing Names.
+ * 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 Names
+ */
+ public void init()
+ {
+ }
+
+ /**
+ * Sets the NameComponentNormalizer for this parser's dnParser.
+ */
+ public void setNormalizer(NameComponentNormalizer normalizer)
+ {
+ 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;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// parser productions
+// ----------------------------------------------------------------------------
+
+wrapperEntryPoint
+ :
+ ( SP )* theACIItem ( SP )* EOF
+ ;
+
+theACIItem
+ :
+ OPEN_CURLY
+ ( SP )* mainACIItemComponent ( SP )*
+ ( SEP ( SP )* mainACIItemComponent ( SP )* )*
+ CLOSE_CURLY
+ ;
+
+mainACIItemComponent
+ :
+ aci_identificationTag
+ | aci_precedence
+ | aci_authenticationLevel
+ | aci_itemOrUserFirst
+ ;
+
+aci_identificationTag
+ :
+ ID_identificationTag ( SP )+ SAFEUTF8STRING
+ ;
+
+aci_precedence
+ :
+ precedence
+ ;
+
+precedence
+ :
+ ID_precedence ( SP )+ INTEGER
+ ;
+
+aci_authenticationLevel
+ :
+ ID_authenticationLevel ( SP )+ authenticationLevel
+ ;
+
+authenticationLevel
+ :
+ ID_none
+ |
+ ID_simple
+ |
+ ID_strong
+ ;
+
+aci_itemOrUserFirst
+ :
+ ID_itemOrUserFirst ( SP )+ itemOrUserFirst
+ ;
+
+itemOrUserFirst
+ :
+ itemFirst | userFirst
+ ;
+
+itemFirst
+ :
+ ID_itemFirst ( SP )* COLON ( SP )*
+ OPEN_CURLY ( SP )*
+ (
+ protectedItems ( SP )*
+ SEP ( SP )* itemPermissions
+ | // relaxing
+ itemPermissions ( SP )*
+ SEP ( SP )* protectedItems
+ )
+ ( SP )* CLOSE_CURLY
+ ;
+
+userFirst
+ :
+ ID_userFirst ( SP )* COLON ( SP )*
+ OPEN_CURLY ( SP )*
+ (
+ userClasses ( SP )*
+ SEP ( SP )* userPermissions
+ | // relaxing
+ userPermissions ( SP )*
+ SEP ( SP )* userClasses
+ )
+ ( SP )* CLOSE_CURLY
+ ;
+
+protectedItems
+ :
+ ID_protectedItems ( SP )*
+ OPEN_CURLY ( SP )*
+ (
+ protectedItem ( SP )*
+ ( SEP ( SP )* protectedItem ( SP )* )*
+ )?
+ CLOSE_CURLY
+ ;
+
+protectedItem
+ :
+ entry
+ | allUserAttributeTypes
+ | attributeType
+ | allAttributeValues
+ | allUserAttributeTypesAndValues
+ | attributeValue
+ | selfValue
+ | rangeOfValues
+ | maxValueCount
+ | maxImmSub
+ | restrictedBy
+ | classes
+ ;
+
+entry
+ :
+ ID_entry
+ ;
+
+allUserAttributeTypes
+ :
+ ID_allUserAttributeTypes
+ ;
+
+attributeType
+ :
+ ID_attributeType ( SP )+ attributeTypeSet
+ ;
+
+allAttributeValues
+ :
+ ID_allAttributeValues ( SP )+ attributeTypeSet
+ ;
+
+allUserAttributeTypesAndValues
+ :
+ ID_allUserAttributeTypesAndValues
+ ;
+
+attributeValue
+ :
+ ATTRIBUTE_VALUE_CANDIDATE // ate the identifier for subordinate dn parser workaround
+ ;
+
+selfValue
+ :
+ ID_selfValue ( SP )+ attributeTypeSet
+ ;
+
+rangeOfValues
+ :
+ RANGE_OF_VALUES_CANDIDATE
+ ;
+
+maxValueCount
+ :
+ ID_maxValueCount ( SP )+
+ OPEN_CURLY ( SP )*
+ aMaxValueCount ( SP )*
+ ( SEP ( SP )* aMaxValueCount ( SP )*
+ )*
+ CLOSE_CURLY
+ ;
+
+aMaxValueCount
+ :
+ OPEN_CURLY ( SP )*
+ (
+ ID_type ( SP )+ oid ( SP )* SEP ( SP )*
+ ID_maxCount ( SP )+ INTEGER
+ | // relaxing
+ ID_maxCount ( SP )+ INTEGER ( SP )* SEP ( SP )*
+ ID_type ( SP )+ oid
+ )
+ ( SP )* CLOSE_CURLY
+ ;
+
+maxImmSub
+ :
+ ID_maxImmSub ( SP )+ INTEGER
+ ;
+
+restrictedBy
+ :
+ ID_restrictedBy ( SP )+
+ OPEN_CURLY ( SP )*
+ restrictedValue ( SP )*
+ ( SEP ( SP )* restrictedValue ( SP )*
+ )*
+ CLOSE_CURLY
+ ;
+
+restrictedValue
+ :
+ OPEN_CURLY ( SP )*
+ (
+ ID_type ( SP )+ oid ( SP )* SEP ( SP )*
+ ID_valuesIn ( SP )+ oid
+ | // relaxing
+ ID_valuesIn ( SP )+ oid ( SP )* SEP ( SP )*
+ ID_type ( SP )+ oid
+ )
+ ( SP )* CLOSE_CURLY
+ ;
+
+attributeTypeSet
+ :
+ OPEN_CURLY ( SP )*
+ oid ( SP )*
+ ( SEP ( SP )* oid ( SP )*
+ )*
+ CLOSE_CURLY
+ ;
+
+classes
+ :
+ ID_classes ( SP )+ refinement
+ ;
+
+itemPermissions
+ :
+ ID_itemPermissions ( SP )+
+ OPEN_CURLY ( SP )*
+ ( itemPermission ( SP )*
+ ( SEP ( SP )* itemPermission ( SP )*
+ )*
+ )?
+ CLOSE_CURLY
+ ;
+
+itemPermission
+ :
+ OPEN_CURLY ( SP )*
+ anyItemPermission ( SP )*
+ ( SEP ( SP )* anyItemPermission ( SP )* )*
+ CLOSE_CURLY
+ ;
+
+anyItemPermission
+ :
+ precedence
+ | userClasses
+ | grantsAndDenials
+ ;
+
+grantsAndDenials
+ :
+ ID_grantsAndDenials ( SP )+
+ OPEN_CURLY ( SP )*
+ ( grantAndDenial ( SP )*
+ ( SEP ( SP )* grantAndDenial ( SP )*
+ )*
+ )?
+ CLOSE_CURLY
+ ;
+
+grantAndDenial
+ :
+ ID_grantAdd
+ | ID_denyAdd
+ | ID_grantDiscloseOnError
+ | ID_denyDiscloseOnError
+ | ID_grantRead
+ | ID_denyRead
+ | ID_grantRemove
+ | ID_denyRemove
+ //-- permissions that may be used only in conjunction
+ //-- with the entry component
+ | ID_grantBrowse
+ | ID_denyBrowse
+ | ID_grantExport
+ | ID_denyExport
+ | ID_grantImport
+ | ID_denyImport
+ | ID_grantModify
+ | ID_denyModify
+ | ID_grantRename
+ | ID_denyRename
+ | ID_grantReturnDN
+ | ID_denyReturnDN
+ //-- permissions that may be used in conjunction
+ //-- with any component, except entry, of ProtectedItems
+ | ID_grantCompare
+ | ID_denyCompare
+ | ID_grantFilterMatch
+ | ID_denyFilterMatch
+ | ID_grantInvoke
+ | ID_denyInvoke
+ ;
+
+userClasses
+ :
+ ID_userClasses ( SP )+
+ OPEN_CURLY ( SP )*
+ (
+ userClass ( SP )*
+ ( SEP ( SP )* userClass ( SP )* )*
+ )?
+ CLOSE_CURLY
+ ;
+
+userClass
+ :
+ allUsers
+ | thisEntry
+ | name
+ | userGroup
+ | subtree
+ ;
+
+allUsers
+ :
+ ID_allUsers
+ ;
+
+thisEntry
+ :
+ ID_thisEntry
+ ;
+
+name
+ :
+ ID_name ( SP )+
+ OPEN_CURLY ( SP )*
+ distinguishedName ( SP )*
+ ( SEP ( SP )* distinguishedName ( SP )*
+ )*
+ CLOSE_CURLY
+ ;
+
+userGroup
+ :
+ ID_userGroup ( SP )+
+ OPEN_CURLY ( SP )*
+ distinguishedName ( SP )*
+ ( SEP ( SP )* distinguishedName ( SP )* )*
+ CLOSE_CURLY
+ ;
+
+subtree
+ :
+ ID_subtree ( SP )+
+ OPEN_CURLY ( SP )*
+ subtreeSpecification ( SP )*
+ ( SEP ( SP )* subtreeSpecification ( SP )* )*
+ CLOSE_CURLY
+ ;
+
+userPermissions
+ :
+ ID_userPermissions ( SP )+
+ OPEN_CURLY ( SP )*
+ ( userPermission ( SP )*
+ ( SEP ( SP )* userPermission ( SP )* )*
+ )?
+ CLOSE_CURLY
+ ;
+
+userPermission
+ :
+ OPEN_CURLY ( SP )*
+ anyUserPermission ( SP )*
+ ( SEP ( SP )* anyUserPermission ( SP )* )*
+ CLOSE_CURLY
+ ;
+
+anyUserPermission
+ :
+ precedence
+ | protectedItems
+ | grantsAndDenials
+ ;
+
+subtreeSpecification
+ :
+ OPEN_CURLY ( SP )*
+ ( subtreeSpecificationComponent ( SP )*
+ ( SEP ( SP )* subtreeSpecificationComponent ( SP )* )* )?
+ CLOSE_CURLY
+ ;
+
+subtreeSpecificationComponent
+ :
+ ss_base
+ | ss_specificExclusions
+ | ss_minimum
+ | ss_maximum
+ ;
+
+ss_base
+ :
+ ID_base ( SP )+ distinguishedName
+ ;
+
+ss_specificExclusions
+ :
+ ID_specificExclusions ( SP )+ specificExclusions
+ ;
+
+specificExclusions
+ :
+ OPEN_CURLY ( SP )*
+ ( specificExclusion ( SP )*
+ ( SEP ( SP )* specificExclusion ( SP )* )*
+ )?
+ CLOSE_CURLY
+ ;
+
+specificExclusion
+ :
+ chopBefore | chopAfter
+ ;
+
+chopBefore
+ :
+ ID_chopBefore ( SP )* COLON ( SP )* distinguishedName
+ ;
+
+chopAfter
+ :
+ ID_chopAfter ( SP )* COLON ( SP )* distinguishedName
+ ;
+
+ss_minimum
+ :
+ ID_minimum ( SP )+ baseDistance
+ ;
+
+ss_maximum
+ :
+ ID_maximum ( SP )+ baseDistance
+ ;
+
+distinguishedName
+ :
+ SAFEUTF8STRING
+ ;
+
+baseDistance
+ :
+ INTEGER
+ ;
+
+oid
+ :
+ ( DESCR | NUMERICOID )
+ ;
+
+refinement
+ :
+ item | and | or | not
+ ;
+
+item
+ :
+ ID_item ( SP )* COLON ( SP )* oid
+ ;
+
+and
+ :
+ ID_and ( SP )* COLON ( SP )* refinements
+ ;
+
+or
+ :
+ ID_or ( SP )* COLON ( SP )* refinements
+ ;
+
+not
+ :
+ ID_not ( SP )* COLON ( SP )* refinements
+ ;
+
+refinements
+ :
+ OPEN_CURLY ( SP )*
+ (
+ refinement ( SP )*
+ ( SEP ( SP )* refinement ( SP )* )*
+ )? CLOSE_CURLY
+ ;
+
+
+// ----------------------------------------------------------------------------
+// lexer class definition
+// ----------------------------------------------------------------------------
+
+/**
+ * The parser's primary lexer.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+class AntlrACIItemCheckerLexer extends Lexer;
+
+
+// ----------------------------------------------------------------------------
+// lexer options
+// ----------------------------------------------------------------------------
+
+options
+{
+ k = 2;
+ charVocabulary = '\3'..'\377';
+}
+
+
+//----------------------------------------------------------------------------
+// tokens
+//----------------------------------------------------------------------------
+
+tokens
+{
+ ID_identificationTag = "identificationTag";
+ ID_precedence = "precedence";
+ ID_FALSE = "FALSE";
+ ID_TRUE = "TRUE";
+ ID_none = "none";
+ ID_simple = "simple";
+ ID_strong = "strong";
+ ID_level = "level";
+ ID_basicLevels = "basicLevels";
+ ID_localQualifier = "localQualifier";
+ ID_signed = "signed";
+ ID_authenticationLevel = "authenticationLevel";
+ ID_itemOrUserFirst = "itemOrUserFirst";
+ ID_itemFirst = "itemFirst";
+ ID_userFirst = "userFirst";
+ ID_protectedItems = "protectedItems";
+ ID_classes = "classes";
+ ID_entry = "entry";
+ ID_allUserAttributeTypes = "allUserAttributeTypes";
+ ID_attributeType = "attributeType";
+ ID_allAttributeValues = "allAttributeValues";
+ ID_allUserAttributeTypesAndValues = "allUserAttributeTypesAndValues";
+ ID_selfValue = "selfValue";
+ ID_item = "item";
+ ID_and = "and";
+ ID_or = "or";
+ ID_not = "not";
+ ID_rangeOfValues = "rangeOfValues";
+ ID_maxValueCount = "maxValueCount";
+ ID_type = "type";
+ ID_maxCount = "maxCount";
+ ID_maxImmSub = "maxImmSub";
+ ID_restrictedBy = "restrictedBy";
+ ID_valuesIn = "valuesIn";
+ ID_userClasses = "userClasses";
+ ID_base = "base";
+ ID_specificExclusions = "specificExclusions";
+ ID_chopBefore = "chopBefore";
+ ID_chopAfter = "chopAfter";
+ ID_minimum = "minimum";
+ ID_maximum = "maximum";
+ ID_specificationFilter = "specificationFilter";
+ ID_grantsAndDenials = "grantsAndDenials";
+ ID_itemPermissions = "itemPermissions";
+ ID_userPermissions = "userPermissions";
+ ID_allUsers = "allUsers";
+ ID_thisEntry = "thisEntry";
+ ID_subtree = "subtree";
+ ID_name = "name";
+ ID_userGroup = "userGroup";
+
+ ID_grantAdd = "grantAdd"; // (0),
+ ID_denyAdd = "denyAdd"; // (1),
+ ID_grantDiscloseOnError = "grantDiscloseOnError"; // (2),
+ ID_denyDiscloseOnError = "denyDiscloseOnError"; // (3),
+ ID_grantRead = "grantRead"; // (4),
+ ID_denyRead = "denyRead"; // (5),
+ ID_grantRemove = "grantRemove"; // (6),
+ ID_denyRemove = "denyRemove"; // (7),
+ //-- permissions that may be used only in conjunction
+ //-- with the entry component
+ ID_grantBrowse = "grantBrowse"; // (8),
+ ID_denyBrowse = "denyBrowse"; // (9),
+ ID_grantExport = "grantExport"; // (10),
+ ID_denyExport = "denyExport"; // (11),
+ ID_grantImport = "grantImport"; // (12),
+ ID_denyImport = "denyImport"; // (13),
+ ID_grantModify = "grantModify"; // (14),
+ ID_denyModify = "denyModify"; // (15),
+ ID_grantRename = "grantRename"; // (16),
+ ID_denyRename = "denyRename"; // (17),
+ ID_grantReturnDN = "grantReturnDN"; // (18),
+ ID_denyReturnDN = "denyReturnDN"; // (19),
+ //-- permissions that may be used in conjunction
+ //-- with any component, except entry, of ProtectedItems
+ ID_grantCompare = "grantCompare"; // (20),
+ ID_denyCompare = "denyCompare"; // (21),
+ ID_grantFilterMatch = "grantFilterMatch"; // (22),
+ ID_denyFilterMatch = "denyFilterMatch"; // (23),
+ ID_grantInvoke = "grantInvoke"; // (24),
+ ID_denyInvoke = "denyInvoke"; // (25)
+}
+
+
+// ----------------------------------------------------------------------------
+// lexer initialization
+// ----------------------------------------------------------------------------
+
+
+// ----------------------------------------------------------------------------
+// attribute description lexer rules from models
+// ----------------------------------------------------------------------------
+
+// This is all messed up - could not figure out how to get antlr to represent
+// the safe UTF-8 character set from RFC 3642 for production SafeUTF8Character
+
+protected SAFEUTF8CHAR :
+ '\u0001'..'\u0021' |
+ '\u0023'..'\u007F' |
+ '\u00c0'..'\u00d6' |
+ '\u00d8'..'\u00f6' |
+ '\u00f8'..'\u00ff' |
+ '\u0100'..'\u1fff' |
+ '\u3040'..'\u318f' |
+ '\u3300'..'\u337f' |
+ '\u3400'..'\u3d2d' |
+ '\u4e00'..'\u9fff' |
+ '\uf900'..'\ufaff' ;
+
+OPEN_CURLY : '{' ;
+
+CLOSE_CURLY : '}' ;
+
+SEP : ',' ;
+
+SP : ' ' | '\t' | '\n' { newline(); } | '\r' ;
+
+COLON : ':' ;
+
+protected DIGIT : '0' | LDIGIT ;
+
+protected LDIGIT : '1'..'9' ;
+
+protected ALPHA : 'A'..'Z' | 'a'..'z' ;
+
+protected INTEGER : DIGIT | ( LDIGIT ( DIGIT )+ ) ;
+
+protected HYPHEN : '-' ;
+
+protected NUMERICOID : INTEGER ( DOT INTEGER )+ ;
+
+protected DOT : '.' ;
+
+INTEGER_OR_NUMERICOID
+ :
+ ( INTEGER DOT ) => NUMERICOID
+ {
+ $setType( NUMERICOID );
+ }
+ |
+ INTEGER
+ {
+ $setType( INTEGER );
+ }
+ ;
+
+SAFEUTF8STRING : '"'! ( SAFEUTF8CHAR )* '"'! ;
+
+DESCR // THIS RULE ALSO STANDS FOR AN IDENTIFIER
+ :
+ ( "attributeValue" ( SP! )+ '{' ) =>
+ "attributeValue"! ( SP! )+ '{'! ( options { greedy = false; } : . )* '}'!
+ { $setType( ATTRIBUTE_VALUE_CANDIDATE ); }
+ | ( "rangeOfValues" ( SP! )+ '(' ) =>
+ "rangeOfValues"! ( SP! )+ '(' ( options { greedy = false; } : . )* ')'
+ { $setType( RANGE_OF_VALUES_CANDIDATE ); }
+ | ALPHA ( ALPHA | DIGIT | HYPHEN )*
+ ;
Added: directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ACIItemChecker.java
URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ACIItemChecker.java?view=auto&rev=489128
==============================================================================
--- directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ACIItemChecker.java (added)
+++ directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ACIItemChecker.java Wed Dec 20 08:14:55 2006
@@ -0,0 +1,142 @@
+/*
+ * 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.aci;
+
+
+import java.io.StringReader;
+import java.text.ParseException;
+import java.util.Map;
+
+import org.apache.directory.shared.ldap.name.NameComponentNormalizer;
+
+import antlr.RecognitionException;
+import antlr.TokenStreamException;
+
+
+/**
+ * A reusable wrapper around the antlr generated parser for an ACIItem as
+ * defined by X.501. This class enables the reuse of the antlr parser/lexer pair
+ * without having to recreate them every time.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 437007 $
+ */
+public class ACIItemChecker
+{
+ /** the antlr generated parser being wrapped */
+ private ReusableAntlrACIItemChecker checker;
+
+ /** the antlr generated lexer being wrapped */
+ private ReusableAntlrACIItemCheckerLexer lexer;
+
+ private final boolean isNormalizing;
+
+
+ /**
+ * Creates a ACIItem parser.
+ */
+ public ACIItemChecker()
+ {
+ this.lexer = new ReusableAntlrACIItemCheckerLexer( new StringReader( "" ) );
+ this.checker = new ReusableAntlrACIItemChecker( lexer );
+
+ this.checker.init(); // this method MUST be called while we cannot do
+ // constructor overloading for antlr generated parser
+ this.isNormalizing = false;
+ }
+
+
+ /**
+ * Creates a normalizing ACIItem parser.
+ */
+ public ACIItemChecker(NameComponentNormalizer normalizer, Map oidsMap )
+ {
+ this.lexer = new ReusableAntlrACIItemCheckerLexer( new StringReader( "" ) );
+ this.checker = new ReusableAntlrACIItemChecker( lexer );
+
+ this.checker.setNormalizer( normalizer );
+ this.checker.init(); // this method MUST be called while we cannot do
+ // constructor overloading for antlr generated parser
+ this.isNormalizing = true;
+ }
+
+
+ /**
+ * Initializes the plumbing by creating a pipe and coupling the parser/lexer
+ * pair with it. param spec the specification to be parsed
+ */
+ private synchronized void reset( String spec )
+ {
+ StringReader in = new StringReader( spec );
+ this.lexer.prepareNextInput( in );
+ this.checker.resetState();
+ }
+
+
+ /**
+ * Parses an ACIItem without exhausting the parser.
+ *
+ * @param spec
+ * the specification to be parsed
+ * @return the specification bean
+ * @throws ParseException
+ * if there are any recognition errors (bad syntax)
+ */
+ public synchronized void parse( String spec ) throws ParseException
+ {
+ if ( spec == null || spec.trim().equals( "" ) )
+ {
+ return;
+ }
+
+ reset( spec ); // reset and initialize the parser / lexer pair
+
+ try
+ {
+ this.checker.wrapperEntryPoint();
+ }
+ catch ( TokenStreamException e )
+ {
+ String msg = "Parser failure on ACIItem:\n\t" + spec;
+ msg += "\nAntlr exception trace:\n" + e.getMessage();
+ throw new ParseException( msg, 0 );
+ }
+ catch ( RecognitionException e )
+ {
+ String msg = "Parser failure on ACIItem:\n\t" + spec;
+ msg += "\nAntlr exception trace:\n" + e.getMessage();
+ throw new ParseException( msg, e.getColumn() );
+ }
+
+ return;
+ }
+
+
+ /**
+ * Tests to see if this parser is normalizing.
+ *
+ * @return true if it normalizes false otherwise
+ */
+ public boolean isNormizing()
+ {
+ return this.isNormalizing;
+ }
+}
Added: directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ReusableAntlrACIItemChecker.java
URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ReusableAntlrACIItemChecker.java?view=auto&rev=489128
==============================================================================
--- directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ReusableAntlrACIItemChecker.java (added)
+++ directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ReusableAntlrACIItemChecker.java Wed Dec 20 08:14:55 2006
@@ -0,0 +1,62 @@
+/*
+ * 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.aci;
+
+
+
+import antlr.TokenStream;
+
+
+/**
+ * A reusable parser class extended from antlr generated parser for an LDAP
+ * subtree specification as defined by <a
+ * href="http://www.faqs.org/rfcs/rfc3672.html"> RFC 3672</a>. This class
+ * enables the reuse of the antlr parser without having to recreate the it every
+ * time as stated in <a
+ * href="http://www.antlr.org:8080/pipermail/antlr-interest/2003-April/003631.html">
+ * a Antlr Interest Group mail</a> .
+ *
+ * @see <a href="http://www.faqs.org/rfcs/rfc3672.html">RFC 3672</a>
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 437007 $
+ */
+class ReusableAntlrACIItemChecker extends AntlrACIItemChecker
+{
+ /**
+ * Creates a ReusableAntlrACIItemChecker instance.
+ */
+ public ReusableAntlrACIItemChecker( TokenStream lexer )
+ {
+ super( lexer );
+ }
+
+
+ /**
+ * Resets the state of an antlr parser.
+ */
+ public void resetState()
+ {
+ // no set method for this protected field.
+ this.traceDepth = 0;
+
+ this.getInputState().reset();
+ }
+}
Added: directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ReusableAntlrACIItemCheckerLexer.java
URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ReusableAntlrACIItemCheckerLexer.java?view=auto&rev=489128
==============================================================================
--- directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ReusableAntlrACIItemCheckerLexer.java (added)
+++ directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/aci/ReusableAntlrACIItemCheckerLexer.java Wed Dec 20 08:14:55 2006
@@ -0,0 +1,81 @@
+/*
+ * 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.aci;
+
+
+import java.io.Reader;
+
+import antlr.CharBuffer;
+import antlr.LexerSharedInputState;
+
+
+/**
+ * A reusable lexer class extended from antlr generated lexer for an LDAP
+ * subtree specification as defined by <a
+ * href="http://www.faqs.org/rfcs/rfc3672.html"> RFC 3672</a>. This class
+ * enables the reuse of the antlr lexer without having to recreate the it every
+ * time as stated in <a
+ * href="http://www.antlr.org:8080/pipermail/antlr-interest/2003-April/003631.html">
+ * a Antlr Interest Group mail</a> .
+ *
+ * @see <a href="http://www.faqs.org/rfcs/rfc3672.html">RFC 3672</a>
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 437007 $
+ */
+class ReusableAntlrACIItemCheckerLexer extends AntlrACIItemCheckerLexer
+{
+ private boolean savedCaseSensitive;
+
+ private boolean savedCaseSensitiveLiterals;
+
+
+ /**
+ * Creates a ReusableAntlrACIItemCheckerLexer instance.
+ *
+ * @param in
+ * the input to the lexer
+ */
+ public ReusableAntlrACIItemCheckerLexer(Reader in)
+ {
+ super( in );
+ savedCaseSensitive = getCaseSensitive();
+ savedCaseSensitiveLiterals = getCaseSensitiveLiterals();
+ }
+
+
+ /**
+ * Resets the state of an antlr lexer and initializes it with new input.
+ *
+ * @param in
+ * the input to the lexer
+ */
+ public void prepareNextInput( Reader in )
+ {
+ CharBuffer buf = new CharBuffer( in );
+ LexerSharedInputState state = new LexerSharedInputState( buf );
+ this.setInputState( state );
+
+ this.setCaseSensitive( savedCaseSensitive );
+
+ // no set method for this protected field.
+ this.caseSensitiveLiterals = savedCaseSensitiveLiterals;
+ }
+}
Added: directory/trunks/shared/ldap/src/test/java/org/apache/directory/shared/ldap/aci/ACIItemChekerTest.java
URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/test/java/org/apache/directory/shared/ldap/aci/ACIItemChekerTest.java?view=auto&rev=489128
==============================================================================
--- directory/trunks/shared/ldap/src/test/java/org/apache/directory/shared/ldap/aci/ACIItemChekerTest.java (added)
+++ directory/trunks/shared/ldap/src/test/java/org/apache/directory/shared/ldap/aci/ACIItemChekerTest.java Wed Dec 20 08:14:55 2006
@@ -0,0 +1,250 @@
+/*
+ * 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.aci;
+
+
+import org.apache.directory.shared.ldap.aci.ACIItemChecker;
+
+import junit.framework.TestCase;
+
+
+/**
+ * Unit tests class for ACIItem checker (wrapper).
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 437007 $
+ */
+public class ACIItemChekerTest extends TestCase
+{
+
+ /** the ACIItem checker wrapper */
+ ACIItemChecker checker;
+
+
+ // /** holds multithreaded success value */
+ // boolean isSuccessMultithreaded = true;
+
+ /**
+ * Creates a ACIItemParserTest instance.
+ */
+ public ACIItemChekerTest()
+ {
+ super();
+ checker = new ACIItemChecker();
+ }
+
+
+ /**
+ * Creates a ACIItemParserTest instance.
+ */
+ public ACIItemChekerTest(String s)
+ {
+ super( s );
+ checker = new ACIItemChecker();
+ }
+
+
+ /**
+ * Tests the checker with an ACIItem of ItemFirst main component.
+ */
+ public void testItemFirst() throws Exception
+ {
+ String spec = " { identificationTag \"id1\" , precedence 114 , authenticationLevel simple , "
+ + "itemOrUserFirst itemFirst :{ protectedItems { entry , attributeType { 1.2.3 , ou } , "
+ + " attributeValue { ou=people , cn=Ersin } , rangeOfValues (cn=ErsinEr) , "
+ + "classes and : { item: xyz , or:{item:X,item:Y} }} , "
+ + "itemPermissions { { userClasses {allUsers , userGroup { \"1.2=y,z=t\" , \"a=b,c=d\" } "
+ + " , subtree { { base \"ou=people\" } } } , grantsAndDenials { denyCompare , grantModify } },"
+ + "{ precedence 10, userClasses {allUsers , userGroup { \"1.2=y,z=t\" , \"a=b,c=d\" } "
+ + " , subtree { { base \"ou=people\" } } } , grantsAndDenials { denyCompare , grantModify } } } }}";
+
+ checker.parse( spec );
+ }
+
+
+ /**
+ * Tests the checker with an ACIItem of UserFirst main component.
+ */
+ public void testUserFirst() throws Exception
+ {
+ String spec = "{ identificationTag \"id2\" , precedence 14, authenticationLevel none , "
+ + "itemOrUserFirst userFirst: { userClasses { allUsers , name { \"ou=people,cn=ersin\" }, "
+ + "subtree {{ base \"ou=system\" }, { base \"ou=ORGANIZATIONUNIT\","
+ + "minimum 1, maximum 2 } } } , "
+ + "userPermissions { { protectedItems{ entry , attributeType { cn , ou } , attributeValue {x=y,m=n,k=l} , "
+ + "rangeOfValues (cn=ErsinEr) } , grantsAndDenials { grantBrowse } } } } } ";
+
+ checker.parse( spec );
+ }
+
+
+ public void testAllowAddAllUsers() throws Exception
+ {
+ String spec = "{ identificationTag \"addAci\", " + "precedence 14, " + "authenticationLevel none, "
+ + "itemOrUserFirst userFirst: { " + "userClasses { allUsers }, "
+ + "userPermissions { { protectedItems {entry}, " + "grantsAndDenials { grantAdd } } } } }";
+
+ checker.parse( spec );
+ }
+
+
+ public void testCombo() throws Exception
+ {
+ String spec = "{ identificationTag \"addAci\", " + "precedence 14, " + "authenticationLevel none, "
+ + "itemOrUserFirst userFirst: { " + "userClasses { allUsers, name { \"ou=blah\" } }, "
+ + "userPermissions { { protectedItems {entry}, " + "grantsAndDenials { grantAdd } } } } }";
+
+ checker.parse( spec );
+ }
+
+
+ public void testOrderOfProtectedItemsDoesNotMatter() throws Exception
+ {
+ String spec = " { identificationTag \"id1\" , precedence 114 , authenticationLevel simple , "
+ + "itemOrUserFirst itemFirst :{ protectedItems { attributeType { 1.2.3 , ou }, entry , "
+ + " rangeOfValues (cn=ErsinEr) , attributeValue { ou=people , cn=Ersin },"
+ + "classes and : { item: xyz , or:{item:X,item:Y} }} , "
+ + "itemPermissions { { userClasses {allUsers , userGroup { \"1.2=y,z=t\" , \"a=b,c=d\" } "
+ + " , subtree { { base \"ou=people\" } } } , grantsAndDenials { denyCompare , grantModify } },"
+ + "{ precedence 10, userClasses {allUsers , userGroup { \"1.2=y,z=t\" , \"a=b,c=d\" } "
+ + " , subtree { { base \"ou=people\" } } } , grantsAndDenials { denyCompare , grantModify } } } }}";
+
+ checker.parse( spec );
+ }
+
+
+ public void testOrderOfUserClassesDoesNotMatter() throws Exception
+ {
+ String spec = "{ identificationTag \"id2\" , precedence 14, authenticationLevel none , "
+ + "itemOrUserFirst userFirst: { userClasses { name { \"ou=people,cn=ersin\" }, allUsers, "
+ + "subtree {{ base \"ou=system\" }, { base \"ou=ORGANIZATIONUNIT\","
+ + "minimum 1, maximum 2 } } } , "
+ + "userPermissions { { protectedItems{ entry , attributeType { cn , ou } , attributeValue {x=y,m=n,k=l} , "
+ + "rangeOfValues (cn=ErsinEr) } , grantsAndDenials { grantBrowse } } } } } ";
+
+ checker.parse( spec );
+ }
+
+
+ public void testItemPermissionComponentsOrderDoesNotMatter() throws Exception
+ {
+ String spec = " { identificationTag \"id1\" , precedence 114 , authenticationLevel simple , "
+ + "itemOrUserFirst itemFirst :{ protectedItems { attributeType { 1.2.3 , ou }, entry , "
+ + " rangeOfValues (cn=ErsinEr) , attributeValue { ou=people , cn=Ersin },"
+ + "classes and : { item: xyz , or:{item:X,item:Y} }} , "
+ + "itemPermissions { { grantsAndDenials { denyCompare , grantModify }, userClasses {allUsers , userGroup { \"1.2=y,z=t\" , \"a=b,c=d\" } "
+ + " , subtree { { base \"ou=people\" } } } },"
+ + "{ precedence 10, userClasses {allUsers , userGroup { \"1.2=y,z=t\" , \"a=b,c=d\" } "
+ + " , subtree { { base \"ou=people\" } } } , grantsAndDenials { denyCompare , grantModify } } } }}";
+
+ checker.parse( spec );
+ }
+
+
+ public void testUserPermissionComponentsOrderDoesNotMatter() throws Exception
+ {
+ String spec = "{ identificationTag \"id2\" , precedence 14, authenticationLevel none , "
+ + "itemOrUserFirst userFirst: { userClasses { allUsers , name { \"ou=people,cn=ersin\" }, "
+ + "subtree {{ base \"ou=system\" }, { base \"ou=ORGANIZATIONUNIT\","
+ + "minimum 1, maximum 2 } } } , "
+ + "userPermissions { { grantsAndDenials { grantBrowse }, protectedItems{ entry , attributeType { cn , ou } , attributeValue {x=y,m=n,k=l} , "
+ + "rangeOfValues (cn=ErsinEr) } } } } } ";
+
+ checker.parse( spec );
+ }
+
+
+ public void testOrderOfMainACIComponentsDoesNotMatter() throws Exception
+ {
+ String spec = "{ itemOrUserFirst userFirst: { userClasses { allUsers , name { \"ou=people,cn=ersin\" }, "
+ + "subtree {{ base \"ou=system\" }, { base \"ou=ORGANIZATIONUNIT\","
+ + "minimum 1, maximum 2 } } } , "
+ + "userPermissions { { protectedItems{ entry , attributeType { cn , ou } , attributeValue {x=y,m=n,k=l} , "
+ + "rangeOfValues (cn=ErsinEr) } , grantsAndDenials { grantBrowse } } } }, "
+ + " identificationTag \"id2\" , authenticationLevel none, precedence 14 } ";
+
+ checker.parse( spec );
+ }
+
+
+ public void testUserFirstComponentsOrderDoesNotMatter() throws Exception
+ {
+ String spec = "{ identificationTag \"id2\" , precedence 14, authenticationLevel none , "
+ + "itemOrUserFirst userFirst: { userPermissions { { protectedItems{ entry , attributeType { cn , ou } , attributeValue {x=y,m=n,k=l} , "
+ + "rangeOfValues (cn=ErsinEr) } , grantsAndDenials { grantBrowse } } }, userClasses { allUsers , name { \"ou=people,cn=ersin\" }, "
+ + "subtree {{ base \"ou=system\" }, { base \"ou=ORGANIZATIONUNIT\","
+ + "minimum 1, maximum 2 } } } } } ";
+
+ checker.parse( spec );
+ }
+
+
+ public void testItemFirstComponentsOrderDoesNotMatter() throws Exception
+ {
+ String spec = " { identificationTag \"id1\" , precedence 114 , authenticationLevel simple , "
+ + "itemOrUserFirst itemFirst :{ itemPermissions { { userClasses {allUsers , userGroup { \"1.2=y,z=t\" , \"a=b,c=d\" } "
+ + " , subtree { { base \"ou=people\" } } } , grantsAndDenials { denyCompare , grantModify } },"
+ + "{ precedence 10, userClasses {allUsers , userGroup { \"1.2=y,z=t\" , \"a=b,c=d\" } "
+ + " , subtree { { base \"ou=people\" } } } , grantsAndDenials { denyCompare , grantModify } } },protectedItems { entry , attributeType { 1.2.3 , ou } , "
+ + " attributeValue { ou=people , cn=Ersin } , rangeOfValues (cn=ErsinEr) , "
+ + "classes and : { item: xyz , or:{item:X,item:Y} }} " + " }}";
+
+ checker.parse( spec );
+ }
+
+
+ public void testRestrictedValueComponentsOrderDoesNotMatter() throws Exception
+ {
+ String spec = "{ identificationTag \"id2\" , precedence 14, authenticationLevel none , "
+ + "itemOrUserFirst userFirst: { userClasses { allUsers , name { \"ou=people,cn=ersin\" }, "
+ + "subtree {{ base \"ou=system\"}, { base \"ou=ORGANIZATIONUNIT\"," + "minimum 1, maximum 2 } } } , "
+ + "userPermissions { { protectedItems{ entry , "
+ + "maxValueCount { { type 10.11.12, maxCount 10 }, { maxCount 20, type 11.12.13 } } "
+ + " } , grantsAndDenials { grantBrowse } } } } } ";
+
+ checker.parse( spec );
+ }
+
+
+ public void testMaxValueCountComponentsOrderDoesNotMatter() throws Exception
+ {
+ String spec = "{ identificationTag \"id2\" , precedence 14, authenticationLevel none , "
+ + "itemOrUserFirst userFirst: { userClasses { allUsers , name { \"ou=people,cn=ersin\" }, "
+ + "subtree {{ base \"ou=system\" }, { base \"ou=ORGANIZATIONUNIT\"," + "minimum 1, maximum 2 } } } , "
+ + "userPermissions { { protectedItems{ entry , "
+ + "restrictedBy { { type 10.11.12, valuesIn ou }, { valuesIn cn, type 11.12.13 } } "
+ + " } , grantsAndDenials { grantBrowse } } } } } ";
+
+ checker.parse( spec );
+ }
+
+
+ public void testSubtreeSpecificationComponentsOrderDoesNotMatter() throws Exception
+ {
+ String spec = "{ identificationTag \"id2\" , precedence 14, authenticationLevel none , "
+ + "itemOrUserFirst userFirst: { userPermissions { { protectedItems{ entry , attributeType { cn , ou } , attributeValue {x=y,m=n,k=l} , "
+ + "rangeOfValues (cn=ErsinEr) } , grantsAndDenials { grantBrowse } } }, userClasses { allUsers , name { \"ou=people,cn=ersin\" }, "
+ + "subtree {{ minimum 7, maximum 9, base \"ou=system\" }, { base \"ou=ORGANIZATIONUNIT\","
+ + " maximum 2, minimum 1 } } } } } ";
+
+ checker.parse( spec );
+ }
+}