Added: directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/grammars/LdapResultGrammar.java URL: http://svn.apache.org/viewcvs/directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/grammars/LdapResultGrammar.java?view=auto&rev=161400 ============================================================================== --- directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/grammars/LdapResultGrammar.java (added) +++ directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/grammars/LdapResultGrammar.java Thu Apr 14 22:42:23 2005 @@ -0,0 +1,585 @@ +/* + * 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.asn1.ldap.codec.grammars; + +import org.apache.asn1.ber.containers.IAsn1Container; +import org.apache.asn1.ber.grammar.AbstractGrammar; +import org.apache.asn1.ber.grammar.GrammarAction; +import org.apache.asn1.ber.grammar.GrammarTransition; +import org.apache.asn1.ber.grammar.IGrammar; +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.DecoderException; +import org.apache.asn1.ldap.codec.LdapMessageContainer; +import org.apache.asn1.ldap.codec.primitives.LdapDN; +import org.apache.asn1.ldap.codec.primitives.LdapString; +import org.apache.asn1.ldap.codec.utils.IntegerDecoder; +import org.apache.asn1.ldap.codec.utils.LdapResultEnum; +import org.apache.asn1.ldap.pojo.BindResponsePOJO; +import org.apache.asn1.ldap.pojo.LdapMessagePOJO; +import org.apache.asn1.ldap.pojo.LdapResultPOJO; +import org.apache.asn1.util.MutableString; +import org.apache.asn1.util.pools.PoolEnum; +import org.apache.asn1.util.pools.PoolException; + +import org.apache.log4j.Logger; + + +/** + * This class implements the LdapMessage. All the actions are declared in this + * class. As it is a singleton, these declaration are only done once. + * + * If an action is to be added or modified, this is where the work is to be done ! + * + * @author <a href="mailto:[email protected]">Apache Directory Project</a> + */ +public class LdapResultGrammar extends AbstractGrammar implements IGrammar +{ + //~ Static fields/initializers ----------------------------------------------------------------- + + /** The logger */ + private static final Logger log = Logger.getLogger( LdapResultGrammar.class ); + + /** Logging speed up */ + private static final boolean DEBUG = log.isDebugEnabled(); + + /** The instance of grammar. LdapMessage is a singleton */ + private static IGrammar instance = new LdapResultGrammar(); + + //~ Constructors ------------------------------------------------------------------------------- + + /** + * Creates a new LdapMessageGrammar object. + */ + private LdapResultGrammar() + { + name = LdapResultGrammar.class.getName(); + + super.transitions = new GrammarTransition[StatesEnum.LDAP_RESULT_LAST_STATE][256]; + + //============================================================================================ + // LdapResult + //============================================================================================ + // LDAPResult --> SEQUENCE { + // resultCode ENUMERATED { ... (Tag) + // We have a LDAPResult, and the tag may be 0x0A + // Nothing to do + super.transitions[StatesEnum.LDAP_RESULT_CODE_TAG][0x0A] = new GrammarTransition( + StatesEnum.LDAP_RESULT_CODE_TAG, StatesEnum.LDAP_RESULT_CODE_LENGTH, null ); + + // LDAPResult --> SEQUENCE { + // resultCode ENUMERATED { ... (Length) + // let's check the length + super.transitions[StatesEnum.LDAP_RESULT_CODE_LENGTH][0x0A] = new GrammarTransition( + StatesEnum.LDAP_RESULT_CODE_LENGTH, StatesEnum.LDAP_RESULT_CODE_VALUE, + new GrammarAction( "LdapResult Length" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + + // We have to store the expected Length of the PDU + LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) + container; + LdapMessagePOJO ldapMessage = ( LdapMessagePOJO ) + ( ldapMessageContainer.getLdapMessage() ); + BindResponsePOJO bindResponse = ( BindResponsePOJO ) + ( ldapMessage.getProtocolOp() ); + + // We have to allocate a LdapResultPOJO now + LdapResultPOJO ldapResult = null; + + try + { + ldapResult = ( LdapResultPOJO ) ( ldapMessageContainer.getPoolManager() + .allocate( PoolEnum.LDAP_RESULT_POJO_POOL ) ); + bindResponse.setLdapResult( ldapResult ); + } + catch ( PoolException pe ) + { + throw new DecoderException( + "Cannot allocate a LdapResult Pojo : " + pe.getMessage() ); + } + + TLV tlv = ldapMessageContainer.getCurrentTLV(); + + ldapResult.setExpectedLength( tlv.getLength().getLength() ); + ldapResult.setCurrentLength( 0 ); + ldapResult.setFather( bindResponse ); + + checkLength( bindResponse, tlv ); + + return; + } + } ); + + // LDAPResult --> SEQUENCE { + // resultCode ENUMERATED { ... (Value) + // The result code. The different values are : + // success (0), + // operationsError (1), + // protocolError (2), + // timeLimitExceeded (3), + // sizeLimitExceeded (4), + // compareFalse (5), + // compareTrue (6), + // authMethodNotSupported (7), + // strongAuthRequired (8), + // -- 9 reserved -- + // referral (10), -- new + // adminLimitExceeded (11), -- new + // unavailableCriticalExtension (12), -- new + // confidentialityRequired (13), -- new + // saslBindInProgress (14), -- new + // noSuchAttribute (16), + // undefinedAttributeType (17), + // inappropriateMatching (18), + // constraintViolation (19), + // attributeOrValueExists (20), + // invalidAttributeSyntax (21), + // -- 22-31 unused -- + // noSuchObject (32), + // aliasProblem (33), + // invalidDNSyntax (34), + // -- 35 reserved for undefined isLeaf -- + // aliasDereferencingProblem (36), + // -- 37-47 unused -- + // inappropriateAuthentication (48), + // invalidCredentials (49), + // insufficientAccessRights (50), + // busy (51), + // unavailable (52), + // unwillingToPerform (53), + // loopDetect (54), + // -- 55-63 unused -- + // namingViolation (64), + // objectClassViolation (65), + // notAllowedOnNonLeaf (66), + // notAllowedOnRDN (67), + // entryAlreadyExists (68), + // objectClassModsProhibited (69), + // -- 70 reserved for CLDAP -- + // affectsMultipleDSAs (71), -- new + // -- 72-79 unused -- + // other (80) }, + // -- 81-90 reserved for APIs -- + // + super.transitions[StatesEnum.LDAP_RESULT_CODE_VALUE][0x0A] = new GrammarTransition( + StatesEnum.LDAP_RESULT_CODE_VALUE, StatesEnum.LDAP_RESULT_MATCHED_DN_TAG, + new GrammarAction( "Store resultCode" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + + LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) + container; + LdapMessagePOJO ldapMessage = + ldapMessageContainer.getLdapMessage(); + BindResponsePOJO bindResponse = ( BindResponsePOJO ) + ( ldapMessage.getProtocolOp() ); + LdapResultPOJO ldapResult = ( LdapResultPOJO ) + ( bindResponse.getLdapResult() ); + + // We don't have to allocate a LdapResultPOJO first. + + // The current TLV should be a integer + // We get it and store it in MessageId + TLV tlv = ldapMessageContainer.getCurrentTLV(); + + Value value = tlv.getValue(); + + int resultCode = IntegerDecoder.parse( value, 0, 90 ); + + // Treat the 'normal' cases ! + switch ( resultCode ) + { + + case LdapResultEnum.SUCCESS : + case LdapResultEnum.OPERATIONS_ERROR : + case LdapResultEnum.PROTOCOL_ERROR : + case LdapResultEnum.TIME_LIMIT_EXCEEDED : + case LdapResultEnum.SIZE_LIMIT_EXCEEDED : + case LdapResultEnum.COMPARE_FALSE : + case LdapResultEnum.COMPARE_TRUE : + case LdapResultEnum.AUTH_METHOD_NOT_SUPPORTED : + case LdapResultEnum.STRONG_AUTH_REQUIRED : + case LdapResultEnum.REFERRAL : + case LdapResultEnum.ADMIN_LIMIT_EXCEEDED : + case LdapResultEnum.UNAVAILABLE_CRITICAL_EXTENSION : + case LdapResultEnum.CONFIDENTIALITY_REQUIRED : + case LdapResultEnum.SASL_BIND_IN_PROGRESS : + case LdapResultEnum.NO_SUCH_ATTRIBUTE : + case LdapResultEnum.UNDEFINED_ATTRIBUTE_TYPE : + case LdapResultEnum.INAPPROPRIATE_MATCHING : + case LdapResultEnum.CONSTRAINT_VIOLATION : + case LdapResultEnum.ATTRIBUTE_OR_VALUE_EXISTS : + case LdapResultEnum.INVALID_ATTRIBUTE_SYNTAX : + case LdapResultEnum.NO_SUCH_OBJECT : + case LdapResultEnum.ALIAS_PROBLEM : + case LdapResultEnum.INVALID_DN_SYNTAX : + case LdapResultEnum.ALIAS_DEREFERENCING_PROBLEM : + case LdapResultEnum.INAPPROPRIATE_AUTHENTICATION : + case LdapResultEnum.INVALID_CREDENTIALS : + case LdapResultEnum.INSUFFICIENT_ACCESS_RIGHTS : + case LdapResultEnum.BUSY : + case LdapResultEnum.UNAVAILABLE : + case LdapResultEnum.UNWILLING_TO_PERFORM : + case LdapResultEnum.LOOP_DETECT : + case LdapResultEnum.NAMING_VIOLATION : + case LdapResultEnum.OBJECT_CLASS_VIOLATION : + case LdapResultEnum.NOT_ALLOWED_ON_NON_LEAF : + case LdapResultEnum.NOT_ALLOWED_ON_RDN : + case LdapResultEnum.ENTRY_ALREADY_EXISTS : + case LdapResultEnum.AFFECTS_MULTIPLE_DSAS : + ldapResult.setResultCode( resultCode ); + break; + + default : + throw new DecoderException( + "Error <" + LdapResultEnum.errorCode( resultCode ) + + "> not allowed" ); + } + } + } ); + + // LDAPResult --> SEQUENCE { + // ... + // matchedDN LDAPDN, (Tag) + // The tag is 0x04. Nothing to do + super.transitions[StatesEnum.LDAP_RESULT_MATCHED_DN_TAG][0x04] = new GrammarTransition( + StatesEnum.LDAP_RESULT_MATCHED_DN_TAG, StatesEnum.LDAP_RESULT_MATCHED_DN_LENGTH, + null ); + + // LDAPResult --> SEQUENCE { + // ... + // matchedDN LDAPDN, (Length) + // The tag is 0x04. We have to check the Length + super.transitions[StatesEnum.LDAP_RESULT_MATCHED_DN_LENGTH][0x04] = new GrammarTransition( + StatesEnum.LDAP_RESULT_MATCHED_DN_LENGTH, StatesEnum.LDAP_RESULT_MATCHED_DN_VALUE, + new GrammarAction( "Ldap Result Matched DN lentgh control" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + + LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) + container; + LdapMessagePOJO ldapMessage = ( LdapMessagePOJO ) + ( ldapMessageContainer.getLdapMessage() ); + BindResponsePOJO bindResponse = ( BindResponsePOJO ) + ( ldapMessage.getProtocolOp() ); + LdapResultPOJO ldapResult = ( LdapResultPOJO ) + ( bindResponse.getLdapResult() ); + + TLV tlv = + ldapMessageContainer.getCurrentTLV(); + + checkLength( bindResponse, tlv ); + + // We have to handle the special case of a 0 length matched DN + if (tlv.getLength().getLength() == 0) + { + ldapResult.setMatchedDN( MutableString.EMPTY_STRING ); + } + } + } ); + + // LDAPResult --> SEQUENCE { + // ... + // matchedDN LDAPDN, (Value) + // We store the LDAPDN after having checked that it is valid. + super.transitions[StatesEnum.LDAP_RESULT_MATCHED_DN_VALUE][0x04] = new GrammarTransition( + StatesEnum.LDAP_RESULT_MATCHED_DN_VALUE, StatesEnum.LDAP_RESULT_ERROR_MESSAGE_TAG, + new GrammarAction( "Store Ldap Result matched DN" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + + LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) + container; + LdapMessagePOJO ldapMessage = ( LdapMessagePOJO ) + ( ldapMessageContainer.getLdapMessage() ); + BindResponsePOJO bindResponse = ( BindResponsePOJO ) + ( ldapMessage.getProtocolOp() ); + LdapResultPOJO ldapResult = ( LdapResultPOJO ) + ( bindResponse.getLdapResult() ); + + // Get the Value and store it in the BindResponse + TLV tlv = ldapMessageContainer.getCurrentTLV(); + + MutableString matchedDN = LdapDN.parseDN( + ldapMessageContainer.getPoolManager(), tlv.getValue().getData() ); + ldapResult.setMatchedDN( matchedDN ); + return; + } + } ); + + // LDAPResult --> SEQUENCE { + // ... + // errorMessage LDAPString, (Tag) + // The tag is 0x04. Nothing to do + super.transitions[StatesEnum.LDAP_RESULT_ERROR_MESSAGE_TAG][0x04] = new GrammarTransition( + StatesEnum.LDAP_RESULT_ERROR_MESSAGE_TAG, + StatesEnum.LDAP_RESULT_ERROR_MESSAGE_LENGTH, null ); + + // LDAPResult --> SEQUENCE { + // ... + // errorMessage LDAPString, (Length) + // The tag is 0x04. We have to check the Length + super.transitions[StatesEnum.LDAP_RESULT_ERROR_MESSAGE_LENGTH][0x04] = + new GrammarTransition( StatesEnum.LDAP_RESULT_ERROR_MESSAGE_LENGTH, + StatesEnum.LDAP_RESULT_ERROR_MESSAGE_VALUE, + new GrammarAction( "Ldap Result error message length control" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + + LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) + container; + LdapMessagePOJO ldapMessage = ( LdapMessagePOJO ) + ( ldapMessageContainer.getLdapMessage() ); + BindResponsePOJO bindResponse = ( BindResponsePOJO ) + ( ldapMessage.getProtocolOp() ); + LdapResultPOJO ldapResult = ( LdapResultPOJO ) + ( bindResponse.getLdapResult() ); + + TLV tlv = + ldapMessageContainer.getCurrentTLV(); + + checkLength( bindResponse, tlv ); + + // We have to handle the special case of a 0 length error message + if (tlv.getLength().getLength() == 0) + { + ldapResult.setErrorMessage( MutableString.EMPTY_STRING ); + } + } + } ); + + // LDAPResult --> SEQUENCE { + // ... + // errorMessage LDAPString, (Value) + // Stores the value. + super.transitions[StatesEnum.LDAP_RESULT_ERROR_MESSAGE_VALUE][0x04] = + new GrammarTransition( StatesEnum.LDAP_RESULT_ERROR_MESSAGE_VALUE, + StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, + new GrammarAction( "Store Ldap Result error message" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + + LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) + container; + LdapMessagePOJO ldapMessage = ( LdapMessagePOJO ) + ( ldapMessageContainer.getLdapMessage() ); + BindResponsePOJO bindResponse = ( BindResponsePOJO ) + ( ldapMessage.getProtocolOp() ); + LdapResultPOJO ldapResult = ( LdapResultPOJO ) + ( bindResponse.getLdapResult() ); + + // Get the Value and store it in the BindResponse + TLV tlv = ldapMessageContainer.getCurrentTLV(); + + MutableString errorMessage = LdapString.parse( + ldapMessageContainer.getPoolManager(), tlv.getValue().getData() ); + ldapResult.setErrorMessage( errorMessage ); + return; + } + } ); + + // LDAPResult --> SEQUENCE { + // ... + // referral [3] Referral OPTIONAL } (Tag) + // + // The next state could be one of the following : + // - 0x80 : a control, like in SearchResultDone, ModifyResponse, AddResponse, DelResponse, ModifyDNResponse, CompareResponse + // - 0x83 : a referral, in a LdapResult. + // - 0x87 : a serverSaslCreds, in a BindResponse + // - 0x8A : an extended response + // - GRAMMAR_END : this is implicitly deducted by the fact that we don't have anymore byte... + // + // We don't deal with all of this values, we just have to treat the 0x83, because + // referral is a part of the LdapResult grammar. In all other cases, we just quit + // the grammar. + // + // This is a control. We have to quit the LdapResult grammar + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_TAG][0x80] = + new GrammarTransition( StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, + StatesEnum.GRAMMAR_END, null ); + + // This is a referral. + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_TAG][0x83] = + new GrammarTransition( StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, + StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_LENGTH, null ); + + // This is a serverSaslCreds. We have to quit the LdapResult grammar + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_TAG][0x87] = + new GrammarTransition( StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, + StatesEnum.GRAMMAR_END, null ); + + // This is a extended response. We have to quit the LdapResult grammar + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_TAG][0x8A] = + new GrammarTransition( StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, + StatesEnum.GRAMMAR_END, null ); + + // LDAPResult --> SEQUENCE { + // ... + // referral [3] Referral OPTIONAL } (Length) + // We just check the length, and store the new expected length. As this is a sequence, we don't have any value, so we + // transit to the REFERRAL_TAG. + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_LENGTH][0x83] = + new GrammarTransition( StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_LENGTH, + StatesEnum.LDAP_RESULT_REFERRAL_TAG, + new GrammarAction( "Ldap Result referrals length control" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + + LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) + container; + LdapMessagePOJO ldapMessage = ( LdapMessagePOJO ) + ( ldapMessageContainer.getLdapMessage() ); + BindResponsePOJO bindResponse = ( BindResponsePOJO ) + ( ldapMessage.getProtocolOp() ); + LdapResultPOJO ldapResult = ( LdapResultPOJO ) + ( bindResponse.getLdapResult() ); + + TLV tlv = + ldapMessageContainer.getCurrentTLV(); + + checkLength( bindResponse, tlv ); + + // We will use the LdapString POJO to check the expected length of the following + // referrals. This is quite a trick, but as this POJO's expected length is never + // used, it's just ok. + ldapResult.setExpectedLength( ldapMessageContainer.getCurrentTLV() + .getLength().getLength() ); + ldapResult.setCurrentLength( 0 ); + + } + } ); + + // Referral ::= SEQUENCE OF LDAPURL (Tag) + // This is a SEQUENCE, we will have at least one referral, but may be many. + // As this is the tag, we don't have anything to do. + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_TAG][0x04] = new GrammarTransition( + StatesEnum.LDAP_RESULT_REFERRAL_TAG, StatesEnum.LDAP_RESULT_REFERRAL_LENGTH, null ); + + // Referral ::= SEQUENCE OF LDAPURL (Length) + // This is a SEQUENCE, we will have at least one referral, but may be many. + // We will check the length. + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_LENGTH][0x04] = new GrammarTransition( + StatesEnum.LDAP_RESULT_REFERRAL_LENGTH, StatesEnum.LDAP_RESULT_REFERRAL_VALUE, + new GrammarAction( "Ldap Result referral length control" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + + LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) + container; + LdapMessagePOJO ldapMessage = ( LdapMessagePOJO ) + ( ldapMessageContainer.getLdapMessage() ); + BindResponsePOJO bindResponse = ( BindResponsePOJO ) + ( ldapMessage.getProtocolOp() ); + LdapResultPOJO ldapResult = ( LdapResultPOJO ) + ( bindResponse.getLdapResult() ); + + TLV tlv = + ldapMessageContainer.getCurrentTLV(); + + checkLength( ldapResult, tlv ); + + // We have to handle the special case of a 0 length referral + if (tlv.getLength().getLength() == 0) + { + ldapResult.addReferral( MutableString.EMPTY_STRING ); + } + } + } ); + + // Referral ::= SEQUENCE OF LDAPURL (Length) + // We may have other referrals, but wa may also have finished to read the LdapResult. + // To handle those different cases, we have to transit to a special state, which + // will do this brancing. + // Here, we store the referral in the ldapResult. + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_VALUE][0x04] = new GrammarTransition( + StatesEnum.LDAP_RESULT_REFERRAL_LENGTH, StatesEnum.LDAP_RESULT_REFERRAL_LOOP_TAG, + new GrammarAction( "Store Ldap Result referral" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + + LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) + container; + LdapMessagePOJO ldapMessage = ( LdapMessagePOJO ) + ( ldapMessageContainer.getLdapMessage() ); + BindResponsePOJO bindResponse = ( BindResponsePOJO ) + ( ldapMessage.getProtocolOp() ); + LdapResultPOJO ldapResult = ( LdapResultPOJO ) + ( bindResponse.getLdapResult() ); + + TLV tlv = + ldapMessageContainer.getCurrentTLV(); + + MutableString referral = LdapString.parse( + ldapMessageContainer.getPoolManager(), tlv.getValue().getData() ); + ldapResult.addReferral( referral ); + } + } ); + + // Referral ::= SEQUENCE OF LDAPURL (Tag) + // We may have another referral, but we could also have something else : + // - 0x04 : a referral, in a LdapResult. + // - 0x80 : a control, like in SearchResultDone, ModifyResponse, AddResponse, DelResponse, ModifyDNResponse, CompareResponse + // - 0x87 : a serverSaslCreds, in a BindResponse + // - 0x8A : an extended response + // - GRAMMAR_END : this is implicitly deducted by the fact that we don't have anymore byte... + // Those different cases are handled here. + + // This is a referral. We have to transit to its Length state + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_LOOP_TAG][0x04] = + new GrammarTransition( StatesEnum.LDAP_RESULT_REFERRAL_LOOP_TAG, + StatesEnum.LDAP_RESULT_REFERRAL_SEQUENCE_LENGTH, null ); + + // This is a control. We have to quit the LdapResult grammar + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_LOOP_TAG][0x80] = + new GrammarTransition( StatesEnum.LDAP_RESULT_REFERRAL_LOOP_TAG, + StatesEnum.GRAMMAR_END, null ); + + // This is a serverSaslCreds. We have to quit the LdapResult grammar + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_LOOP_TAG][0x87] = + new GrammarTransition( StatesEnum.LDAP_RESULT_REFERRAL_LOOP_TAG, + StatesEnum.GRAMMAR_END, null ); + + // This is a extended response. We have to quit the LdapResult grammar + super.transitions[StatesEnum.LDAP_RESULT_REFERRAL_LOOP_TAG][0x8A] = + new GrammarTransition( StatesEnum.LDAP_RESULT_REFERRAL_LOOP_TAG, + StatesEnum.GRAMMAR_END, null ); + + } + + //~ Methods ------------------------------------------------------------------------------------ + + /** + * This class is a singleton. + * + * @return An instance on this grammar + */ + public static IGrammar getInstance() + { + return instance; + } +}
