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 2005/09/14 20:27:18 UTC

svn commit: r280902 - in /directory/shared/ldap/trunk/common: ./ src/antlr/ src/java/org/apache/ldap/common/acl/ src/test/org/apache/ldap/common/acl/

Author: akarasulu
Date: Wed Sep 14 11:27:10 2005
New Revision: 280902

URL: http://svn.apache.org/viewcvs?rev=280902&view=rev
Log:
Applying Ersin Er's patch from DIRLDAP-53 here:

http://issues.apache.org/jira/browse/DIRLDAP-53

Thanks Ersin!!!!


Added:
    directory/shared/ldap/trunk/common/src/antlr/ACIItem.g   (with props)
    directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ACIItemParser.java   (with props)
    directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemLexer.java   (with props)
    directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemParser.java   (with props)
    directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/acl/
    directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/acl/ACIItemParserTest.java   (with props)
Modified:
    directory/shared/ldap/trunk/common/maven.xml

Modified: directory/shared/ldap/trunk/common/maven.xml
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/maven.xml?rev=280902&r1=280901&r2=280902&view=diff
==============================================================================
--- directory/shared/ldap/trunk/common/maven.xml (original)
+++ directory/shared/ldap/trunk/common/maven.xml Wed Sep 14 11:27:10 2005
@@ -47,6 +47,10 @@
 
     <j:set var="maven.antlr.grammars" value="subtree-specification.g"/>
     <attainGoal name="antlr:generate" />
+    
+    <j:set var="maven.antlr.grammars" value="ACIItem.g"/>
+    <attainGoal name="antlr:generate" />
+    
   </goal>
 
   <preGoal name="jar:jar">

