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 2005/04/05 09:21:58 UTC

svn commit: r160136 - directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageContainer.java directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageGrammar.java

Author: elecharny
Date: Tue Apr  5 00:21:58 2005
New Revision: 160136

URL: http://svn.apache.org/viewcvs?view=rev&rev=160136
Log:
Dealing with grammar switches. Need a second look, it's not perfect...

Modified:
    directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageContainer.java
    directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageGrammar.java

Modified: directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageContainer.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageContainer.java?view=diff&r1=160135&r2=160136
==============================================================================
--- directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageContainer.java (original)
+++ directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageContainer.java Tue Apr  5 00:21:58 2005
@@ -47,8 +47,18 @@
     /** The pool that is associated with this container */
     protected LocalPoolManager poolManager;
 
-    /** The grammar that is used to decode the ldapMessage */
-    protected IGrammar grammar;
+    /** The grammars that are used.
+     * It's a stack as we can switch grammars */
+    protected IGrammar[] grammarStack;
+    
+    /** All the possible grammars */
+    private IGrammar[] grammars;
+    
+    /** The number of stored grammars */ 
+    private int nbGrammars;
+    
+    /** The current grammar */
+    private int currentGrammar;
 
     /** The ldap message */
     private LdapMessagePOJO ldapMessage;
@@ -57,10 +67,15 @@
 
     /**
      * Creates a new LdapMessageContainer object.
+     * We will store ten grammars, it's enough ...
      */
     public LdapMessageContainer()
     {
         super( );
+        currentGrammar = -1;
+        grammars = new IGrammar[10];
+        grammarStack = new IGrammar[10];
+        nbGrammars = 0;
     }
 
     //~ Methods ------------------------------------------------------------------------------------
@@ -73,7 +88,20 @@
         state      = 0;
         transition = 0;
         ldapMessage.free();
-
+        
+        for (int i = 0; i < nbGrammars; i++ )
+        {
+            grammars[i] = null;
+        }
+        
+        for (int i = 0; i < grammarStack.length; i++ )
+        {
+            grammarStack[i] = null;
+        }
+        
+        currentGrammar = 0;
+        nbGrammars = 0;
+        
         super.free();
     }
 
@@ -120,17 +148,39 @@
      */
     public IGrammar getGrammar()
     {
-        return grammar;
+        return grammarStack[currentGrammar];
+    }
+
+    /**
+     * Add a IGrammar to use
+     *
+     * @param grammar The grammar to add.
+     */
+    public void addGrammar( IGrammar grammar )
+    {
+        grammars[nbGrammars++] = grammar;
+    }
+
+    /**
+     * Switch to another grammar
+     *
+     * @param grammar The grammar to add.
+     */
+    public void switchGrammar( int grammar )
+    {
+        currentGrammar ++;
+        grammarStack[currentGrammar] = grammars[grammar];
     }
 
     /**
-     * Set the IGrammar to use
+     * restore the previous grammar (the one before a switch has occured)
      *
-     * @param grammar The grammar to set.
+     * @param grammar The grammar to add.
      */
-    public void setGrammar( IGrammar grammar )
+    public void restoreGrammar()
     {
-        this.grammar = grammar;
+        grammarStack[currentGrammar] = null;
+        currentGrammar --;
     }
 
     /**
@@ -187,5 +237,20 @@
     public void setTransition( int transition )
     {
         this.transition = transition;
+    }
+    
+    /**
+     * @return Returns the currentGrammar.
+     */
+    public int getCurrentGrammar() {
+        return currentGrammar;
+    }
+
+    /**
+     * @return Set the grammar that will be used to start a decoding.
+     */
+    public void setInitGrammar(int grammar) {
+        currentGrammar ++;
+        grammarStack[currentGrammar] = grammars[grammar];
     }
 }

Modified: directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageGrammar.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageGrammar.java?view=diff&r1=160135&r2=160136
==============================================================================
--- directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageGrammar.java (original)
+++ directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageGrammar.java Tue Apr  5 00:21:58 2005
@@ -24,9 +24,10 @@
 import org.apache.asn1.ber.grammar.StatesEnum;
 import org.apache.asn1.ber.tlv.TLV;
 import org.apache.asn1.ber.tlv.Value;
-import org.apache.asn1.ldap.codec.primitives.IntegerDecoder;
+import org.apache.asn1.ldap.codec.utils.IntegerDecoder;
 import org.apache.asn1.ldap.pojo.AbstractPOJO;
 import org.apache.asn1.ldap.pojo.BindRequestPOJO;
+import org.apache.asn1.ldap.pojo.BindResponsePOJO;
 import org.apache.asn1.ldap.pojo.LdapMessagePOJO;
 import org.apache.asn1.ldap.pojo.LdapPOJO;
 import org.apache.asn1.ldap.pojo.SimpleAuthenticationPOJO;