Added: directory/shared/ldap/trunk/common/src/antlr/ACIItem.g
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/antlr/ACIItem.g?rev=280902&view=auto
==============================================================================
--- directory/shared/ldap/trunk/common/src/antlr/ACIItem.g (added)
+++ directory/shared/ldap/trunk/common/src/antlr/ACIItem.g Wed Sep 14 11:27:10 2005
@@ -0,0 +1,1418 @@
+header
+{
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.ldap.common.acl;
+
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Enumeration;
+
+import javax.naming.Name;
+import javax.naming.NamingException;
+
+import org.apache.ldap.common.filter.AbstractExprNode;
+import org.apache.ldap.common.filter.BranchNode;
+import org.apache.ldap.common.filter.ExprNode;
+import org.apache.ldap.common.filter.FilterParserImpl;
+import org.apache.ldap.common.filter.LeafNode;
+import org.apache.ldap.common.filter.SimpleNode;
+import org.apache.ldap.common.name.DnParser;
+import org.apache.ldap.common.subtree.SubtreeSpecification;
+import org.apache.ldap.common.subtree.SubtreeSpecificationModifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+}
+
+
+// ----------------------------------------------------------------------------
+// parser class definition
+// ----------------------------------------------------------------------------
+
+/**
+ * The antlr generated ACIItem parser.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+class AntlrACIItemParser extends Parser;
+
+
+// ----------------------------------------------------------------------------
+// parser options
+// ----------------------------------------------------------------------------
+
+options
+{
+    k = 1; // ;-)
+    defaultErrorHandler = false;
+}
+
+
+// ----------------------------------------------------------------------------
+// imaginary tokens
+// ----------------------------------------------------------------------------
+
+tokens
+{
+    ATTRIBUTE_VALUE_CANDIDATE;
+    RANGE_OF_VALUES_CANDIDATE;
+}
+
+
+// ----------------------------------------------------------------------------
+// parser initialization
+// ----------------------------------------------------------------------------
+
+{
+    private static final Logger log = LoggerFactory.getLogger( AntlrACIItemParser.class );
+    
+    private final DnParser dnParser = createDnParser();
+    private final FilterParserImpl filterParser = new FilterParserImpl();
+
+    private SubtreeSpecificationModifier ssModifier = null;
+    
+    // these Sets will be instantiated for each 
+    private Set chopBeforeExclusions;
+    private Set chopAfterExclusions;
+
+
+    /**
+     * Creates a subordinate DnParser for parsing Names.
+     *
+     * @return the DnParser to be used for parsing Names
+     */
+    private DnParser createDnParser()
+    {
+        // TODO : WE MAY NEED A NORMALIZING PARSER
+        try
+        {
+            return new DnParser();
+        }
+        catch ( NamingException e )
+        {
+            String msg = "Failed to initialize the subordinate DnParser for this AntlrSubtreeSpecificationParser";
+
+            // We throw a NPE since this variable cannot be null for proper operation
+            // so we can catch the null pointer before the dnParser is even used.
+
+            throw new NullPointerException( "dnParser is null: " + msg );
+        }
+    }
+
+    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
+{
+    log.debug( "entered wrapperEntryPoint()" );
+}
+    :
+    theACIItem EOF
+    ;
+
+theACIItem
+{
+    log.debug( "entered theACIItem()" );
+}
+    :
+    OPEN_CURLY
+        ( SP )* aci_identificationTag ( SP )*
+        SEP ( SP )* aci_precedence ( SP )*
+        SEP ( SP )* aci_authenticationLevel ( SP )*
+        SEP ( SP )* aci_itemOrUserFirst ( SP )*
+    CLOSE_CURLY
+    ;
+
+aci_identificationTag
+{
+    log.debug( "entered aci_identificationTag()" );
+}
+    :
+    ID_identificationTag ( SP )+ SAFEUTF8STRING
+    ;
+
+aci_precedence
+{
+    log.debug( "entered aci_precedence()" );
+}
+    :
+    ID_precedence ( SP )+ precedence
+    ;
+
+precedence returns [ int prec ]
+{
+    log.debug( "entered precedence()" );
+    prec = 0;
+}
+    :
+    token:INTEGER
+    {
+        prec = token2Integer( token );
+        if( prec < 0 || prec > 255 )
+        {
+            throw new RecognitionException( "Expecting INTEGER token having value between 0 and 255, found " + prec );
+        }
+    }
+    ;
+
+aci_authenticationLevel
+{
+    log.debug( "entered aci_authenticationLevel()" );
+}
+    :
+    ID_authenticationLevel ( SP )+ authenticationLevel
+    ;
+
+authenticationLevel
+{
+    log.debug( "entered authenticationLevel()" );
+}
+    :
+    basicLevels // | other // the "other" component can be omitted for LDAP ACI
+    ;
+
+basicLevels
+{
+    log.debug( "entered basicLevels()" );
+}
+    :
+    ID_basicLevels ( SP )* COLON ( SP )*
+    OPEN_CURLY ( SP )*
+        level (SP)* level_follower
+    CLOSE_CURLY
+    ;      
+
+level
+{
+    log.debug( "entered level()" );
+}
+    :
+    ID_level ( SP )+
+    ( ID_none
+      | ID_simple
+      | ID_strong
+    )
+    ;
+
+level_follower
+{
+    log.debug( "entered level_follower()" );
+}
+    :
+    ( SEP (SP)* localQualifier_signed ) ?
+    ;
+
+localQualifier_signed
+{
+    log.debug( "entered localQualifier_signed()" );
+}
+    :
+    ID_localQualifier (SP)+ token:INTEGER (SP)* signed_e
+    {
+        token2Integer( token );
+    }
+    | signed
+    ;
+
+signed_e
+{
+    log.debug( "entered signed_e()" );
+}
+    : ( SEP (SP)* signed )?
+    ;
+
+signed
+{
+    log.debug( "entered signed()" );
+}
+    :
+    ID_signed (SP)+ booleanValue (SP)*
+    ;
+
+booleanValue
+{
+    log.debug( "entered booleanValue()" );
+}
+    :
+    ID_FALSE | ID_TRUE
+    ;
+
+//other
+//    :
+//    token:EXTERNAL // !!! See RFC 3642 for ABNF grammar !!!
+//    ;
+
+aci_itemOrUserFirst
+{
+    log.debug("entered aci_itemOrUserFirst()");
+}
+    :
+    ID_itemOrUserFirst ( SP )+ itemOrUserFirst
+    ;
+
+itemOrUserFirst
+{
+    log.debug("entered itemOrUserFirst()");
+}
+    :
+    itemFirst | userFirst
+    ;
+
+itemFirst
+{
+    log.debug("entered itemFirst()");
+}
+    :
+    ID_itemFirst COLON
+        OPEN_CURLY ( SP )*
+            protectedItems
+            SEP ( SP )* itemPermissions
+        ( SP )* CLOSE_CURLY
+    ;
+
+userFirst
+{
+    log.debug("entered userFirst()");
+}
+    :
+    ID_userFirst COLON
+        OPEN_CURLY
+            ( SP )* userClasses
+            SEP ( SP )* userPermissions
+        ( SP )* CLOSE_CURLY
+    ;
+
+protectedItems
+{
+    log.debug("entered protectedItems()");
+}
+    :
+    ID_protectedItems ( SP )*
+        OPEN_CURLY (SP)*
+            (
+                ( entry entry_follower
+                | allUserAttributeTypes allUserAttributeTypes_follower
+                | attributeType attributeType_follower
+                | allAttributeValues allAttributeValues_follower 
+                | allUserAttributeTypesAndValues allUserAttributeTypesAndValues_follower
+                | attributeValue attributeValue_follower
+                | selfValue selfValue_follower
+                | rangeOfValues rangeOfValues_follower
+                | maxValueCount maxValueCount_follower
+                | maxImmSub maxImmSub_follower
+                | restrictedBy restrictedBy_follower
+                // LDAP does not have contexts
+                // contexts
+                classes
+                )
+                ( SP )*
+            )?
+       CLOSE_CURLY
+    ;
+
+entry_follower
+    :
+    ( SEP ( SP )*
+        (
+            allUserAttributeTypes allUserAttributeTypes_follower
+            | attributeType attributeType_follower
+            | allAttributeValues allAttributeValues_follower 
+            | allUserAttributeTypesAndValues allUserAttributeTypesAndValues_follower
+            | attributeValue attributeValue_follower
+            | selfValue selfValue_follower
+            | rangeOfValues rangeOfValues_follower
+            | maxValueCount maxValueCount_follower
+            | maxImmSub maxImmSub_follower
+            | restrictedBy restrictedBy_follower
+            | classes
+        )
+    )?
+    ;
+
+allUserAttributeTypes_follower
+    :
+    ( SEP ( SP )*
+        (
+            attributeType attributeType_follower
+            | allAttributeValues allAttributeValues_follower 
+            | allUserAttributeTypesAndValues allUserAttributeTypesAndValues_follower
+            | attributeValue attributeValue_follower
+            | selfValue selfValue_follower
+            | rangeOfValues rangeOfValues_follower
+            | maxValueCount maxValueCount_follower
+            | maxImmSub maxImmSub_follower
+            | restrictedBy restrictedBy_follower
+            | classes
+        )
+    )?
+    ;
+
+attributeType_follower
+    :
+    ( SEP ( SP )*
+        (
+            allAttributeValues allAttributeValues_follower 
+            | allUserAttributeTypesAndValues allUserAttributeTypesAndValues_follower
+            | attributeValue attributeValue_follower
+            | selfValue selfValue_follower
+            | rangeOfValues rangeOfValues_follower
+            | maxValueCount maxValueCount_follower
+            | maxImmSub maxImmSub_follower
+            | restrictedBy restrictedBy_follower
+            | classes
+        )
+    )?
+    ;
+
+allAttributeValues_follower
+    :
+    ( SEP ( SP )*
+        ( 
+            allUserAttributeTypesAndValues allUserAttributeTypesAndValues_follower
+            | attributeValue attributeValue_follower
+            | selfValue selfValue_follower
+            | rangeOfValues rangeOfValues_follower
+            | maxValueCount maxValueCount_follower
+            | maxImmSub maxImmSub_follower
+            | restrictedBy restrictedBy_follower
+            | classes
+        )
+    )?
+    ;
+
+allUserAttributeTypesAndValues_follower
+    :
+    ( SEP ( SP )*
+        (
+            attributeValue attributeValue_follower
+            | selfValue selfValue_follower
+            | rangeOfValues rangeOfValues_follower
+            | maxValueCount maxValueCount_follower
+            | maxImmSub maxImmSub_follower
+            | restrictedBy restrictedBy_follower
+            | classes
+        )
+    )?
+    ;
+
+attributeValue_follower
+    :
+    ( SEP ( SP )*
+        (
+            selfValue selfValue_follower
+            | rangeOfValues rangeOfValues_follower
+            | maxValueCount maxValueCount_follower
+            | maxImmSub maxImmSub_follower
+            | restrictedBy restrictedBy_follower
+            | classes
+        )
+    )?
+    ;
+
+selfValue_follower
+    :
+    ( SEP ( SP )*
+        (
+            rangeOfValues rangeOfValues_follower
+            | maxValueCount maxValueCount_follower
+            | maxImmSub maxImmSub_follower
+            | restrictedBy restrictedBy_follower
+            | classes
+        )
+    )?
+    ;
+
+rangeOfValues_follower
+    :
+    ( SEP ( SP )*
+        (
+            maxValueCount maxValueCount_follower
+            | maxImmSub maxImmSub_follower
+            | restrictedBy restrictedBy_follower
+            | classes
+        )
+    )?
+    ;
+
+maxValueCount_follower
+    :
+    ( SEP ( SP )*
+        (
+            maxImmSub maxImmSub_follower
+            | restrictedBy restrictedBy_follower
+            | classes
+        )
+    )?
+    ;
+
+maxImmSub_follower
+    :
+    ( SEP ( SP )*
+        (
+			restrictedBy restrictedBy_follower
+            | classes
+        )
+    )?
+    ;
+
+restrictedBy_follower
+    :
+    ( SEP ( SP )*
+        (
+			classes
+        )
+    )?
+    ;
+
+entry
+{
+    log.debug("entered entry()");
+}
+    :
+    ID_entry
+    ;
+
+allUserAttributeTypes
+{
+    log.debug("entered allUserAttributeTypes()");
+}
+    :
+    ID_allUserAttributeTypes
+    ;
+
+attributeType
+{
+    log.debug("entered attributeType()");
+}
+    :
+    ID_attributeType ( SP )+ attributeTypeSet
+    ;
+
+allAttributeValues
+{
+    log.debug("entered allAttributeValues()");
+}
+    :
+    ID_allAttributeValues ( SP )+ attributeTypeSet
+    ;
+
+allUserAttributeTypesAndValues
+{
+    log.debug("entered allUserAttributeTypesAndValues()");
+}
+    :
+    ID_allUserAttributeTypesAndValues
+    ;
+
+attributeValue
+{
+    log.debug("entered attributeValue()");
+}
+    :
+    token:ATTRIBUTE_VALUE_CANDIDATE // ate the identifier for subordinate dn parser workaround
+    {
+        // A Dn can be considered as a set of attributeTypeAndValues
+        // So, parse the set as a Dn and extract each attributeTypeAndValue
+        Name attributeTypeAnvValueSetAsDn =  dnParser.parse( token.getText() );
+        Enumeration attributeTypeandValueSet = attributeTypeAnvValueSetAsDn.getAll();
+        String attributeTypeandValue = null;
+        while (attributeTypeandValueSet.hasMoreElements())
+        {
+            attributeTypeandValue = ( String ) attributeTypeandValueSet.nextElement();
+            log.debug( "An attributeTypeAndValue from the set: " + attributeTypeandValue );
+        }
+    }
+    ;
+    exception
+    catch [Exception e]
+    {
+        throw new RecognitionException( "dnParser failed. " + e.getMessage() );
+    }
+
+selfValue
+{
+    log.debug("entered selfValue()");
+}
+    :
+    ID_selfValue ( SP )+ attributeTypeSet
+    ;
+
+rangeOfValues returns [ ExprNode node ]
+{
+    log.debug("entered rangeOfValues()");
+    node = null;
+}
+    :
+    token:RANGE_OF_VALUES_CANDIDATE
+    {
+        node = filterParser.parse( token.getText() );
+    }
+    ;
+    exception
+    catch [Exception e]
+    {
+        throw new RecognitionException( "filterParser failed. " + e.getMessage() );
+    }   
+
+maxValueCount
+{
+    log.debug("entered maxValueCount()");
+}
+    :
+    ID_maxValueCount ( SP )+
+    OPEN_CURLY ( SP )*
+        aMaxValueCount ( SP )*
+            ( SEP ( SP )* aMaxValueCount ( SP )* )*
+    CLOSE_CURLY
+    ;
+
+aMaxValueCount
+{
+    log.debug("entered aMaxValueCount()");
+}
+    :
+    OPEN_CURLY ( SP )*
+        ID_type ( SP )+ oid ( SP )* SEP ( SP )*
+        ID_maxCount ( SP )+ token:INTEGER
+        {
+            token2Integer( token );
+        }
+    ( SP )* CLOSE_CURLY
+    ;
+
+maxImmSub
+{
+    log.debug("entered maxImmSub()");
+}
+    :
+    ID_maxImmSub ( SP )+ token:INTEGER
+    {
+        token2Integer( token );
+    }
+    ;
+
+restrictedBy
+{
+    log.debug("entered restrictedBy()");
+}
+    :
+    ID_restrictedBy ( SP )+
+    OPEN_CURLY ( SP )*
+    restrictedValue ( SP )*
+            ( SEP ( SP )* restrictedValue ( SP )* )*
+    CLOSE_CURLY
+    ;
+
+restrictedValue
+{
+    log.debug("entered restrictedValue()");
+}
+    :
+    OPEN_CURLY ( SP )*
+        ID_type ( SP )+ oid ( SP )* SEP ( SP )*
+        ID_valuesIn ( SP )+ oid
+    ( SP )* CLOSE_CURLY
+    ;
+
+attributeTypeSet
+{
+    log.debug("entered attributeTypeSet()");
+}
+    :
+        OPEN_CURLY (SP)*
+            oid (SP)*
+                ( SEP (SP)* oid (SP)* )*
+        CLOSE_CURLY
+    ;
+
+classes
+{
+    log.debug("entered classes()");  
+}
+    :
+    ID_classes (SP)+ refinement
+    ;
+
+itemPermissions
+{
+    log.debug("entered itemPermissions()");  
+}
+    :
+    ID_itemPermissions (SP)+
+    OPEN_CURLY (SP)*
+        ( itemPermission (SP)*
+            ( SEP (SP)* itemPermission (SP)* )*
+        )?
+    CLOSE_CURLY
+    ;
+
+itemPermission
+{
+    log.debug( "entered itemPermission()" );
+}
+    :
+    OPEN_CURLY (SP)*
+        precedence_e // -- defaults to precedence in ACIItem
+    (SP)* CLOSE_CURLY
+    ;
+
+precedence_e
+{
+    log.debug("entered precedence_e()");
+}
+    :
+    ID_precedence (SP)+ precedence (SP)* (SEP) (SP)* userClasses (SP)* (SEP) (SP)* grantsAndDenials
+    | userClasses (SP)* (SEP) (SP)* grantsAndDenials
+    ;
+
+grantsAndDenials
+{
+    log.debug("entered grantsAndDenials()");
+}
+    :
+    ID_grantsAndDenials (SP)+
+    OPEN_CURLY (SP)*
+        ( grantAndDenialsBit (SP)*
+            ( SEP (SP)* grantAndDenialsBit (SP)* )*
+        )?
+    CLOSE_CURLY
+    ;
+
+grantAndDenialsBit
+{
+    log.debug("entered grantAndDenialsBit()");
+}
+    :
+    ID_grantAdd // (0),
+    | ID_denyAdd // (1),
+    | ID_grantDiscloseOnError // (2),
+    | ID_denyDiscloseOnError // (3),
+    | ID_grantRead // (4),
+    | ID_denyRead // (5),
+    | ID_grantRemove // (6),
+    | ID_denyRemove // (7),
+    //-- permissions that may be used only in conjunction
+    //-- with the entry component
+    | ID_grantBrowse // (8),
+    | ID_denyBrowse // (9),
+    | ID_grantExport // (10),
+    | ID_denyExport // (11),
+    | ID_grantImport // (12),
+    | ID_denyImport // (13),
+    | ID_grantModify // (14),
+    | ID_denyModify // (15),
+    | ID_grantRename // (16),
+    | ID_denyRename // (17),
+    | ID_grantReturnDN // (18),
+    | ID_denyReturnDN // (19),
+    //-- permissions that may be used in conjunction
+    //-- with any component, except entry, of ProtectedItems
+    | ID_grantCompare // (20),
+    | ID_denyCompare // (21),
+    | ID_grantFilterMatch // (22),
+    | ID_denyFilterMatch // (23),
+    | ID_grantInvoke // (24),
+    | ID_denyInvoke // (25)
+    ;
+
+userClasses
+    :
+    ID_userClasses (SP)+
+    OPEN_CURLY (SP)*
+        (
+            ( allUsers allUsers_follower
+            | thisEntry thisEntry_follower
+            | name name_follower
+            | userGroup userGroup_follower
+            | subtree
+            )
+            ( SP )*
+        )?
+    CLOSE_CURLY
+    ;
+
+allUsers_follower
+    :
+    ( SEP ( SP )*
+         (
+             thisEntry thisEntry_follower
+             | name name_follower
+             | userGroup userGroup_follower
+             | subtree
+         )
+    )?
+    ;
+
+thisEntry_follower
+    :
+    ( SEP ( SP )*
+        (
+            name name_follower
+            | userGroup userGroup_follower
+            | subtree
+        )
+    )?
+    ;
+
+name_follower
+    :
+    ( SEP ( SP )*
+        (
+            userGroup userGroup_follower
+            | subtree
+        )
+    )?
+    ;
+
+userGroup_follower
+    :
+    ( SEP ( SP )*
+        (
+            subtree
+        )
+    )?
+    ;
+
+allUsers
+    :
+    ID_allUsers
+    ;
+
+thisEntry
+    :
+    ID_thisEntry
+    ;
+
+name
+{
+    log.debug("entered name()");
+}
+    :
+    ID_name ( SP )+ 
+    OPEN_CURLY (SP)*
+        token1:SAFEUTF8STRING
+        {
+            dnParser.parse( token1.getText() );
+            log.debug( "name : " + token1.getText() );
+        } (SP)*
+            ( SEP (SP)* token2:SAFEUTF8STRING
+                        {
+                            dnParser.parse( token2.getText() );
+                            log.debug( "name : " + token2.getText() );
+                        } (SP)*
+            )*
+    CLOSE_CURLY
+    ;
+    exception
+    catch [Exception e]
+    {
+        throw new RecognitionException( "dnParser failed. " + e.getMessage() );
+    }
+
+userGroup
+{
+    log.debug("entered userGroup()");
+}
+	:
+    ID_userGroup ( SP )+ 
+    OPEN_CURLY (SP)*
+        token1:SAFEUTF8STRING
+        {
+            dnParser.parse( token1.getText() );
+            log.debug("name : " + token1.getText() );
+        } (SP)*
+            ( SEP (SP)* token2:SAFEUTF8STRING
+                        {
+                            dnParser.parse( token2.getText() );
+                            log.debug( "name : " + token2.getText() );
+                        } (SP)*
+            )*
+    CLOSE_CURLY
+    ;
+    exception
+    catch [Exception e]
+    {
+        throw new RecognitionException( "dnParser failed. " + e.getMessage() );
+    }
+
+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
+{
+    log.debug( "entered userPermission()" );
+}
+    :
+    OPEN_CURLY (SP)*
+        precedence_ee // -- defaults to precedence in ACIItem
+    (SP)* CLOSE_CURLY
+    ;
+
+precedence_ee
+{
+    log.debug("entered precedence_ee()");
+}
+    :
+    ID_precedence (SP)+ precedence (SP)* (SEP) (SP)* protectedItems (SP)* (SEP) (SP)* grantsAndDenials
+    | protectedItems (SP)* (SEP) (SP)* grantsAndDenials
+    ;
+
+subtreeSpecification returns [SubtreeSpecification ss]
+{
+    log.debug( "entered subtreeSpecification()" );
+    // clear out ss, ssModifier, chopBeforeExclusions and chopAfterExclusions
+    // in case something is left from the last parse
+    ss = null;
+    ssModifier = new SubtreeSpecificationModifier();
+    chopBeforeExclusions = new HashSet();
+    chopAfterExclusions = new HashSet();
+}
+    :
+    OPEN_CURLY ( SP )*
+        (
+            (
+              ss_base ss_base_follower
+            | ss_specificExclusions ss_specificExclusions_follower
+            | ss_minimum ss_minimum_follower
+            | ss_maximum ss_maximum_follower
+            | ss_specificationFilter
+            )
+            ( 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
+    :
+    ( SEP ( SP )*
+        (
+            ss_specificationFilter
+        )
+    )?
+    ;
+
+ss_base
+{
+    log.debug( "entered ss_base()" );
+    Name base = null;
+}
+    :
+    ID_base ( SP )+ base=localName
+    {
+        ssModifier.setBase( base );
+    }
+    ;
+
+ss_specificExclusions
+{
+    log.debug( "entered ss_specificExclusions()" );
+}
+    :
+    ID_specificExclusions ( SP )+ specificExclusions
+    {
+        ssModifier.setChopBeforeExclusions( chopBeforeExclusions );
+        ssModifier.setChopAfterExclusions( chopAfterExclusions );
+    }
+    ;
+
+specificExclusions
+{
+    log.debug( "entered specificExclusions()" );
+}
+    :
+    OPEN_CURLY ( SP )*
+        ( specificExclusion (SP)*
+            ( SEP ( SP )* specificExclusion )*
+        )?
+    CLOSE_CURLY
+    ;
+
+specificExclusion
+{
+    log.debug( "entered specificExclusion()" );
+}
+    :
+    chopBefore | chopAfter
+    ;
+
+chopBefore
+{
+    log.debug( "entered chopBefore()" );
+    Name chopBeforeExclusion = null;
+}
+    :
+    ID_chopBefore COLON chopBeforeExclusion=localName
+    {
+        chopBeforeExclusions.add( chopBeforeExclusion );
+    }
+    ;
+
+chopAfter
+{
+    log.debug( "entered chopAfter()" );
+    Name chopAfterExclusion = null;
+}
+    :
+    ID_chopAfter COLON chopAfterExclusion=localName
+    {
+        chopAfterExclusions.add( chopAfterExclusion );
+    }
+    ;
+
+ss_minimum
+{
+    log.debug( "entered ss_minimum()" );
+    int minimum = 0;
+}
+    :
+    ID_minimum ( SP )+ minimum=baseDistance
+    {
+        ssModifier.setMinBaseDistance( minimum );
+    }
+    ;
+
+ss_maximum
+{
+    log.debug( "entered ss_maximum()" );
+    int maximum = 0;
+}
+    :
+    ID_maximum ( SP )+ maximum=baseDistance
+    {
+        ssModifier.setMaxBaseDistance( maximum );
+    }
+    ;
+
+ss_specificationFilter
+{
+    log.debug( "entered ss_specificationFilter()" );
+    ExprNode theRefinement = null;
+}
+    :
+    ID_specificationFilter ( SP )+ theRefinement=refinement
+    {
+        ssModifier.setRefinement( theRefinement );
+    }
+    ;
+
+localName returns [Name name] 
+{
+    log.debug( "entered localName()" );
+    name = null;
+}
+    :
+    token:SAFEUTF8STRING
+    {
+        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:INTEGER
+    {
+        distance = token2Integer( token );
+    }
+    ;
+
+oid returns [String result]
+{
+    log.debug( "entered oid()" );
+    result = null;
+}
+    :
+    token1:DESCR
+    {
+        result = token1.getText();
+        log.debug("Recognized a DESCR: " + token1.getText());
+    }
+    |
+    token2:NUMERICOID
+    {
+        result = token2.getText();
+        log.debug("Recognized a NUMERICOID: " + token2.getText());
+    }
+    ;
+
+refinement returns [ExprNode node]
+{
+    log.debug( "entered refinement()" );
+    node = null;
+} :
+    ( node=item | node=and | node=or | node=not )
+    {
+        log.debug("refinement icinde node: " + node.toString());
+    }
+    ;
+
+item returns [LeafNode node]
+{
+    log.debug( "entered item()" );
+    node = null;
+    String l_oid = null;
+}
+	:
+    ID_item COLON l_oid=oid
+    {
+        node = new SimpleNode( "objectClass" , l_oid , AbstractExprNode.EQUALITY );
+    }
+    ;
+
+and returns [BranchNode node]
+{
+    log.debug( "entered and()" );
+    node = null;
+    ArrayList children = null; 
+}
+	:
+    ID_and COLON children=refinements
+    {
+        node = new BranchNode( AbstractExprNode.AND , children );
+    }
+    ;
+
+or returns [BranchNode node]
+{
+    log.debug( "entered or()" );
+    node = null;
+    ArrayList children = null; 
+}
+	:
+    ID_or COLON children=refinements
+    {
+        node = new BranchNode( AbstractExprNode.OR , children );
+    }
+    ;
+
+not returns [BranchNode node]
+{
+    log.debug( "entered not()" );
+    node = null;
+    ArrayList children = null;
+}
+    :
+    ID_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();
+}
+	:
+    OPEN_CURLY
+    (
+        child=refinement
+        {
+            tempChildren.add( child );
+        }
+        ( SEP child=refinement
+        {
+            tempChildren.add( child );
+        } )*
+    )? CLOSE_CURLY
+    {
+        children = tempChildren;
+    }
+    ;
+
+    
+//  ----------------------------------------------------------------------------
+//  lexer class definition
+//  ----------------------------------------------------------------------------
+
+/**
+  * The parser's primary lexer.
+  *
+  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+  * @version $Rev$
+  */
+class AntlrACIItemLexer 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
+// ----------------------------------------------------------------------------
+
+{
+     private static final Logger log = LoggerFactory.getLogger( AntlrACIItemLexer.class );
+}
+
+
+// ----------------------------------------------------------------------------
+// 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 : ' ' ;
+
+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 )*
+    ;

Propchange: directory/shared/ldap/trunk/common/src/antlr/ACIItem.g
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ACIItemParser.java
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ACIItemParser.java?rev=280902&view=auto
==============================================================================
--- directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ACIItemParser.java (added)
+++ directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ACIItemParser.java Wed Sep 14 11:27:10 2005
@@ -0,0 +1,105 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.ldap.common.acl;
+
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.text.ParseException;
+
+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$
+ */
+public class ACIItemParser
+{
+    /** the antlr generated parser being wrapped */
+    private ReusableAntlrACIItemParser parser;
+    /** the antlr generated lexer being wrapped */
+    private ReusableAntlrACIItemLexer lexer;
+
+
+    /**
+     * Creates a ACIItem parser.
+     */
+    public ACIItemParser()
+    {
+        this.lexer = new ReusableAntlrACIItemLexer( new StringReader( "" ) );
+        this.parser = new ReusableAntlrACIItemParser( lexer );
+    }
+
+    /**
+     * 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.parser.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)
+     * @throws IOException if there is a problem with underlying streams
+     */
+    public synchronized void parse( String spec ) throws ParseException, IOException
+    {
+        if ( spec == null || spec.trim().equals( "" ) )
+        {
+            // return null;
+        }
+        
+        reset(spec); // reset and initialize the parser / lexer pair
+
+        try
+        {
+            /*l_ACIItem = */this.parser.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 l_ACIItem;
+    }
+}

Propchange: directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ACIItemParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemLexer.java
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemLexer.java?rev=280902&view=auto
==============================================================================
--- directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemLexer.java (added)
+++ directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemLexer.java Wed Sep 14 11:27:10 2005
@@ -0,0 +1,74 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.ldap.common.acl;
+
+
+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$
+ */
+class ReusableAntlrACIItemLexer extends AntlrACIItemLexer
+{
+    private boolean savedCaseSensitive;
+    private boolean savedCaseSensitiveLiterals;
+
+    /**
+     * Creates a ReusableAntlrSubtreeSpecificationLexer instance.
+     *
+     * @param in the input to the lexer
+     */
+    public ReusableAntlrACIItemLexer( 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;
+    }
+}

Propchange: directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemLexer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemParser.java
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemParser.java?rev=280902&view=auto
==============================================================================
--- directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemParser.java (added)
+++ directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemParser.java Wed Sep 14 11:27:10 2005
@@ -0,0 +1,58 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.ldap.common.acl;
+
+
+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$
+ */
+class ReusableAntlrACIItemParser extends AntlrACIItemParser
+{
+    /**
+     * Creates a ReusableAntlrSubtreeSpecificationParser instance.
+     */
+    public ReusableAntlrACIItemParser( 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();
+    }
+}

Propchange: directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ReusableAntlrACIItemParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/acl/ACIItemParserTest.java
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/acl/ACIItemParserTest.java?rev=280902&view=auto
==============================================================================
--- directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/acl/ACIItemParserTest.java (added)
+++ directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/acl/ACIItemParserTest.java Wed Sep 14 11:27:10 2005
@@ -0,0 +1,84 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.ldap.common.acl;
+
+
+import junit.framework.TestCase;
+
+
+/**
+ * Unit tests class for ACIItem parser (wrapper).
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class ACIItemParserTest extends TestCase
+{
+    
+    /** the ACIItem parser wrapper */
+    ACIItemParser parser;
+    
+//    /** holds multithreaded success value */
+//    boolean isSuccessMultithreaded = true;
+
+
+    /**
+     * Creates a ACIItemParserTest instance.
+     */
+    public ACIItemParserTest()
+    {
+        super();
+        parser = new ACIItemParser();
+    }
+
+    
+    /**
+     * Creates a ACIItemParserTest instance.
+     */
+    public ACIItemParserTest( String s )
+    {
+        super( s );
+        parser = new ACIItemParser();
+    }
+
+
+    /**
+     * Tests the parser with some valid input.
+     */    
+    public void testSpecItemFirst() throws Exception
+    { 
+        String spec1 = "{ identificationTag \"id1\" , precedence 114, authenticationLevel basicLevels:{ level none, localQualifier 23, signed FALSE }, " +
+        "itemOrUserFirst itemFirst:{ protectedItems{ entry, attributeType { 1.2.3, ou }, attributeValue { ou=people, cn=Ersin }, rangeOfValues (cn=ErsinEr) }, " +
+        "itemPermissions { { userClasses {allUsers, userGroup { \"1.2=y,z=t\", \"a=b,c=d\" }, subtree { { base \"ou=people\" } } }, grantsAndDenials { denyCompare, grantModify } } } }}";
+        
+        parser.parse(spec1);
+    }
+    
+    /**
+     * Tests the parser with some valid input.
+     */    
+    public void testSpecUserFirst() throws Exception
+    {        
+        String spec2 = "{ identificationTag \"id2\", precedence 14, authenticationLevel basicLevels:{ level none, localQualifier 23, signed FALSE }, " +
+        "itemOrUserFirst userFirst:{ userClasses {allUsers, name { \"ou=people,cn=ersin\" } }, " +
+        "userPermissions { { protectedItems{ entry, attributeType { cn, ou }, rangeOfValues (cn=ErsinEr) }, grantsAndDenials { grantBrowse } } } }}";
+        
+        parser.parse(spec2);
+    }
+}

Propchange: directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/acl/ACIItemParserTest.java
------------------------------------------------------------------------------
    svn:eol-style = native