@@ -57,6 +58,11 @@
 
     /** The instance of grammar. LdapMessage is a singleton */
     private static IGrammar instance = new LdapMessageGrammar();
+    
+    static
+    {
+        getInstance().setName("LdapMessageGrammar");
+    }
 
     //~ Constructors -------------------------------------------------------------------------------
     /**
@@ -87,8 +93,11 @@
     {
 
         // We have 17 differents states, so 16 transitions between states.
-        super.transitions = new GrammarTransition[StatesEnum.LAST_STATE][256];
+        super.transitions = new GrammarTransition[StatesEnum.LAST_LDAP_STATE][256];
 
+        //============================================================================================
+        // LdapMessage 
+        //============================================================================================
         // LDAPMessage --> SEQUENCE { ... (Tag)
         // We have a LDAPMessage, and the tag must be 0x30
         super.transitions[StatesEnum.LDAP_MESSAGE_TAG][0x30] = new GrammarTransition( "LdapMessage Tag",
@@ -139,6 +148,9 @@
         // Nothing to do, it's a constructed TLV
         super.transitions[StatesEnum.LDAP_MESSAGE_VALUE][0x30] = new GrammarTransition( "LdapMessage Value", StatesEnum.LDAP_MESSAGE_ID_TAG, null);
 
+        //============================================================================================
+        // LdapMessage Message ID 
+        //============================================================================================
         // LDAPMessage --> ... MessageId ...(Tag)
         // The tag must be 0x02. Nothing special to do.
         super.transitions[StatesEnum.LDAP_MESSAGE_ID_TAG][0x02] = new GrammarTransition( "MessageId Tag", StatesEnum.LDAP_MESSAGE_ID_LENGTH, null);
@@ -189,6 +201,46 @@
                     }
                 } );
 
+        //============================================================================================
+        // LdapResult 
+        //============================================================================================
+        // LDAPResult --> SEQUENCE { 
+        //    resultCode ENUMERATED { ... (Tag)
+        // We have a LDAPResult Enumerated, the tag must be 0x0A
+        // Nothing to do
+        super.transitions[StatesEnum.LDAP_RESULT_CODE_TAG][0x0A] = new GrammarTransition( "LdapResult resultCode Tag",
+                StatesEnum.LDAP_RESULT_CODE_LENGTH, null);
+
+        // LDAPResult --> SEQUENCE { 
+        //    resultCode ENUMERATED { ... (Length)
+        // The length must be 1 (as the result code is between 0 and 90)
+        super.transitions[StatesEnum.LDAP_RESULT_CODE_LENGTH][0x0A] = new GrammarTransition( "LdapResult resultCode Length",
+                StatesEnum.LDAP_RESULT_CODE_VALUE, new GrammarAction( "LdapResult resultCode Length" )
+                {
+                    public void action( IAsn1Container container ) throws DecoderException
+                    {
+                    	// We have to check that the length is 1
+                        TLV tlv = ((LdapMessageContainer)container).getCurrentTLV();
+                        
+                	    if ( tlv.getLength().getLength() != 1 )
+                	    {
+                	        throw new DecoderException("The LdapResult resultCode must be 1 byte length, got " + tlv.getLength().getLength());
+                	    }
+                	    
+                    	checkLength(((LdapMessageContainer)container).getLdapMessage(), tlv);
+
+                    	return;
+                    }
+                } );
+        
+        // LDAPResult --> SEQUENCE { 
+        //    resultCode ENUMERATED { ... (Length)
+        // The value must be in {[0-8], [10-21], [32-35], 36, [48-54], [64-69], 71, 80}
+        super.transitions[StatesEnum.LDAP_RESULT_CODE_VALUE][0x0A] = new GrammarTransition( "LdapMessage Value", StatesEnum.LDAP_RESULT_MATCHED_DN_TAG, null);
+
+        //============================================================================================
+        // protocolOp : Bind Request 
+        //============================================================================================
         // If the Tag is 0x60, then it's a BindRequest. Nothing to do while the length is not verified.
         // LdapMessage ::= ... BindRequest ...
         // BindRequest ::= [APPLICATION 0] SEQUENCE { ... (Tag)
@@ -233,15 +285,15 @@
         // LdapMessage ::= ... BindRequest ...
         // BindRequest ::= [APPLICATION 0] SEQUENCE { ... (Value)
         // Nothing to do, the Value is empty, this is a constructed TLV
-        super.transitions[StatesEnum.PROTOCOL_OP_VALUE][0x60] = new GrammarTransition( "BindRequest Value", StatesEnum.BIND_VERSION_TAG, null);
+        super.transitions[StatesEnum.PROTOCOL_OP_VALUE][0x60] = new GrammarTransition( "BindRequest Value", StatesEnum.BIND_REQUEST_VERSION_TAG, null);
 
         // BindRequest ::= ... version INTEGER (1 .. 127 ), ... (Tag)
         // Nothing to do.
-        super.transitions[StatesEnum.BIND_VERSION_TAG][0x02] = new GrammarTransition( "Bind version Tag", StatesEnum.BIND_VERSION_LENGTH, null);
+        super.transitions[StatesEnum.BIND_REQUEST_VERSION_TAG][0x02] = new GrammarTransition( "Bind version Tag", StatesEnum.BIND_REQUEST_VERSION_LENGTH, null);
         
         // BindRequest ::= ... version INTEGER (1 .. 127 ), ... (Length)
         // Checks the length
-        super.transitions[StatesEnum.BIND_VERSION_LENGTH][0x02] = new GrammarTransition( "Bind version Length", StatesEnum.BIND_VERSION_VALUE,
+        super.transitions[StatesEnum.BIND_REQUEST_VERSION_LENGTH][0x02] = new GrammarTransition( "Bind version Length", StatesEnum.BIND_REQUEST_VERSION_VALUE,
                 new GrammarAction( "Store version" )
                 {
                     public void action( IAsn1Container container ) throws DecoderException
@@ -254,7 +306,7 @@
 
         // BindRequest ::= ... version INTEGER (1 .. 127 ), ... (value)
         // Checks that the Version is in [1, 127]
-        super.transitions[StatesEnum.BIND_VERSION_VALUE][0x02] = new GrammarTransition( "Bind version Length", StatesEnum.BIND_NAME_TAG,
+        super.transitions[StatesEnum.BIND_REQUEST_VERSION_VALUE][0x02] = new GrammarTransition( "Bind version Length", StatesEnum.BIND_REQUEST_NAME_TAG,
                 new GrammarAction( "Store version" )
                 {
                     public void action( IAsn1Container container ) throws DecoderException
@@ -281,11 +333,11 @@
 
         // BindRequest ::= ... name LDAPDN, ... (Tag)
         // Nothing to do. The tag is supposed to be 0x04
-        super.transitions[StatesEnum.BIND_NAME_TAG][0x04] = new GrammarTransition( "bind name tag", StatesEnum.BIND_NAME_LENGTH, null);
+        super.transitions[StatesEnum.BIND_REQUEST_NAME_TAG][0x04] = new GrammarTransition( "bind name tag", StatesEnum.BIND_REQUEST_NAME_LENGTH, null);
         
         // BindRequest ::= ... name LDAPDN, ... (Length)
         // We just check the length.
-        super.transitions[StatesEnum.BIND_NAME_LENGTH][0x04] = new GrammarTransition( "bind name length", StatesEnum.BIND_NAME_VALUE,
+        super.transitions[StatesEnum.BIND_REQUEST_NAME_LENGTH][0x04] = new GrammarTransition( "bind name length", StatesEnum.BIND_REQUEST_NAME_VALUE,
                 new GrammarAction( "Check Bind Name Length" )
                 {
                     public void action( IAsn1Container container ) throws DecoderException
@@ -297,7 +349,7 @@
 
         // BindRequest ::= ... name LDAPDN, ... (Value)
         // We just check the length.
-        super.transitions[StatesEnum.BIND_NAME_VALUE][0x04] = new GrammarTransition( "bind name value", StatesEnum.BIND_AUTHENTICATION_CHOICE_TAG,
+        super.transitions[StatesEnum.BIND_REQUEST_NAME_VALUE][0x04] = new GrammarTransition( "bind name value", StatesEnum.BIND_REQUEST_AUTHENTICATION_CHOICE_TAG,
                 new GrammarAction( "Store Bind Name value" )
                 {
                     public void action( IAsn1Container container ) throws DecoderException
@@ -335,11 +387,11 @@
         // The tag might be either 0x80 (SimpleAuthentication) or 0x83 (SaslAuthentication)
         // Here, it's 0x80, so a SimpleAuthentication. 
         // Nothing to do.
-        super.transitions[StatesEnum.BIND_AUTHENTICATION_CHOICE_TAG][( 0x80 & 0x00FF )] = new GrammarTransition( "Bind Simple Authentication Tag", StatesEnum.BIND_AUTHENTICATION_SIMPLE_LENGTH, null);
+        super.transitions[StatesEnum.BIND_REQUEST_AUTHENTICATION_CHOICE_TAG][( 0x80 & 0x00FF )] = new GrammarTransition( "Bind Simple Authentication Tag", StatesEnum.BIND_REQUEST_AUTHENTICATION_SIMPLE_LENGTH, null);
         
         // AuthenticationChoice ::= CHOICE {
         //		simple         [0] OCTET STRING, (Length)
-        super.transitions[StatesEnum.BIND_AUTHENTICATION_SIMPLE_LENGTH][( 0x80 & 0x00FF )] = new GrammarTransition( "Bind Simple Authentication Length", StatesEnum.BIND_AUTHENTICATION_SIMPLE_VALUE, 
+        super.transitions[StatesEnum.BIND_REQUEST_AUTHENTICATION_SIMPLE_LENGTH][( 0x80 & 0x00FF )] = new GrammarTransition( "Bind Simple Authentication Length", StatesEnum.BIND_REQUEST_AUTHENTICATION_SIMPLE_VALUE, 
         		new GrammarAction( "Check simple authentication length" ) 
                 {
                     public void action( IAsn1Container container ) throws DecoderException
@@ -352,7 +404,7 @@
 
         // AuthenticationChoice ::= CHOICE {
         //		simple         [0] OCTET STRING, (Value)
-        super.transitions[StatesEnum.BIND_AUTHENTICATION_SIMPLE_VALUE][( 0x80 & 0x00FF )] = new GrammarTransition( "Bind Simple Authentication Value", -1, //StatesEnum.CONTROLS_TAG, 
+        super.transitions[StatesEnum.BIND_REQUEST_AUTHENTICATION_SIMPLE_VALUE][( 0x80 & 0x00FF )] = new GrammarTransition( "Bind Simple Authentication Value", -1, //StatesEnum.CONTROLS_TAG, 
                 new GrammarAction( "Store Bind Simple Authentication value" )
                 {
                     public void action( IAsn1Container container ) throws DecoderException
@@ -397,5 +449,56 @@
 						}
                     }
                 } );
+
+        //============================================================================================
+        // protocolOp : Bind Response 
+        //============================================================================================
+        // If the Tag is 0x61, then it's a BindResponse. Nothing to do while the length is not verified.
+        // LdapMessage ::= ... BindResponse ...
+        // BindResponse ::= [APPLICATION 1] SEQUENCE { ... (Tag)
+        super.transitions[StatesEnum.PROTOCOL_OP_TAG][0x61] = new GrammarTransition( "BindResponse Tag", StatesEnum.PROTOCOL_OP_LENGTH, null );
+
+        // We have to allocate a BindResponsePOJO
+        // LdapMessage ::= ... BindResponse ...
+        // BindResponse ::= [APPLICATION 1] SEQUENCE { ... (Length)
+        super.transitions[StatesEnum.PROTOCOL_OP_LENGTH][0x61] = new GrammarTransition( "BindResponse Length", StatesEnum.PROTOCOL_OP_VALUE, 
+                new GrammarAction( "Init BindReponse" )
+                {
+                    public void action( IAsn1Container container ) throws DecoderException
+                    {
+
+                    	LdapMessageContainer ldapMessageContainer = (LdapMessageContainer)container;
+                    	LdapMessagePOJO ldapMessage = ldapMessageContainer.getLdapMessage();
+
+                    	checkLength(((LdapMessageContainer)container).getLdapMessage(), ((LdapMessageContainer)container).getCurrentTLV());
+                    	
+                    	try 
+						{
+	                    	// Now, we can allocate the BindResponse POJO
+	                    	LdapPOJO bindResponse= (LdapPOJO)ldapMessageContainer.getPoolManager().allocate(PoolEnum.BIND_RESPONSE_POJO_POOL);
+	                    	
+	                    	// As this is a new Constructed object, we have to init its length
+	                        TLV   tlv       = ldapMessageContainer.getCurrentTLV();
+	                        int expectedLength = tlv.getLength().getLength();
+	                    	((BindResponsePOJO)bindResponse).setExpectedLength(expectedLength);
+	                    	((BindResponsePOJO)bindResponse).setCurrentLength(0);
+
+							// And we associate it to the ldapMessage POJO
+	                    	ldapMessage.setProtocolOP(bindResponse);
+	                    	
+                    	} catch (PoolException pe) 
+						{
+                    		throw new DecoderException(
+                                    "Cannot allocate a BindResponse Pojo : " + pe.getMessage() );
+                    	}
+                    }
+                });
+
+        // LdapMessage ::= ... BindResponse ...
+        // BindResponse ::= [APPLICATION 1] SEQUENCE { ... (Value)
+        // Ok, we have a LdapResult to parse. As it can be used in many different
+        // rules, we have to decode it using another grammar (LdapResultGrammar).
+        super.transitions[StatesEnum.PROTOCOL_OP_VALUE][0x61] = new GrammarTransition( "BindResponse Value", StatesEnum.LDAP_RESULT_GRAMMAR_SWITCH, null);
+
     }
 }