001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    package org.apache.directory.shared.ldap.codec;
021    
022    
023    import javax.naming.InvalidNameException;
024    import javax.naming.NamingException;
025    
026    import org.apache.directory.shared.asn1.ber.IAsn1Container;
027    import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar;
028    import org.apache.directory.shared.asn1.ber.grammar.GrammarAction;
029    import org.apache.directory.shared.asn1.ber.grammar.GrammarTransition;
030    import org.apache.directory.shared.asn1.ber.grammar.IAction;
031    import org.apache.directory.shared.asn1.ber.grammar.IGrammar;
032    import org.apache.directory.shared.asn1.ber.tlv.TLV;
033    import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
034    import org.apache.directory.shared.asn1.ber.tlv.Value;
035    import org.apache.directory.shared.asn1.codec.DecoderException;
036    import org.apache.directory.shared.asn1.primitives.OID;
037    import org.apache.directory.shared.asn1.util.BooleanDecoder;
038    import org.apache.directory.shared.asn1.util.BooleanDecoderException;
039    import org.apache.directory.shared.asn1.util.IntegerDecoder;
040    import org.apache.directory.shared.asn1.util.IntegerDecoderException;
041    import org.apache.directory.shared.ldap.codec.abandon.AbandonRequestCodec;
042    import org.apache.directory.shared.ldap.codec.actions.AttributeDescAction;
043    import org.apache.directory.shared.ldap.codec.actions.ControlValueAction;
044    import org.apache.directory.shared.ldap.codec.actions.ControlsInitAction;
045    import org.apache.directory.shared.ldap.codec.actions.ErrorMessageAction;
046    import org.apache.directory.shared.ldap.codec.actions.InitAndFilterAction;
047    import org.apache.directory.shared.ldap.codec.actions.InitApproxMatchFilterAction;
048    import org.apache.directory.shared.ldap.codec.actions.InitAssertionValueFilterAction;
049    import org.apache.directory.shared.ldap.codec.actions.InitAttributeDescFilterAction;
050    import org.apache.directory.shared.ldap.codec.actions.InitAttributeDescListAction;
051    import org.apache.directory.shared.ldap.codec.actions.InitEqualityMatchFilterAction;
052    import org.apache.directory.shared.ldap.codec.actions.InitExtensibleMatchFilterAction;
053    import org.apache.directory.shared.ldap.codec.actions.InitGreaterOrEqualFilterAction;
054    import org.apache.directory.shared.ldap.codec.actions.InitLessOrEqualFilterAction;
055    import org.apache.directory.shared.ldap.codec.actions.InitNotFilterAction;
056    import org.apache.directory.shared.ldap.codec.actions.InitOrFilterAction;
057    import org.apache.directory.shared.ldap.codec.actions.InitPresentFilterAction;
058    import org.apache.directory.shared.ldap.codec.actions.InitReferralsAction;
059    import org.apache.directory.shared.ldap.codec.actions.InitSubstringsFilterAction;
060    import org.apache.directory.shared.ldap.codec.actions.MatchedDNAction;
061    import org.apache.directory.shared.ldap.codec.actions.ModifyAttributeValueAction;
062    import org.apache.directory.shared.ldap.codec.actions.ReferralAction;
063    import org.apache.directory.shared.ldap.codec.actions.ResponseAction;
064    import org.apache.directory.shared.ldap.codec.actions.ResponseNameAction;
065    import org.apache.directory.shared.ldap.codec.actions.ResultCodeAction;
066    import org.apache.directory.shared.ldap.codec.actions.SearchResultAttributeValueAction;
067    import org.apache.directory.shared.ldap.codec.actions.ServerSASLCredsAction;
068    import org.apache.directory.shared.ldap.codec.actions.StoreAnyAction;
069    import org.apache.directory.shared.ldap.codec.actions.StoreFinalAction;
070    import org.apache.directory.shared.ldap.codec.actions.StoreMatchValueAction;
071    import org.apache.directory.shared.ldap.codec.actions.StoreReferenceAction;
072    import org.apache.directory.shared.ldap.codec.actions.StoreTypeMatchingRuleAction;
073    import org.apache.directory.shared.ldap.codec.actions.ValueAction;
074    import org.apache.directory.shared.ldap.codec.add.AddRequestCodec;
075    import org.apache.directory.shared.ldap.codec.add.AddResponseCodec;
076    import org.apache.directory.shared.ldap.codec.bind.BindRequestCodec;
077    import org.apache.directory.shared.ldap.codec.bind.BindResponseCodec;
078    import org.apache.directory.shared.ldap.codec.bind.SaslCredentials;
079    import org.apache.directory.shared.ldap.codec.bind.SimpleAuthentication;
080    import org.apache.directory.shared.ldap.codec.compare.CompareRequestCodec;
081    import org.apache.directory.shared.ldap.codec.compare.CompareResponseCodec;
082    import org.apache.directory.shared.ldap.codec.del.DelRequestCodec;
083    import org.apache.directory.shared.ldap.codec.del.DelResponseCodec;
084    import org.apache.directory.shared.ldap.codec.extended.ExtendedRequestCodec;
085    import org.apache.directory.shared.ldap.codec.extended.ExtendedResponseCodec;
086    import org.apache.directory.shared.ldap.codec.intermediate.IntermediateResponseCodec;
087    import org.apache.directory.shared.ldap.codec.modify.ModifyRequestCodec;
088    import org.apache.directory.shared.ldap.codec.modify.ModifyResponseCodec;
089    import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNRequestCodec;
090    import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNResponseCodec;
091    import org.apache.directory.shared.ldap.codec.search.ExtensibleMatchFilter;
092    import org.apache.directory.shared.ldap.codec.search.SearchRequestCodec;
093    import org.apache.directory.shared.ldap.codec.search.SearchResultDoneCodec;
094    import org.apache.directory.shared.ldap.codec.search.SearchResultEntryCodec;
095    import org.apache.directory.shared.ldap.codec.search.SearchResultReferenceCodec;
096    import org.apache.directory.shared.ldap.codec.search.SubstringFilter;
097    import org.apache.directory.shared.ldap.codec.unbind.UnBindRequestCodec;
098    import org.apache.directory.shared.ldap.filter.SearchScope;
099    import org.apache.directory.shared.ldap.message.AddResponseImpl;
100    import org.apache.directory.shared.ldap.message.BindResponseImpl;
101    import org.apache.directory.shared.ldap.message.CompareResponseImpl;
102    import org.apache.directory.shared.ldap.message.DeleteResponseImpl;
103    import org.apache.directory.shared.ldap.message.ModifyDnResponseImpl;
104    import org.apache.directory.shared.ldap.message.ModifyResponseImpl;
105    import org.apache.directory.shared.ldap.message.ResultCodeEnum;
106    import org.apache.directory.shared.ldap.message.SearchResponseDoneImpl;
107    import org.apache.directory.shared.ldap.name.LdapDN;
108    import org.apache.directory.shared.ldap.name.Rdn;
109    import org.apache.directory.shared.ldap.util.StringTools;
110    import org.slf4j.Logger;
111    import org.slf4j.LoggerFactory;
112    
113    
114    /**
115     * This class implements the LdapMessage message. All the actions are declared
116     * in this class. As it is a singleton, these declaration are only done once. If
117     * an action is to be added or modified, this is where the work is to be done !
118     * 
119     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
120     * @version $Rev: 764131 $, $Date: 2009-04-11 03:03:00 +0200 (Sam, 11 avr 2009) $, 
121     */
122    public class LdapMessageGrammar extends AbstractGrammar
123    {
124        // ~ Static fields/initializers
125        // -----------------------------------------------------------------
126    
127        /** The logger */
128        static final Logger log = LoggerFactory.getLogger( LdapMessageGrammar.class );
129    
130        /** A speedup for logger */
131        static final boolean IS_DEBUG = log.isDebugEnabled();
132    
133        /** The instance of grammar. LdapMessageGrammar is a singleton */
134        private static IGrammar instance = new LdapMessageGrammar();
135    
136    
137        // ~ Constructors
138        // -------------------------------------------------------------------------------
139    
140        /**
141         * Creates a new LdapMessageGrammar object.
142         */
143        private LdapMessageGrammar()
144        {
145    
146            name = LdapMessageGrammar.class.getName();
147            statesEnum = LdapStatesEnum.getInstance();
148    
149            // Create the transitions table
150            super.transitions = new GrammarTransition[LdapStatesEnum.LAST_LDAP_STATE][256];
151    
152            // ============================================================================================
153            // Transition from START to LdapMessage
154            // ============================================================================================
155            // This is the starting state :
156            // LDAPMessage --> SEQUENCE { ... 
157            //
158            // We have a LDAPMessage, and the tag must be 0x30. 
159            //
160            // The next state will be LDAP_MESSAGE_STATE
161            //
162            // We will just check that the length is not null
163            super.transitions[LdapStatesEnum.START_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
164                LdapStatesEnum.START_STATE, LdapStatesEnum.LDAP_MESSAGE_STATE, UniversalTag.SEQUENCE_TAG,
165                new GrammarAction( "LdapMessage initialization" )
166                {
167                    public void action( IAsn1Container container ) throws DecoderException
168                    {
169    
170                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
171    
172                        TLV tlv = ldapMessageContainer.getCurrentTLV();
173    
174                        // The Length should not be null
175                        if ( tlv.getLength() == 0 )
176                        {
177                            log.error( "The LdapMessage has a zero length. This is not allowed" );
178    
179                            // This will generate a PROTOCOL_ERROR
180                            throw new DecoderException( "The LdapMessage should not be empty" );
181                        }
182    
183                        // First, create a empty LdapMessage Object
184                        LdapMessageCodec ldapMessage = new LdapMessageCodec();
185    
186                        // Then stores it into the container
187                        ldapMessageContainer.setLdapMessage( ldapMessage );
188    
189                        return;
190                    }
191                } );
192    
193            // --------------------------------------------------------------------------------------------
194            // Transition from LdapMessage to Message ID
195            // --------------------------------------------------------------------------------------------
196            // LDAPMessage --> ... MessageId ...
197            //
198            // Checks that MessageId is in [0 .. 2147483647] and store the value in
199            // the LdapMessage Object
200            //
201            // (2147483647 = Integer.MAX_VALUE)
202            // The next state will be MESSAGE_ID_STATE
203            //
204            // The message ID will be temporarely stored in the container, because we can't store it
205            // into an object.
206            super.transitions[LdapStatesEnum.LDAP_MESSAGE_STATE][UniversalTag.INTEGER_TAG] = new GrammarTransition(
207                LdapStatesEnum.LDAP_MESSAGE_STATE, LdapStatesEnum.MESSAGE_ID_STATE, UniversalTag.INTEGER_TAG,
208                new GrammarAction( "Store MessageId" )
209                {
210                    public void action( IAsn1Container container ) throws DecoderException
211                    {
212    
213                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
214                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
215    
216                        // The current TLV should be a integer
217                        // We get it and store it in MessageId
218                        TLV tlv = ldapMessageContainer.getCurrentTLV();
219    
220                        // The Length should not be null
221                        if ( tlv.getLength() == 0 )
222                        {
223                            log.error( "The messageId has a zero length. This is not allowed" );
224    
225                            // This will generate a PROTOCOL_ERROR
226                            throw new DecoderException( "The messageId should not be null" );
227                        }
228    
229                        Value value = tlv.getValue();
230    
231                        try
232                        {
233                            int messageId = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
234    
235                            ldapMessage.setMessageId( messageId );
236                            ldapMessageContainer.setMessageId( messageId );
237    
238                            if ( IS_DEBUG )
239                            {
240                                log.debug( "Ldap Message Id has been decoded : " + messageId );
241                            }
242                        }
243                        catch ( IntegerDecoderException ide )
244                        {
245                            log.error( "The Message Id " + StringTools.dumpBytes( value.getData() ) + " is invalid : "
246                                + ide.getMessage() + ". The message ID must be between (0 .. 2 147 483 647)" );
247    
248                            // This will generate a PROTOCOL_ERROR                        
249                            throw new DecoderException( ide.getMessage() );
250                        }
251    
252                        return;
253                    }
254                } );
255    
256            // ********************************************************************************************
257            // We have a ProtocolOp :
258            // If the Tag is 0x42, then it's an UnBindRequest.
259            // If the Tag is 0x4A, then it's a DelRequest.
260            // If the Tag is 0x50, then it's an AbandonRequest.
261            // If the Tag is 0x60, then it's a BindRequest.
262            // If the Tag is 0x61, then it's a BindResponse.
263            // If the Tag is 0x63, then it's a SearchRequest.
264            // If the Tag is 0x64, then it's a SearchResultEntry.
265            // If the Tag is 0x65, then it's a SearchResultDone
266            // If the Tag is 0x66, then it's a ModifyRequest
267            // If the Tag is 0x67, then it's a ModifyResponse.
268            // If the Tag is 0x68, then it's an AddRequest.
269            // If the Tag is 0x69, then it's an AddResponse.
270            // If the Tag is 0x6B, then it's a DelResponse.
271            // If the Tag is 0x6C, then it's a ModifyDNRequest.
272            // If the Tag is 0x6D, then it's a ModifyDNResponse.
273            // If the Tag is 0x6E, then it's a CompareRequest
274            // If the Tag is 0x6F, then it's a CompareResponse.
275            // If the Tag is 0x73, then it's a SearchResultReference.
276            // If the Tag is 0x77, then it's an ExtendedRequest.
277            // If the Tag is 0x78, then it's an ExtendedResponse.
278            //
279            // We create the associated object in this transition, and store it into the container.
280            // ********************************************************************************************
281    
282            // --------------------------------------------------------------------------------------------
283            // Transition from Message ID to UnBindRequest Message.
284            // --------------------------------------------------------------------------------------------
285            // LdapMessage ::= ... UnBindRequest ...
286            // unbindRequest ::= [APPLICATION 2] NULL
287            // We have to switch to the UnBindRequest grammar
288            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.UNBIND_REQUEST_TAG] = new GrammarTransition(
289                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.UNBIND_REQUEST_STATE, LdapConstants.UNBIND_REQUEST_TAG,
290                new GrammarAction( "Unbind Request initialization" )
291                {
292                    public void action( IAsn1Container container ) throws DecoderException
293                    {
294    
295                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
296                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
297    
298                        TLV tlv = ldapMessageContainer.getCurrentTLV();
299                        int expectedLength = tlv.getLength();
300    
301                        // The Length should be null
302                        if ( expectedLength != 0 )
303                        {
304                            log.error( "The length of a UnBindRequest must be null, the actual value is {}", Integer
305                                .valueOf( expectedLength ) );
306    
307                            // This will generate a PROTOCOL_ERROR
308                            throw new DecoderException( "The length of a UnBindRequest must be null" );
309                        }
310    
311                        UnBindRequestCodec unBindRequest = new UnBindRequestCodec();
312    
313                        unBindRequest.setParent( ldapMessage );
314    
315                        // And we associate it to the ldapMessage Object
316                        ldapMessage.setProtocolOP( unBindRequest );
317    
318                        // We can quit now
319                        ldapMessageContainer.grammarEndAllowed( true );
320    
321                        return;
322                    }
323                } );
324    
325            // --------------------------------------------------------------------------------------------
326            // transition from UnBindRequest Message to Controls.
327            // --------------------------------------------------------------------------------------------
328            //         unbindRequest   UnbindRequest,
329            //         ... },
330            //     controls       [0] Controls OPTIONAL }
331            //
332            super.transitions[LdapStatesEnum.UNBIND_REQUEST_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
333                LdapStatesEnum.UNBIND_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
334                new ControlsInitAction() );
335    
336            // --------------------------------------------------------------------------------------------
337            // Transition from Message ID to DelRequest Message.
338            // --------------------------------------------------------------------------------------------
339            // LdapMessage ::= ... DelRequest ...
340            // delRequest ::= [APPLICATION 10] LDAPDN
341            //
342            // We store the DN to bve deleted into the DelRequest object
343            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.DEL_REQUEST_TAG] = new GrammarTransition(
344                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.DEL_REQUEST_STATE, LdapConstants.DEL_REQUEST_TAG,
345                new GrammarAction( "Init del Request" )
346                {
347                    public void action( IAsn1Container container ) throws DecoderException
348                    {
349    
350                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
351                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
352    
353                        // We can allocate the DelRequest Object
354                        DelRequestCodec delRequest = new DelRequestCodec();
355    
356                        // And store the DN into it
357                        // Get the Value and store it in the DelRequest
358                        TLV tlv = ldapMessageContainer.getCurrentTLV();
359    
360                        // We have to handle the special case of a 0 length matched
361                        // DN
362                        LdapDN entry = null;
363    
364                        if ( tlv.getLength() == 0 )
365                        {
366                            // This will generate a PROTOCOL_ERROR
367                            throw new DecoderException( "The entry must not be null" );
368                        }
369                        else
370                        {
371                            byte[] dnBytes = tlv.getValue().getData();
372    
373                            try
374                            {
375                                entry = new LdapDN( dnBytes );
376                            }
377                            catch ( InvalidNameException ine )
378                            {
379                                String msg = "The DN to delete : " + StringTools.utf8ToString( dnBytes ) + " ("
380                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
381                                log.error( "{} : {}", msg, ine.getMessage() );
382    
383                                DeleteResponseImpl response = new DeleteResponseImpl( ldapMessage.getMessageId() );
384                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
385                                    LdapDN.EMPTY_LDAPDN, ine );
386                            }
387    
388                            delRequest.setEntry( entry );
389                        }
390    
391                        // then we associate it to the ldapMessage Object
392                        ldapMessage.setProtocolOP( delRequest );
393    
394                        // We can have an END transition
395                        ldapMessageContainer.grammarEndAllowed( true );
396    
397                        if ( IS_DEBUG )
398                        {
399                            log.debug( "Deleting DN {}", entry );
400                        }
401                    }
402                } );
403    
404            // --------------------------------------------------------------------------------------------
405            // transition from DelRequest Message to Controls.
406            // --------------------------------------------------------------------------------------------
407            //         delRequest   DelRequest,
408            //         ... },
409            //     controls       [0] Controls OPTIONAL }
410            //
411            super.transitions[LdapStatesEnum.DEL_REQUEST_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
412                LdapStatesEnum.DEL_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
413                new ControlsInitAction() );
414    
415            // --------------------------------------------------------------------------------------------
416            // Transition from Message ID to AbandonRequest Message.
417            // --------------------------------------------------------------------------------------------
418            // LdapMessage ::= ... AbandonRequest ...
419            // AbandonRequest ::= [APPLICATION 16] MessageID
420            //
421            // Create the AbandonRequest object, and store the ID in it
422            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.ABANDON_REQUEST_TAG] = new GrammarTransition(
423                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.ABANDON_REQUEST_STATE, LdapConstants.ABANDON_REQUEST_TAG,
424                new GrammarAction( "Init Abandon Request" )
425                {
426                    public void action( IAsn1Container container ) throws DecoderException
427                    {
428    
429                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
430                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
431    
432                        // The current TLV should be a integer
433                        // We get it and store it in MessageId
434                        TLV tlv = ldapMessageContainer.getCurrentTLV();
435    
436                        Value value = tlv.getValue();
437    
438                        if ( ( value == null ) || ( value.getData() == null ) )
439                        {
440                            String msg = "The AbandonRequest messageId must not be null";
441                            log.error( msg );
442    
443                            // This will generate a PROTOCOL_ERROR
444                            throw new DecoderException( msg );
445                        }
446    
447                        try
448                        {
449                            int abandonnedMessageId = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
450    
451                            // Ok, the Message ID is correct. We have to store it
452                            // in the AbandonRequest Object
453                            AbandonRequestCodec abandonRequest = new AbandonRequestCodec();
454                            abandonRequest.setAbandonedMessageId( abandonnedMessageId );
455                            ldapMessage.setProtocolOP( abandonRequest );
456    
457                            if ( IS_DEBUG )
458                            {
459                                log
460                                    .debug( "AbandonMessage Id has been decoded : {}", Integer
461                                        .valueOf( abandonnedMessageId ) );
462                            }
463    
464                            ldapMessageContainer.grammarEndAllowed( true );
465                            return;
466                        }
467                        catch ( IntegerDecoderException ide )
468                        {
469                            log.error( "The Abandonned Message Id {} is invalid : {}."
470                                + " The message ID must be between (0 .. 2 147 483 647)", StringTools.dumpBytes( value
471                                .getData() ), ide.getMessage() );
472    
473                            // This will generate a PROTOCOL_ERROR
474                            throw new DecoderException( ide.getMessage() );
475                        }
476                    }
477                } );
478    
479            // --------------------------------------------------------------------------------------------
480            // transition from AbandonRequest Message to Controls.
481            // --------------------------------------------------------------------------------------------
482            //         abandonRequest   AbandonRequest,
483            //         ... },
484            //     controls       [0] Controls OPTIONAL }
485            //
486            super.transitions[LdapStatesEnum.ABANDON_REQUEST_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
487                LdapStatesEnum.ABANDON_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
488                new ControlsInitAction() );
489    
490            // --------------------------------------------------------------------------------------------
491            // Transition from Message ID to BindRequest Message.
492            // --------------------------------------------------------------------------------------------
493            // LdapMessage ::= ... BindRequest ...
494            // BindRequest ::= [APPLICATION 0] SEQUENCE { ...
495            //
496            // We have to allocate a BindRequest
497            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.BIND_REQUEST_TAG] = new GrammarTransition(
498                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.BIND_REQUEST_STATE, LdapConstants.BIND_REQUEST_TAG,
499                new GrammarAction( "Init BindRequest" )
500                {
501                    public void action( IAsn1Container container ) throws DecoderException
502                    {
503                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
504                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
505    
506                        // We will check that the request is not null
507                        TLV tlv = ldapMessageContainer.getCurrentTLV();
508    
509                        if ( tlv.getLength() == 0 )
510                        {
511                            String msg = "The BindRequest must not be null";
512                            log.error( msg );
513    
514                            // This will generate a PROTOCOL_ERROR
515                            throw new DecoderException( msg );
516                        }
517    
518                        // Now, we can allocate the BindRequest Object
519                        ldapMessage.setProtocolOP( new BindRequestCodec() );
520                    }
521                } );
522    
523            // --------------------------------------------------------------------------------------------
524            // Transition from BindRequest to version
525            // --------------------------------------------------------------------------------------------
526            // BindRequest ::= [APPLICATION 0] SEQUENCE {
527            //     version                 INTEGER (1 ..  127),
528            //     ....
529            //
530            // The Ldap version is parsed and stored into the BindRequest object
531            super.transitions[LdapStatesEnum.BIND_REQUEST_STATE][UniversalTag.INTEGER_TAG] = new GrammarTransition(
532                LdapStatesEnum.BIND_REQUEST_STATE, LdapStatesEnum.VERSION_STATE, UniversalTag.INTEGER_TAG,
533                new GrammarAction( "Store version" )
534                {
535                    public void action( IAsn1Container container ) throws DecoderException
536                    {
537    
538                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
539                        BindRequestCodec bindRequestMessage = ldapMessageContainer.getLdapMessage().getBindRequest();
540    
541                        // The current TLV should be a integer between 1 and 127
542                        // We get it and store it in Version
543                        TLV tlv = ldapMessageContainer.getCurrentTLV();
544    
545                        Value value = tlv.getValue();
546    
547                        try
548                        {
549                            int version = IntegerDecoder.parse( value, 1, 127 );
550    
551                            if ( IS_DEBUG )
552                            {
553                                log.debug( "Ldap version ", Integer.valueOf( version ) );
554                            }
555    
556                            bindRequestMessage.setVersion( version );
557                        }
558                        catch ( IntegerDecoderException ide )
559                        {
560                            log.error( "The version {} is invalid : {}. The version must be between (0 .. 127)",
561                                StringTools.dumpBytes( value.getData() ), ide.getMessage() );
562    
563                            // This will generate a PROTOCOL_ERROR
564                            throw new DecoderException( ide.getMessage() );
565                        }
566    
567                        return;
568                    }
569                } );
570    
571            // --------------------------------------------------------------------------------------------
572            // Transition from version to name
573            // --------------------------------------------------------------------------------------------
574            // BindRequest ::= [APPLICATION 0] SEQUENCE {
575            //     ....
576            //     name                    LDAPDN,
577            //     ....
578            //
579            // The Ldap version is parsed and stored into the BindRequest object
580            super.transitions[LdapStatesEnum.VERSION_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
581                LdapStatesEnum.VERSION_STATE, LdapStatesEnum.NAME_STATE, UniversalTag.OCTET_STRING_TAG, new GrammarAction(
582                    "Store Bind Name value" )
583                {
584                    public void action( IAsn1Container container ) throws DecoderException
585                    {
586                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
587                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
588                        BindRequestCodec bindRequestMessage = ldapMessage.getBindRequest();
589    
590                        // Get the Value and store it in the BindRequest
591                        TLV tlv = ldapMessageContainer.getCurrentTLV();
592    
593                        // We have to handle the special case of a 0 length name
594                        if ( tlv.getLength() == 0 )
595                        {
596                            bindRequestMessage.setName( LdapDN.EMPTY_LDAPDN );
597                        }
598                        else
599                        {
600                            byte[] dnBytes = tlv.getValue().getData();
601    
602                            try
603                            {
604                                LdapDN dn = new LdapDN( dnBytes );
605                                bindRequestMessage.setName( dn );
606                            }
607                            catch ( InvalidNameException ine )
608                            {
609                                String msg = "Incorrect DN given : " + StringTools.utf8ToString( dnBytes ) + " ("
610                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
611                                log.error( "{} : {}", msg, ine.getMessage() );
612    
613                                BindResponseImpl response = new BindResponseImpl( ldapMessage.getMessageId() );
614    
615                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
616                                    LdapDN.EMPTY_LDAPDN, ine );
617                            }
618                        }
619    
620                        if ( IS_DEBUG )
621                        {
622                            log.debug( " The Bind name is {}", bindRequestMessage.getName() );
623                        }
624    
625                        return;
626                    }
627                } );
628    
629            // --------------------------------------------------------------------------------------------
630            // Transition from name to Simple Authentication
631            // --------------------------------------------------------------------------------------------
632            // BindRequest ::= [APPLICATION 0] SEQUENCE {
633            //     ....
634            //     authentication          AuthenticationChoice }
635            //
636            // AuthenticationChoice ::= CHOICE {
637            //     simple                  [0] OCTET STRING,
638            //     ...
639            //
640            // We have to create an Authentication Object to store the credentials.
641            super.transitions[LdapStatesEnum.NAME_STATE][LdapConstants.BIND_REQUEST_SIMPLE_TAG] = new GrammarTransition(
642                LdapStatesEnum.NAME_STATE, LdapStatesEnum.SIMPLE_STATE, LdapConstants.BIND_REQUEST_SIMPLE_TAG,
643                new GrammarAction( "Store Bind Simple Authentication value" )
644                {
645                    public void action( IAsn1Container container ) throws DecoderException
646                    {
647                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
648    
649                        BindRequestCodec bindRequestMessage = ldapMessageContainer.getLdapMessage().getBindRequest();
650                        TLV tlv = ldapMessageContainer.getCurrentTLV();
651    
652                        // Allocate the Authentication Object
653                        SimpleAuthentication authentication = null;
654    
655                        authentication = new SimpleAuthentication();
656    
657                        authentication.setParent( bindRequestMessage );
658    
659                        bindRequestMessage.setAuthentication( authentication );
660    
661                        // We have to handle the special case of a 0 length simple
662                        if ( tlv.getLength() == 0 )
663                        {
664                            authentication.setSimple( StringTools.EMPTY_BYTES );
665                        }
666                        else
667                        {
668                            authentication.setSimple( tlv.getValue().getData() );
669                        }
670    
671                        // We can have an END transition
672                        ldapMessageContainer.grammarEndAllowed( true );
673    
674                        if ( IS_DEBUG )
675                        {
676                            log.debug( "The simple authentication is : {}", authentication.getSimple() );
677                        }
678                    }
679                } );
680    
681            // --------------------------------------------------------------------------------------------
682            // transition from Simple Authentication to Controls.
683            // --------------------------------------------------------------------------------------------
684            //         bindRequest   BindRequest,
685            //         ... },
686            //     controls       [0] Controls OPTIONAL }
687            //
688            super.transitions[LdapStatesEnum.SIMPLE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
689                LdapStatesEnum.SIMPLE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
690                new ControlsInitAction() );
691    
692            // --------------------------------------------------------------------------------------------
693            // Transition from name to SASL Authentication
694            // --------------------------------------------------------------------------------------------
695            // BindRequest ::= [APPLICATION 0] SEQUENCE {
696            //     ....
697            //     authentication          AuthenticationChoice }
698            //
699            // AuthenticationChoice ::= CHOICE {
700            //     ...
701            //     sasl                  [3] SaslCredentials }
702            //     ...
703            //
704            // We have to create an Authentication Object to store the credentials.
705            super.transitions[LdapStatesEnum.NAME_STATE][LdapConstants.BIND_REQUEST_SASL_TAG] = new GrammarTransition(
706                LdapStatesEnum.NAME_STATE, LdapStatesEnum.SASL_STATE, LdapConstants.BIND_REQUEST_SASL_TAG,
707                new GrammarAction( "Initialize Bind SASL Authentication" )
708                {
709                    public void action( IAsn1Container container ) throws DecoderException
710                    {
711                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
712                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
713                        BindRequestCodec bindRequestMessage = ldapMessage.getBindRequest();
714                        TLV tlv = ldapMessageContainer.getCurrentTLV();
715    
716                        // We will check that the sasl is not null
717                        if ( tlv.getLength() == 0 )
718                        {
719                            String msg = "The SaslCredential must not be null";
720                            log.error( msg );
721    
722                            BindResponseImpl response = new BindResponseImpl( ldapMessage.getMessageId() );
723    
724                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_CREDENTIALS,
725                                bindRequestMessage.getName(), null );
726                        }
727    
728                        // Create the SaslCredentials Object
729                        SaslCredentials authentication = new SaslCredentials();
730    
731                        authentication.setParent( bindRequestMessage );
732    
733                        bindRequestMessage.setAuthentication( authentication );
734    
735                        if ( IS_DEBUG )
736                        {
737                            log.debug( "The SaslCredential has been created" );
738                        }
739    
740                        return;
741                    }
742                } );
743    
744            // --------------------------------------------------------------------------------------------
745            // Transition from SASL Authentication to Mechanism
746            // --------------------------------------------------------------------------------------------
747            // SaslCredentials ::= SEQUENCE {
748            //     mechanism   LDAPSTRING,
749            //     ...
750            //
751            // We have to store the mechanism.
752            super.transitions[LdapStatesEnum.SASL_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
753                LdapStatesEnum.SASL_STATE, LdapStatesEnum.MECHANISM_STATE, UniversalTag.OCTET_STRING_TAG,
754                new GrammarAction( "Store SASL mechanism" )
755                {
756                    public void action( IAsn1Container container ) throws DecoderException
757                    {
758                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
759                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
760                        BindRequestCodec bindRequestMessage = ldapMessage.getBindRequest();
761                        TLV tlv = ldapMessageContainer.getCurrentTLV();
762    
763                        // Get the SaslCredentials Object
764                        SaslCredentials authentication = bindRequestMessage.getSaslAuthentication();
765    
766                        // We have to handle the special case of a 0 length
767                        // mechanism
768                        if ( tlv.getLength() == 0 )
769                        {
770                            authentication.setMechanism( "" );
771                        }
772                        else
773                        {
774                            authentication.setMechanism( StringTools.utf8ToString( tlv.getValue().getData() ) );
775                        }
776    
777                        // We can have an END transition
778                        ldapMessageContainer.grammarEndAllowed( true );
779    
780                        if ( IS_DEBUG )
781                        {
782                            log.debug( "The mechanism is : {}", authentication.getMechanism() );
783                        }
784    
785                        return;
786                    }
787                } );
788    
789            // --------------------------------------------------------------------------------------------
790            // Transition from Mechanism to Credentials
791            // --------------------------------------------------------------------------------------------
792            // SaslCredentials ::= SEQUENCE {
793            //     ...
794            //     credentials OCTET STRING OPTIONAL }
795            //
796            // We have to store the mechanism.
797            super.transitions[LdapStatesEnum.MECHANISM_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
798                LdapStatesEnum.MECHANISM_STATE, LdapStatesEnum.CREDENTIALS_STATE, UniversalTag.OCTET_STRING_TAG,
799                new GrammarAction( "Store SASL credentials" )
800                {
801                    public void action( IAsn1Container container )
802                    {
803                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
804    
805                        BindRequestCodec bindRequestMessage = ldapMessageContainer.getLdapMessage().getBindRequest();
806    
807                        // Get the Value and store it in the BindRequest
808                        TLV tlv = ldapMessageContainer.getCurrentTLV();
809    
810                        SaslCredentials credentials = bindRequestMessage.getSaslAuthentication();
811    
812                        // We have to handle the special case of a 0 length
813                        // credentials
814                        if ( tlv.getLength() == 0 )
815                        {
816                            credentials.setCredentials( StringTools.EMPTY_BYTES );
817                        }
818                        else
819                        {
820                            credentials.setCredentials( tlv.getValue().getData() );
821                        }
822    
823                        // We can have an END transition
824                        ldapMessageContainer.grammarEndAllowed( true );
825                        if ( IS_DEBUG )
826                        {
827                            log.debug( "The credentials are : {}", credentials.getCredentials() );
828                        }
829    
830                        return;
831                    }
832                } );
833    
834            // --------------------------------------------------------------------------------------------
835            // transition from from Mechanism to Controls.
836            // --------------------------------------------------------------------------------------------
837            //         bindRequest   BindRequest,
838            //         ... },
839            //     controls       [0] Controls OPTIONAL }
840            //
841            super.transitions[LdapStatesEnum.MECHANISM_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
842                LdapStatesEnum.MECHANISM_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
843                new ControlsInitAction() );
844    
845            // --------------------------------------------------------------------------------------------
846            // transition from credentials to Controls.
847            // --------------------------------------------------------------------------------------------
848            //         bindRequest   BindRequest,
849            //         ... },
850            //     controls       [0] Controls OPTIONAL }
851            //
852            super.transitions[LdapStatesEnum.CREDENTIALS_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
853                LdapStatesEnum.CREDENTIALS_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
854                new ControlsInitAction() );
855    
856            // --------------------------------------------------------------------------------------------
857            // Transition from MessageId to BindResponse message 
858            // --------------------------------------------------------------------------------------------
859            // LdapMessage ::= ... BindResponse ...
860            // BindResponse ::= [APPLICATION 1] SEQUENCE { ...
861            // We have to switch to the BindResponse grammar
862            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.BIND_RESPONSE_TAG] = new GrammarTransition(
863                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.BIND_RESPONSE_STATE, LdapConstants.BIND_RESPONSE_TAG,
864                new GrammarAction( "Init BindReponse" )
865                {
866                    public void action( IAsn1Container container )
867                    {
868    
869                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
870                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
871    
872                        // Now, we can allocate the BindRequest Object
873                        BindResponseCodec bindResponse = new BindResponseCodec();
874    
875                        // As this is a new Constructed object, we have to init its
876                        // length
877                        bindResponse.setParent( ldapMessage );
878    
879                        // And we associate it to the ldapMessage Object
880                        ldapMessage.setProtocolOP( bindResponse );
881                    }
882                } );
883    
884            // --------------------------------------------------------------------------------------------
885            // Transition from BindResponse message to Result Code BR 
886            // --------------------------------------------------------------------------------------------
887            // BindResponse ::= [APPLICATION 1] SEQUENCE {
888            //     COMPONENTS OF LDAPResult,
889            //     ...
890            //
891            // LDAPResult ::= SEQUENCE {
892            //     resultCode ENUMERATED { 
893            //         ...
894            // 
895            // Stores the result code into the Bind Response object
896            super.transitions[LdapStatesEnum.BIND_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
897                LdapStatesEnum.BIND_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_BR_STATE, UniversalTag.ENUMERATED_TAG,
898                new ResultCodeAction() );
899    
900            // --------------------------------------------------------------------------------------------
901            // Transition from Result Code BR to Matched DN BR 
902            // --------------------------------------------------------------------------------------------
903            // LDAPResult ::= SEQUENCE {
904            //     ...
905            //     matchedDN LDAPDN,
906            //     ...
907            //
908            // Stores the matched DN
909            super.transitions[LdapStatesEnum.RESULT_CODE_BR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
910                LdapStatesEnum.RESULT_CODE_BR_STATE, LdapStatesEnum.MATCHED_DN_BR_STATE, UniversalTag.OCTET_STRING_TAG,
911                new MatchedDNAction() );
912    
913            // --------------------------------------------------------------------------------------------
914            // Transition from Matched DN BR to Error Message BR 
915            // --------------------------------------------------------------------------------------------
916            // LDAPResult ::= SEQUENCE {
917            //     ...
918            //     errorMessage LDAPString,
919            //     ...
920            //
921            // Stores the error message
922            super.transitions[LdapStatesEnum.MATCHED_DN_BR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
923                LdapStatesEnum.MATCHED_DN_BR_STATE, LdapStatesEnum.ERROR_MESSAGE_BR_STATE, UniversalTag.OCTET_STRING_TAG,
924                new ErrorMessageAction() );
925    
926            // --------------------------------------------------------------------------------------------
927            // Transition from Error Message BR to Server SASL credentials 
928            // --------------------------------------------------------------------------------------------
929            // BindResponse ::= APPLICATION 1] SEQUENCE {
930            //     ...
931            //     serverSaslCreds [7] OCTET STRING OPTIONAL }
932            //
933            // Stores the sasl credentials 
934            super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE][LdapConstants.SERVER_SASL_CREDENTIAL_TAG] = new GrammarTransition(
935                LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE,
936                LdapConstants.SERVER_SASL_CREDENTIAL_TAG, new ServerSASLCredsAction() );
937    
938            // --------------------------------------------------------------------------------------------
939            // Transition from Error Message BR to Referrals BR 
940            // --------------------------------------------------------------------------------------------
941            // LDAPResult ::= SEQUENCE {
942            //     ...
943            //     referral   [3] Referral OPTIONNAL }
944            //
945            // Initialiaze the referrals list 
946            super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE][LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG] = 
947                new GrammarTransition(
948                LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.REFERRALS_BR_STATE,
949                LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, new InitReferralsAction() );
950    
951            // --------------------------------------------------------------------------------------------
952            // Transition from Referrals BR to Referral BR 
953            // --------------------------------------------------------------------------------------------
954            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
955            // URI ::= LDAPString
956            //
957            // Add a first Referral
958            super.transitions[LdapStatesEnum.REFERRALS_BR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
959                LdapStatesEnum.REFERRALS_BR_STATE, LdapStatesEnum.REFERRAL_BR_STATE, UniversalTag.OCTET_STRING_TAG,
960                new ReferralAction() );
961    
962            // --------------------------------------------------------------------------------------------
963            // Transition from Referral BR to Referral BR 
964            // --------------------------------------------------------------------------------------------
965            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
966            // URI ::= LDAPString
967            //
968            // Adda new Referral
969            super.transitions[LdapStatesEnum.REFERRAL_BR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
970                LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.REFERRAL_BR_STATE, UniversalTag.OCTET_STRING_TAG,
971                new ReferralAction() );
972    
973            // --------------------------------------------------------------------------------------------
974            // Transition from Referral BR to Server SASL Credentials 
975            // --------------------------------------------------------------------------------------------
976            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
977            // URI ::= LDAPString
978            //
979            // Adda new Referral
980            super.transitions[LdapStatesEnum.REFERRAL_BR_STATE][LdapConstants.SERVER_SASL_CREDENTIAL_TAG] = new GrammarTransition(
981                LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE,
982                LdapConstants.SERVER_SASL_CREDENTIAL_TAG, new ServerSASLCredsAction() );
983    
984            // --------------------------------------------------------------------------------------------
985            // Transition from Referral BR to Controls 
986            // --------------------------------------------------------------------------------------------
987            //         bindResponse   BindResponse,
988            //         ... },
989            //     controls       [0] Controls OPTIONAL }
990            //
991            // Adda new Referral
992            super.transitions[LdapStatesEnum.REFERRAL_BR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
993                LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
994                new ControlsInitAction() );
995    
996            // --------------------------------------------------------------------------------------------
997            // Transition from Error Message BR to controls 
998            // --------------------------------------------------------------------------------------------
999            //         bindResponse   BindResponse,
1000            //         ... },
1001            //     controls       [0] Controls OPTIONAL }
1002            //
1003            //  
1004            super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1005                LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1006                new ControlsInitAction() );
1007    
1008            // --------------------------------------------------------------------------------------------
1009            // Transition from Server SASL credentials to Controls 
1010            // --------------------------------------------------------------------------------------------
1011            //         bindResponse   BindResponse,
1012            //         ... },
1013            //     controls       [0] Controls OPTIONAL }
1014            //
1015            super.transitions[LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1016                LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1017                new ControlsInitAction() );
1018    
1019            // --------------------------------------------------------------------------------------------
1020            // Transition from Result Code to Matched DN 
1021            // --------------------------------------------------------------------------------------------
1022            // LDAPResult ::= SEQUENCE {
1023            //     ...
1024            //     matchedDN LDAPDN,
1025            //     ...
1026            //
1027            // Stores the matched DN
1028            super.transitions[LdapStatesEnum.RESULT_CODE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1029                LdapStatesEnum.RESULT_CODE_STATE, LdapStatesEnum.MATCHED_DN_STATE, UniversalTag.OCTET_STRING_TAG,
1030                new MatchedDNAction() );
1031    
1032            // --------------------------------------------------------------------------------------------
1033            // Transition from Matched DN to Error Message 
1034            // --------------------------------------------------------------------------------------------
1035            // LDAPResult ::= SEQUENCE {
1036            //     ...
1037            //     errorMessage LDAPString,
1038            //     ...
1039            //
1040            // Stores the error message
1041            super.transitions[LdapStatesEnum.MATCHED_DN_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1042                LdapStatesEnum.MATCHED_DN_STATE, LdapStatesEnum.ERROR_MESSAGE_STATE, UniversalTag.OCTET_STRING_TAG,
1043                new ErrorMessageAction() );
1044    
1045            // --------------------------------------------------------------------------------------------
1046            // Transition from Error Message to Referrals
1047            // --------------------------------------------------------------------------------------------
1048            // LDAPResult ::= SEQUENCE {
1049            //     ...
1050            //     referral   [3] Referral OPTIONNAL }
1051            //
1052            // Initialiaze the referrals list 
1053            super.transitions[LdapStatesEnum.ERROR_MESSAGE_STATE][LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG] = 
1054                new GrammarTransition(
1055                LdapStatesEnum.ERROR_MESSAGE_STATE, LdapStatesEnum.REFERRALS_STATE,
1056                LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, new GrammarAction( "Init referrals list" )
1057                {
1058                    public void action( IAsn1Container container ) throws DecoderException
1059                    {
1060                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1061                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1062                        LdapResponseCodec response = ldapMessage.getLdapResponse();
1063                        LdapResultCodec ldapResult = response.getLdapResult();
1064    
1065                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1066    
1067                        // If we hae a Referrals sequence, then it should not be empty
1068                        // sasl credentials
1069                        if ( tlv.getLength() == 0 )
1070                        {
1071                            String msg = "The Referrals must not be null";
1072                            log.error( msg );
1073    
1074                            // This will generate a PROTOCOL_ERROR
1075                            throw new DecoderException( msg );
1076                        }
1077    
1078                        ldapResult.initReferrals();
1079                    }
1080                } );
1081    
1082            // --------------------------------------------------------------------------------------------
1083            // Transition from Referrals to Referral 
1084            // --------------------------------------------------------------------------------------------
1085            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
1086            // URI ::= LDAPString
1087            //
1088            // Add a first Referral
1089            super.transitions[LdapStatesEnum.REFERRALS_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1090                LdapStatesEnum.REFERRALS_STATE, LdapStatesEnum.REFERRAL_STATE, UniversalTag.OCTET_STRING_TAG,
1091                new ReferralAction() );
1092    
1093            // --------------------------------------------------------------------------------------------
1094            // Transition from Referral to Referral 
1095            // --------------------------------------------------------------------------------------------
1096            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
1097            // URI ::= LDAPString
1098            //
1099            // Adda new Referral
1100            super.transitions[LdapStatesEnum.REFERRAL_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1101                LdapStatesEnum.REFERRAL_STATE, LdapStatesEnum.REFERRAL_STATE, UniversalTag.OCTET_STRING_TAG,
1102                new ReferralAction() );
1103    
1104            // --------------------------------------------------------------------------------------------
1105            // Transition from Referral to Controls 
1106            // --------------------------------------------------------------------------------------------
1107            //         xxxResponse   xxxResponse,
1108            //         ... },
1109            //     controls       [0] Controls OPTIONAL }
1110            //
1111            // Adda new Referral
1112            super.transitions[LdapStatesEnum.REFERRAL_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1113                LdapStatesEnum.REFERRAL_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1114                new ControlsInitAction() );
1115    
1116            // --------------------------------------------------------------------------------------------
1117            // Transition from Error Message to controls 
1118            // --------------------------------------------------------------------------------------------
1119            //         xxxResponse   xxxResponse,
1120            //         ... },
1121            //     controls       [0] Controls OPTIONAL }
1122            //
1123            //  
1124            super.transitions[LdapStatesEnum.ERROR_MESSAGE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1125                LdapStatesEnum.ERROR_MESSAGE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1126                new ControlsInitAction() );
1127    
1128            // --------------------------------------------------------------------------------------------
1129            // Transition from MessageId to SearchResultEntry Message.
1130            // --------------------------------------------------------------------------------------------
1131            // LdapMessage ::= ... SearchResultEntry ...
1132            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1133            //
1134            // Initialize the searchResultEntry object
1135            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.SEARCH_RESULT_ENTRY_TAG] = new GrammarTransition(
1136                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE,
1137                LdapConstants.SEARCH_RESULT_ENTRY_TAG, new GrammarAction( "Init SearchResultEntry" )
1138                {
1139                    public void action( IAsn1Container container )
1140                    {
1141    
1142                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1143                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1144    
1145                        // Now, we can allocate the SearchResultEntry Object
1146                        // And we associate it to the ldapMessage Object
1147                        ldapMessage.setProtocolOP( new SearchResultEntryCodec() );
1148                    }
1149                } );
1150    
1151            // --------------------------------------------------------------------------------------------
1152            // Transition from SearchResultEntry Message to ObjectName
1153            // --------------------------------------------------------------------------------------------
1154            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1155            // objectName LDAPDN,
1156            // ...
1157            //
1158            // Store the object name.
1159            super.transitions[LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1160                LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE, LdapStatesEnum.OBJECT_NAME_STATE, UniversalTag.OCTET_STRING_TAG,
1161                new GrammarAction( "Store search result entry object name Value" )
1162                {
1163                    public void action( IAsn1Container container ) throws DecoderException
1164                    {
1165    
1166                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1167                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1168                        SearchResultEntryCodec searchResultEntry = ldapMessage.getSearchResultEntry();
1169    
1170                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1171    
1172                        LdapDN objectName = LdapDN.EMPTY_LDAPDN;
1173    
1174                        // Store the value.
1175                        if ( tlv.getLength() == 0 )
1176                        {
1177                            searchResultEntry.setObjectName( objectName );
1178                        }
1179                        else
1180                        {
1181                            byte[] dnBytes = tlv.getValue().getData();
1182    
1183                            try
1184                            {
1185                                objectName = new LdapDN( dnBytes );
1186                            }
1187                            catch ( InvalidNameException ine )
1188                            {
1189                                // This is for the client side. We will never decode LdapResult on the server
1190                                String msg = "The DN " + StringTools.dumpBytes( dnBytes ) + "is invalid : "
1191                                    + ine.getMessage();
1192                                log.error( "{} : {}", msg, ine.getMessage() );
1193                                throw new DecoderException( msg, ine );
1194                            }
1195    
1196                            searchResultEntry.setObjectName( objectName );
1197                        }
1198    
1199                        if ( IS_DEBUG )
1200                        {
1201                            log.debug( "Search Result Entry DN found : {}", searchResultEntry.getObjectName() );
1202                        }
1203                    }
1204                } );
1205    
1206            // --------------------------------------------------------------------------------------------
1207            // Transition from ObjectName to AttributesSR
1208            // --------------------------------------------------------------------------------------------
1209            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1210            // ...
1211            // attributes PartialAttributeList }
1212            //
1213            // PartialAttributeList ::= *SEQUENCE* OF SEQUENCE {
1214            // ...
1215            //
1216            // We may have no attributes. Just allows the grammar to end
1217            super.transitions[LdapStatesEnum.OBJECT_NAME_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1218                LdapStatesEnum.OBJECT_NAME_STATE, LdapStatesEnum.ATTRIBUTES_SR_STATE, UniversalTag.SEQUENCE_TAG,
1219                new GrammarAction( "Pop and end allowed" )
1220                {
1221                    public void action( IAsn1Container container ) throws DecoderException
1222                    {
1223                        container.grammarEndAllowed( true );
1224                    }
1225                } );
1226    
1227            // --------------------------------------------------------------------------------------------
1228            // Transition from AttributesSR to PartialAttributesList
1229            // --------------------------------------------------------------------------------------------
1230            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1231            // ...
1232            // attributes PartialAttributeList }
1233            //
1234            // PartialAttributeList ::= SEQUENCE OF *SEQUENCE* {
1235            // ...
1236            //
1237            // nothing to do
1238            super.transitions[LdapStatesEnum.ATTRIBUTES_SR_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1239                LdapStatesEnum.ATTRIBUTES_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE,
1240                UniversalTag.SEQUENCE_TAG, null );
1241    
1242            // --------------------------------------------------------------------------------------------
1243            // Transition from AttributesSR to Controls
1244            // --------------------------------------------------------------------------------------------
1245            //     searchResultEntry SearchResultEntry,
1246            //     ... },
1247            // controls   [0] Controls OPTIONAL }
1248            //
1249            // Initialize the controls
1250            super.transitions[LdapStatesEnum.ATTRIBUTES_SR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1251                LdapStatesEnum.ATTRIBUTES_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1252                new ControlsInitAction() );
1253    
1254            // --------------------------------------------------------------------------------------------
1255            // Transition from PartialAttributesList to typeSR
1256            // --------------------------------------------------------------------------------------------
1257            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1258            // ...
1259            // attributes PartialAttributeList }
1260            //
1261            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1262            //     type  AttributeDescription,
1263            //     ...
1264            //
1265            // Store the attribute's name.
1266            super.transitions[LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1267                LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE, LdapStatesEnum.TYPE_SR_STATE, UniversalTag.OCTET_STRING_TAG,
1268                new GrammarAction( "Store search result entry object name Value" )
1269                {
1270                    public void action( IAsn1Container container ) throws DecoderException
1271                    {
1272                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1273                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1274                        SearchResultEntryCodec searchResultEntry = ldapMessage.getSearchResultEntry();
1275    
1276                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1277    
1278                        String type = "";
1279    
1280                        // Store the name
1281                        if ( tlv.getLength() == 0 )
1282                        {
1283                            // The type can't be null
1284                            String msg = "The AttributeType can't be empty";
1285                            log.error( msg );
1286                            throw new DecoderException( msg );
1287                        }
1288                        else
1289                        {
1290                            type = StringTools.getType( tlv.getValue().getData() );
1291                            searchResultEntry.addAttributeValues( type );
1292                        }
1293    
1294                        if ( IS_DEBUG )
1295                        {
1296                            log.debug( "Attribute type : {}", type );
1297                        }
1298                    }
1299                } );
1300    
1301            // --------------------------------------------------------------------------------------------
1302            // Transition from typeSR to ValsSR
1303            // --------------------------------------------------------------------------------------------
1304            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1305            // ...
1306            // attributes PartialAttributeList }
1307            //
1308            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1309            //     ...
1310            //     vals SET OF AttributeValue }
1311            //
1312            // We may have no value. Just allows the grammar to end
1313            super.transitions[LdapStatesEnum.TYPE_SR_STATE][UniversalTag.SET_TAG] = new GrammarTransition(
1314                LdapStatesEnum.TYPE_SR_STATE, LdapStatesEnum.VALS_SR_STATE, UniversalTag.SET_TAG, new GrammarAction(
1315                    "Grammar end allowed" )
1316                {
1317                    public void action( IAsn1Container container ) throws DecoderException
1318                    {
1319                        container.grammarEndAllowed( true );
1320                    }
1321                } );
1322    
1323            // --------------------------------------------------------------------------------------------
1324            // Transition from ValsSR to AttributeValueSR
1325            // --------------------------------------------------------------------------------------------
1326            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1327            //     ...
1328            //     vals SET OF AttributeValue }
1329            //
1330            // AttributeValue ::= OCTET STRING
1331            // 
1332            // Store the attribute value
1333            super.transitions[LdapStatesEnum.VALS_SR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1334                LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, UniversalTag.OCTET_STRING_TAG,
1335                new SearchResultAttributeValueAction() );
1336    
1337            // --------------------------------------------------------------------------------------------
1338            // Transition from ValsSR to PartialAttributesList
1339            // --------------------------------------------------------------------------------------------
1340            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1341            //     ...
1342            //     vals SET OF AttributeValue }
1343            // 
1344            // Loop when we don't have any attribute value. Nothing to do
1345            super.transitions[LdapStatesEnum.VALS_SR_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1346                LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE, UniversalTag.SEQUENCE_TAG, null );
1347    
1348            // --------------------------------------------------------------------------------------------
1349            // Transition from ValsSR to Controls
1350            // --------------------------------------------------------------------------------------------
1351            //     searchResultEntry SearchResultEntry,
1352            //     ... },
1353            // controls   [0] Controls OPTIONAL }
1354            //
1355            // Initialize the controls
1356            super.transitions[LdapStatesEnum.VALS_SR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1357                LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1358                new ControlsInitAction() );
1359    
1360            // --------------------------------------------------------------------------------------------
1361            // Transition from AttributeValueSR to AttributeValueSR 
1362            // --------------------------------------------------------------------------------------------
1363            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1364            //     ...
1365            //     vals SET OF AttributeValue }
1366            //
1367            // AttributeValue ::= OCTET STRING
1368            // 
1369            // Store the attribute value
1370            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1371                LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE,
1372                UniversalTag.OCTET_STRING_TAG, new SearchResultAttributeValueAction() );
1373    
1374            // --------------------------------------------------------------------------------------------
1375            // Transition from AttributeValueSR to PartialAttributesList
1376            // --------------------------------------------------------------------------------------------
1377            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1378            //     ...
1379            //     vals SET OF AttributeValue }
1380            // 
1381            // Loop when we don't have any attribute value. Nothing to do
1382            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1383                LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE,
1384                UniversalTag.SEQUENCE_TAG, null );
1385    
1386            // --------------------------------------------------------------------------------------------
1387            // Transition from AttributeValueSR to Controls
1388            // --------------------------------------------------------------------------------------------
1389            //     searchResultEntry SearchResultEntry,
1390            //     ... },
1391            // controls   [0] Controls OPTIONAL }
1392            //
1393            // Initialize the controls
1394            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1395                LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1396                new ControlsInitAction() );
1397    
1398            // --------------------------------------------------------------------------------------------
1399            // SearchResultDone Message.
1400            // --------------------------------------------------------------------------------------------
1401            // LdapMessage ::= ... SearchResultDone ...
1402            // SearchResultDone ::= [APPLICATION 5] SEQUENCE { ...
1403            // 
1404            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.SEARCH_RESULT_DONE_TAG] = new GrammarTransition(
1405                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_RESULT_DONE_STATE,
1406                LdapConstants.SEARCH_RESULT_DONE_TAG, new GrammarAction( "Init search Result Done" )
1407                {
1408                    public void action( IAsn1Container container )
1409                    {
1410    
1411                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1412                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1413    
1414                        // Now, we can allocate the SearchResultDone Object
1415                        ldapMessage.setProtocolOP( new SearchResultDoneCodec() );
1416    
1417                        log.debug( "Search Result Done found" );
1418                    }
1419                } );
1420    
1421            // --------------------------------------------------------------------------------------------
1422            // SearchResultDone Message.
1423            // --------------------------------------------------------------------------------------------
1424            // LdapMessage ::= ... SearchResultDone ...
1425            // SearchResultDone ::= [APPLICATION 5] LDAPResult
1426            //
1427            // LDAPResult ::= SEQUENCE {
1428            //     resultCode    ENUMERATED {
1429            //         ...
1430            // 
1431            // Stores the result code
1432            super.transitions[LdapStatesEnum.SEARCH_RESULT_DONE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
1433                LdapStatesEnum.SEARCH_RESULT_DONE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
1434                new ResultCodeAction() );
1435    
1436            // --------------------------------------------------------------------------------------------
1437            // Transition from Message ID to ModifyRequest Message
1438            // --------------------------------------------------------------------------------------------
1439            // LdapMessage ::= ... ModifyRequest ...
1440            // ModifyRequest ::= [APPLICATION 6] SEQUENCE { ...
1441            //
1442            // Creates the Modify Request object
1443            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.MODIFY_REQUEST_TAG] = new GrammarTransition(
1444                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.MODIFY_REQUEST_STATE, LdapConstants.MODIFY_REQUEST_TAG,
1445                new GrammarAction( "Init ModifyRequest" )
1446                {
1447                    public void action( IAsn1Container container )
1448                    {
1449    
1450                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1451                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1452    
1453                        // Now, we can allocate the ModifyRequest Object
1454                        // And we associate it to the ldapMessage Object
1455                        ldapMessage.setProtocolOP( new ModifyRequestCodec() );
1456                    }
1457                } );
1458    
1459            // --------------------------------------------------------------------------------------------
1460            // Transition from ModifyRequest Message to Object
1461            // --------------------------------------------------------------------------------------------
1462            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1463            //     object    LDAPDN,
1464            //     ...
1465            //
1466            // Stores the object DN
1467            super.transitions[LdapStatesEnum.MODIFY_REQUEST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1468                LdapStatesEnum.MODIFY_REQUEST_STATE, LdapStatesEnum.OBJECT_STATE, UniversalTag.OCTET_STRING_TAG,
1469                new GrammarAction( "Store Modify request object Value" )
1470                {
1471                    public void action( IAsn1Container container ) throws DecoderException
1472                    {
1473    
1474                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1475                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1476                        ModifyRequestCodec modifyRequest = ldapMessage.getModifyRequest();
1477    
1478                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1479    
1480                        LdapDN object = LdapDN.EMPTY_LDAPDN;
1481    
1482                        // Store the value.
1483                        if ( tlv.getLength() == 0 )
1484                        {
1485                            modifyRequest.setObject( object );
1486                        }
1487                        else
1488                        {
1489                            byte[] dnBytes = tlv.getValue().getData();
1490    
1491                            try
1492                            {
1493                                object = new LdapDN( dnBytes );
1494                            }
1495                            catch ( InvalidNameException ine )
1496                            {
1497                                String msg = "Invalid DN given : " + StringTools.utf8ToString( dnBytes ) + " ("
1498                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
1499                                log.error( "{} : {}", msg, ine.getMessage() );
1500    
1501                                ModifyResponseImpl response = new ModifyResponseImpl( ldapMessage.getMessageId() );
1502                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
1503                                    LdapDN.EMPTY_LDAPDN, ine );
1504                            }
1505    
1506                            modifyRequest.setObject( object );
1507                        }
1508    
1509                        if ( IS_DEBUG )
1510                        {
1511                            log.debug( "Modification of DN {}", modifyRequest.getObject() );
1512                        }
1513                    }
1514                } );
1515    
1516            // --------------------------------------------------------------------------------------------
1517            // Transition from Object to modifications
1518            // --------------------------------------------------------------------------------------------
1519            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1520            //     ...
1521            //     modification *SEQUENCE OF* SEQUENCE {
1522            //     ...
1523            //
1524            // Initialize the modifications list
1525            super.transitions[LdapStatesEnum.OBJECT_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1526                LdapStatesEnum.OBJECT_STATE, LdapStatesEnum.MODIFICATIONS_STATE, UniversalTag.SEQUENCE_TAG,
1527                new GrammarAction( "Init modifications array list" )
1528                {
1529                    public void action( IAsn1Container container )
1530                    {
1531    
1532                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1533                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1534                        ModifyRequestCodec modifyRequest = ldapMessage.getModifyRequest();
1535    
1536                        modifyRequest.initModifications();
1537                    }
1538                } );
1539    
1540            // --------------------------------------------------------------------------------------------
1541            // Transition from modifications to modification sequence
1542            // --------------------------------------------------------------------------------------------
1543            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1544            //     ...
1545            //     modification SEQUENCE OF *SEQUENCE* {
1546            //     ...
1547            //
1548            // Nothing to do
1549            super.transitions[LdapStatesEnum.MODIFICATIONS_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1550                LdapStatesEnum.MODIFICATIONS_STATE, LdapStatesEnum.MODIFICATIONS_SEQ_STATE, UniversalTag.SEQUENCE_TAG, null );
1551    
1552            // --------------------------------------------------------------------------------------------
1553            // Transition from modification sequence to operation
1554            // --------------------------------------------------------------------------------------------
1555            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1556            //     ...
1557            //     modification SEQUENCE OF SEQUENCE {
1558            //         operation  ENUMERATED {
1559            //             ...
1560            //
1561            // Store operation type
1562            super.transitions[LdapStatesEnum.MODIFICATIONS_SEQ_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
1563                LdapStatesEnum.MODIFICATIONS_SEQ_STATE, LdapStatesEnum.OPERATION_STATE, UniversalTag.ENUMERATED_TAG,
1564                new GrammarAction( "Store operation type" )
1565                {
1566                    public void action( IAsn1Container container ) throws DecoderException
1567                    {
1568    
1569                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1570                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1571                        ModifyRequestCodec modifyRequest = ldapMessage.getModifyRequest();
1572    
1573                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1574    
1575                        // Decode the operation type
1576                        int operation = 0;
1577    
1578                        try
1579                        {
1580                            operation = IntegerDecoder.parse( tlv.getValue(), 0, 2 );
1581                        }
1582                        catch ( IntegerDecoderException ide )
1583                        {
1584                            String msg = "Invalid operation ( " + StringTools.dumpBytes( tlv.getValue().getData() )
1585                                + "), it should be 0, 1 or 2";
1586                            log.error( msg );
1587    
1588                            // This will generate a PROTOCOL_ERROR
1589                            throw new DecoderException( msg );
1590                        }
1591    
1592                        // Store the current operation.
1593                        modifyRequest.setCurrentOperation( operation );
1594    
1595                        if ( IS_DEBUG )
1596                        {
1597                            switch ( operation )
1598                            {
1599                                case LdapConstants.OPERATION_ADD:
1600                                    log.debug( "Modification operation : ADD" );
1601                                    break;
1602    
1603                                case LdapConstants.OPERATION_DELETE:
1604                                    log.debug( "Modification operation : DELETE" );
1605                                    break;
1606    
1607                                case LdapConstants.OPERATION_REPLACE:
1608                                    log.debug( "Modification operation : REPLACE" );
1609                                    break;
1610                            }
1611                        }
1612    
1613                    }
1614                } );
1615    
1616            // --------------------------------------------------------------------------------------------
1617            // Transition from operation to modification
1618            // --------------------------------------------------------------------------------------------
1619            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1620            //     ...
1621            //     modification SEQUENCE OF SEQUENCE {
1622            //             ...
1623            //         modification   AttributeTypeAndValues }
1624            //
1625            // AttributeTypeAndValues ::= SEQUENCE {
1626            //     ...
1627            //
1628            // Nothing to do
1629            super.transitions[LdapStatesEnum.OPERATION_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1630                LdapStatesEnum.OPERATION_STATE, LdapStatesEnum.MODIFICATION_STATE, UniversalTag.SEQUENCE_TAG, null );
1631    
1632            // --------------------------------------------------------------------------------------------
1633            // Transition from modification to TypeMod
1634            // --------------------------------------------------------------------------------------------
1635            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1636            //     ...
1637            //     modification SEQUENCE OF SEQUENCE {
1638            //             ...
1639            //         modification   AttributeTypeAndValues }
1640            //
1641            // AttributeTypeAndValues ::= SEQUENCE {
1642            //     type AttributeDescription,
1643            //     ...
1644            //
1645            // Stores the type
1646            super.transitions[LdapStatesEnum.MODIFICATION_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1647                LdapStatesEnum.MODIFICATION_STATE, LdapStatesEnum.TYPE_MOD_STATE, UniversalTag.OCTET_STRING_TAG,
1648                new GrammarAction( "Store type" )
1649                {
1650                    public void action( IAsn1Container container ) throws DecoderException
1651                    {
1652    
1653                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1654                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1655                        ModifyRequestCodec modifyRequest = ldapMessage.getModifyRequest();
1656    
1657                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1658    
1659                        // Store the value. It can't be null
1660                        String type = null;
1661    
1662                        if ( tlv.getLength() == 0 )
1663                        {
1664                            String msg = "The type can't be null";
1665                            log.error( msg );
1666    
1667                            ModifyResponseImpl response = new ModifyResponseImpl( ldapMessage.getMessageId() );
1668                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
1669                                modifyRequest.getObject(), null );
1670                        }
1671                        else
1672                        {
1673                            type = StringTools.getType( tlv.getValue().getData() );
1674                            modifyRequest.addAttributeTypeAndValues( type );
1675                        }
1676    
1677                        if ( IS_DEBUG )
1678                        {
1679                            log.debug( "Modifying type : {}", type );
1680                        }
1681                    }
1682                } );
1683    
1684            // --------------------------------------------------------------------------------------------
1685            // Transition from TypeMod to vals
1686            // --------------------------------------------------------------------------------------------
1687            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1688            //     ...
1689            //     modification SEQUENCE OF SEQUENCE {
1690            //             ...
1691            //         modification   AttributeTypeAndValues }
1692            //
1693            // AttributeTypeAndValues ::= SEQUENCE {
1694            //     ...
1695            //     vals SET OF AttributeValue }
1696            //
1697            // Initialize the list of values
1698            super.transitions[LdapStatesEnum.TYPE_MOD_STATE][UniversalTag.SET_TAG] = new GrammarTransition(
1699                LdapStatesEnum.TYPE_MOD_STATE, LdapStatesEnum.VALS_STATE, UniversalTag.SET_TAG, new GrammarAction(
1700                    "Init Attribute vals" )
1701                {
1702                    public void action( IAsn1Container container )
1703                    {
1704    
1705                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1706    
1707                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1708    
1709                        // If the length is null, we store an empty value
1710                        if ( tlv.getLength() == 0 )
1711                        {
1712                            log.debug( "No vals for this attribute" );
1713                        }
1714    
1715                        // We can have an END transition
1716                        ldapMessageContainer.grammarEndAllowed( true );
1717    
1718                        log.debug( "Some vals are to be decoded" );
1719                    }
1720                } );
1721    
1722            // --------------------------------------------------------------------------------------------
1723            // Transition from vals to Attribute Value
1724            // --------------------------------------------------------------------------------------------
1725            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1726            //     ...
1727            //     modification SEQUENCE OF SEQUENCE {
1728            //             ...
1729            //         modification   AttributeTypeAndValues }
1730            //
1731            // AttributeTypeAndValues ::= SEQUENCE {
1732            //     ...
1733            //     vals SET OF AttributeValue }
1734            //
1735            // AttributeValue ::= OCTET STRING
1736            //
1737            // Stores a value
1738            super.transitions[LdapStatesEnum.VALS_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1739                LdapStatesEnum.VALS_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_STATE, UniversalTag.OCTET_STRING_TAG,
1740                new ModifyAttributeValueAction() );
1741    
1742            // --------------------------------------------------------------------------------------------
1743            // Transition from vals to ModificationsSeq
1744            // --------------------------------------------------------------------------------------------
1745            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1746            //     ...
1747            //     modification SEQUENCE OF *SEQUENCE* {
1748            //             ...
1749            //         modification   AttributeTypeAndValues }
1750            //
1751            // AttributeTypeAndValues ::= SEQUENCE {
1752            //     ...
1753            //     vals SET OF AttributeValue }
1754            //
1755            // AttributeValue ::= OCTET STRING
1756            //
1757            // Nothing to do
1758            super.transitions[LdapStatesEnum.VALS_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1759                LdapStatesEnum.VALS_STATE, LdapStatesEnum.MODIFICATIONS_SEQ_STATE, UniversalTag.SEQUENCE_TAG, null );
1760    
1761            // --------------------------------------------------------------------------------------------
1762            // Transition from vals to Controls
1763            // --------------------------------------------------------------------------------------------
1764            //     modifyRequest ModifyRequest,
1765            //     ... },
1766            // controls   [0] Controls OPTIONAL }
1767            //
1768            // Nothing to do
1769            super.transitions[LdapStatesEnum.VALS_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1770                LdapStatesEnum.VALS_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1771                new ControlsInitAction() );
1772    
1773            // --------------------------------------------------------------------------------------------
1774            // Transition from Attribute Value to Attribute Value
1775            // --------------------------------------------------------------------------------------------
1776            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1777            //     ...
1778            //     modification SEQUENCE OF SEQUENCE {
1779            //             ...
1780            //         modification   AttributeTypeAndValues }
1781            //
1782            // AttributeTypeAndValues ::= SEQUENCE {
1783            //     ...
1784            //     vals SET OF AttributeValue }
1785            //
1786            // AttributeValue ::= OCTET STRING
1787            //
1788            // Stores a value
1789            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1790                LdapStatesEnum.ATTRIBUTE_VALUE_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_STATE, UniversalTag.OCTET_STRING_TAG,
1791                new ModifyAttributeValueAction() );
1792    
1793            // --------------------------------------------------------------------------------------------
1794            // Transition from Attribute Value to ModificationsSeq
1795            // --------------------------------------------------------------------------------------------
1796            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1797            //     ...
1798            //     modification SEQUENCE OF *SEQUENCE* {
1799            //             ...
1800            //         modification   AttributeTypeAndValues }
1801            //
1802            // AttributeTypeAndValues ::= SEQUENCE {
1803            //     ...
1804            //     vals SET OF AttributeValue }
1805            //
1806            // AttributeValue ::= OCTET STRING
1807            //
1808            // Nothing to do
1809            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1810                LdapStatesEnum.ATTRIBUTE_VALUE_STATE, LdapStatesEnum.MODIFICATIONS_SEQ_STATE, UniversalTag.SEQUENCE_TAG,
1811                null );
1812    
1813            // --------------------------------------------------------------------------------------------
1814            // Transition from Attribute Value to Controls
1815            // --------------------------------------------------------------------------------------------
1816            //     modifyRequest ModifyRequest,
1817            //     ... },
1818            // controls   [0] Controls OPTIONAL }
1819            //
1820            // Nothing to do
1821            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1822                LdapStatesEnum.ATTRIBUTE_VALUE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1823                new ControlsInitAction() );
1824    
1825            // --------------------------------------------------------------------------------------------
1826            // ModifyResponse Message.
1827            // --------------------------------------------------------------------------------------------
1828            // LdapMessage ::= ... ModifyResponse ...
1829            // ModifyResponse ::= [APPLICATION 7] SEQUENCE { ...
1830            // We have to switch to the ModifyResponse grammar
1831            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.MODIFY_RESPONSE_TAG] = new GrammarTransition(
1832                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.MODIFY_RESPONSE_STATE, LdapConstants.MODIFY_RESPONSE_TAG,
1833                new GrammarAction( "Init ModifyResponse" )
1834                {
1835                    public void action( IAsn1Container container )
1836                    {
1837    
1838                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1839                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1840    
1841                        // We associate it to the ldapMessage Object
1842                        ldapMessage.setProtocolOP( new ModifyResponseCodec() );
1843    
1844                        log.debug( "Modify response" );
1845                    }
1846                } );
1847    
1848            // --------------------------------------------------------------------------------------------
1849            // ModifyResponse Message.
1850            // --------------------------------------------------------------------------------------------
1851            // LdapMessage ::= ... ModifyResponse ...
1852            // ModifyResponse ::= [APPLICATION 7] LDAPResult
1853            //
1854            // LDAPResult ::= SEQUENCE {
1855            //     resultCode    ENUMERATED {
1856            //         ...
1857            // 
1858            // Stores the result code
1859            super.transitions[LdapStatesEnum.MODIFY_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
1860                LdapStatesEnum.MODIFY_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
1861                new ResultCodeAction() );
1862    
1863            // --------------------------------------------------------------------------------------------
1864            // AddRequest Message.
1865            // --------------------------------------------------------------------------------------------
1866            // LdapMessage ::= ... AddRequest ...
1867            // AddRequest ::= [APPLICATION 8] SEQUENCE { ...
1868            //
1869            // Initialize the AddRequest object
1870            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.ADD_REQUEST_TAG] = new GrammarTransition(
1871                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.ADD_REQUEST_STATE, LdapConstants.ADD_REQUEST_TAG,
1872                new GrammarAction( "Init addRequest" )
1873                {
1874                    public void action( IAsn1Container container ) throws DecoderException
1875                    {
1876    
1877                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1878                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1879    
1880                        // We will check that the request is not null
1881                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1882    
1883                        if ( tlv.getLength() == 0 )
1884                        {
1885                            String msg = "The AddRequest must not be null";
1886                            log.error( msg );
1887    
1888                            // Will generate a PROTOCOL_ERROR
1889                            throw new DecoderException( msg );
1890                        }
1891    
1892                        // Now, we can allocate the ModifyRequest Object
1893                        // And we associate it to the ldapMessage Object
1894                        ldapMessage.setProtocolOP( new AddRequestCodec() );
1895                    }
1896                } );
1897    
1898            // --------------------------------------------------------------------------------------------
1899            // Transition from Add Request to Entry
1900            // --------------------------------------------------------------------------------------------
1901            // AddRequest ::= [APPLICATION 8] SEQUENCE {
1902            //     entry           LDAPDN,
1903            //     ...
1904            //
1905            // Stores the DN
1906            super.transitions[LdapStatesEnum.ADD_REQUEST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1907                LdapStatesEnum.ADD_REQUEST_STATE, LdapStatesEnum.ENTRY_STATE, UniversalTag.OCTET_STRING_TAG,
1908                new GrammarAction( "Store add request object Value" )
1909                {
1910                    public void action( IAsn1Container container ) throws DecoderException
1911                    {
1912    
1913                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1914                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
1915                        AddRequestCodec addRequest = ldapMessage.getAddRequest();
1916    
1917                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1918    
1919                        // Store the entry. It can't be null
1920                        if ( tlv.getLength() == 0 )
1921                        {
1922                            String msg = "Empty entry DN given";
1923                            log.error( msg );
1924    
1925                            AddResponseImpl response = new AddResponseImpl( ldapMessage.getMessageId() );
1926    
1927                            // I guess that trying to add an entry which DN is empty is a naming violation...
1928                            // Not 100% sure though ...
1929                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.NAMING_VIOLATION,
1930                                LdapDN.EMPTY_LDAPDN, null );
1931                        }
1932                        else
1933                        {
1934                            LdapDN entryDn = null;
1935                            byte[] dnBytes = tlv.getValue().getData();
1936    
1937                            try
1938                            {
1939                                entryDn = new LdapDN( dnBytes );
1940                            }
1941                            catch ( InvalidNameException ine )
1942                            {
1943                                String msg = "Invalid DN given : " + StringTools.utf8ToString( dnBytes ) + " ("
1944                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
1945                                log.error( "{} : {}", msg, ine.getMessage() );
1946    
1947                                AddResponseImpl response = new AddResponseImpl( ldapMessage.getMessageId() );
1948                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
1949                                    LdapDN.EMPTY_LDAPDN, ine );
1950                            }
1951    
1952                            addRequest.setEntryDn( entryDn );
1953                        }
1954    
1955                        log.debug( "Adding an entry with DN : {}", addRequest.getEntry() );
1956                    }
1957                } );
1958    
1959            // --------------------------------------------------------------------------------------------
1960            // Transition from Entry to Attributes
1961            // --------------------------------------------------------------------------------------------
1962            // AddRequest ::= [APPLICATION 8] SEQUENCE {
1963            //     ...
1964            //    attributes AttributeList }
1965            //
1966            // AttributeList ::= SEQUENCE OF ... 
1967            //
1968            // Initialize the attribute list
1969            super.transitions[LdapStatesEnum.ENTRY_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1970                LdapStatesEnum.ENTRY_STATE, LdapStatesEnum.ATTRIBUTES_STATE, UniversalTag.SEQUENCE_TAG, null );
1971    
1972            // --------------------------------------------------------------------------------------------
1973            // Transition from Attributes to Attribute
1974            // --------------------------------------------------------------------------------------------
1975            // AttributeList ::= SEQUENCE OF SEQUENCE {
1976            //
1977            // We don't do anything in this transition. The attribute will be created when we met the type
1978            super.transitions[LdapStatesEnum.ATTRIBUTES_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1979                LdapStatesEnum.ATTRIBUTES_STATE, LdapStatesEnum.ATTRIBUTE_STATE, UniversalTag.SEQUENCE_TAG, null );
1980    
1981            // --------------------------------------------------------------------------------------------
1982            // Transition from Attribute to type
1983            // --------------------------------------------------------------------------------------------
1984            // AttributeList ::= SEQUENCE OF SEQUENCE {
1985            //     type    AttributeDescription,
1986            //     ...
1987            //
1988            // AttributeDescription LDAPString
1989            //
1990            // We store the type in the current attribute
1991            super.transitions[LdapStatesEnum.ATTRIBUTE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1992                LdapStatesEnum.ATTRIBUTE_STATE, LdapStatesEnum.TYPE_STATE, UniversalTag.OCTET_STRING_TAG,
1993                new GrammarAction( "Store attribute type" )
1994                {
1995                    public void action( IAsn1Container container ) throws DecoderException
1996                    {
1997    
1998                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1999                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2000                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2001    
2002                        AddRequestCodec addRequest = ldapMessage.getAddRequest();
2003    
2004                        // Store the type. It can't be null.
2005    
2006                        if ( tlv.getLength() == 0 )
2007                        {
2008                            String msg = "Null or empty types are not allowed";
2009                            log.error( msg );
2010    
2011                            AddResponseImpl response = new AddResponseImpl( ldapMessage.getMessageId() );
2012    
2013                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
2014                                addRequest.getEntry().getDn(), null );
2015                        }
2016    
2017                        String type = StringTools.getType( tlv.getValue().getData() );
2018    
2019                        try
2020                        {
2021                            addRequest.addAttributeType( type );
2022                        }
2023                        catch ( NamingException ne )
2024                        {
2025                            String msg = "Error while injecting the AttributeType";
2026                            log.error( msg );
2027    
2028                            AddResponseImpl response = new AddResponseImpl( ldapMessage.getMessageId() );
2029                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
2030                                addRequest.getEntry().getDn(), ne );
2031                        }
2032    
2033                        if ( IS_DEBUG )
2034                        {
2035                            log.debug( "Adding type {}", type );
2036                        }
2037                    }
2038                } );
2039    
2040            // --------------------------------------------------------------------------------------------
2041            // Transition from type to vals
2042            // --------------------------------------------------------------------------------------------
2043            // AttributeList ::= SEQUENCE OF SEQUENCE {
2044            //     ...
2045            //     vals SET OF AttributeValue }
2046            //
2047            // Nothing to do here.
2048            super.transitions[LdapStatesEnum.TYPE_STATE][UniversalTag.SET_TAG] = new GrammarTransition(
2049                LdapStatesEnum.TYPE_STATE, LdapStatesEnum.VALUES_STATE, UniversalTag.SET_TAG, null );
2050    
2051            // --------------------------------------------------------------------------------------------
2052            // Transition from vals to Value
2053            // --------------------------------------------------------------------------------------------
2054            // AttributeList ::= SEQUENCE OF SEQUENCE {
2055            //     ...
2056            //     vals SET OF AttributeValue }
2057            //
2058            // AttributeValue OCTET STRING
2059            //
2060            // Store the value into the current attribute
2061            super.transitions[LdapStatesEnum.VALUES_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2062                LdapStatesEnum.VALUES_STATE, LdapStatesEnum.VALUE_STATE, UniversalTag.OCTET_STRING_TAG, new ValueAction() );
2063    
2064            // --------------------------------------------------------------------------------------------
2065            // Transition from Value to Value
2066            // --------------------------------------------------------------------------------------------
2067            // AttributeList ::= SEQUENCE OF SEQUENCE {
2068            //     ...
2069            //     vals SET OF AttributeValue }
2070            //
2071            // AttributeValue OCTET STRING
2072            //
2073            // Store the value into the current attribute
2074            super.transitions[LdapStatesEnum.VALUE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2075                LdapStatesEnum.VALUE_STATE, LdapStatesEnum.VALUE_STATE, UniversalTag.OCTET_STRING_TAG, new ValueAction() );
2076    
2077            // --------------------------------------------------------------------------------------------
2078            // Transition from Value to Attribute
2079            // --------------------------------------------------------------------------------------------
2080            // AttributeList ::= SEQUENCE OF SEQUENCE {
2081            //
2082            // Nothing to do here.
2083            super.transitions[LdapStatesEnum.VALUE_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
2084                LdapStatesEnum.VALUE_STATE, LdapStatesEnum.ATTRIBUTE_STATE, UniversalTag.SEQUENCE_TAG, null );
2085    
2086            // --------------------------------------------------------------------------------------------
2087            // Transition from Value to Controls
2088            // --------------------------------------------------------------------------------------------
2089            // AttributeList ::= SEQUENCE OF SEQUENCE {
2090            //
2091            // Initialize the controls
2092            super.transitions[LdapStatesEnum.VALUE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2093                LdapStatesEnum.VALUE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2094                new ControlsInitAction() );
2095    
2096            // --------------------------------------------------------------------------------------------
2097            // AddResponse Message.
2098            // --------------------------------------------------------------------------------------------
2099            // LdapMessage ::= ... AddResponse ...
2100            // AddResponse ::= [APPLICATION 9] LDAPResult
2101            // 
2102            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.ADD_RESPONSE_TAG] = new GrammarTransition(
2103                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.ADD_RESPONSE_STATE, LdapConstants.ADD_RESPONSE_TAG,
2104                new GrammarAction( "Init AddResponse" )
2105                {
2106                    public void action( IAsn1Container container ) throws DecoderException
2107                    {
2108    
2109                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2110                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2111    
2112                        // We will check that the request is not null
2113                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2114    
2115                        int expectedLength = tlv.getLength();
2116    
2117                        if ( expectedLength == 0 )
2118                        {
2119                            String msg = "The AddResponse must not be null";
2120                            log.error( msg );
2121                            throw new DecoderException( msg );
2122                        }
2123    
2124                        // Now, we can allocate the AddRequest Object
2125                        AddResponseCodec addResponse = new AddResponseCodec();
2126    
2127                        // As this is a new Constructed object, we have to init its
2128                        // length
2129                        //addResponse.setExpectedLength( expectedLength );
2130                        //addResponse.setCurrentLength( 0 );
2131                        //addResponse.setParent( ldapMessage );
2132    
2133                        // And we associate it to the ldapMessage Object
2134                        ldapMessage.setProtocolOP( addResponse );
2135    
2136                        log.debug( "Add Response" );
2137                    }
2138                } );
2139    
2140            // --------------------------------------------------------------------------------------------
2141            // AddResponse Message.
2142            // --------------------------------------------------------------------------------------------
2143            // LdapMessage ::= ... AddResponse ...
2144            // AddResponse ::= [APPLICATION 9] LDAPResult
2145            //
2146            // LDAPResult ::= SEQUENCE {
2147            //     resultCode    ENUMERATED {
2148            //         ...
2149            // 
2150            // Stores the result code
2151            super.transitions[LdapStatesEnum.ADD_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
2152                LdapStatesEnum.ADD_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
2153                new ResultCodeAction() );
2154    
2155            // --------------------------------------------------------------------------------------------
2156            // DelResponse Message.
2157            // --------------------------------------------------------------------------------------------
2158            // LdapMessage ::= ... DelResponse ...
2159            // DelResponse ::= [APPLICATION 11] LDAPResult
2160            // We have to switch to the DelResponse grammar
2161            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.DEL_RESPONSE_TAG] = new GrammarTransition(
2162                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.DEL_RESPONSE_STATE, LdapConstants.DEL_RESPONSE_TAG,
2163                new GrammarAction( "Init DelResponse" )
2164                {
2165                    public void action( IAsn1Container container )
2166                    {
2167    
2168                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2169                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2170    
2171                        // Now, we can allocate the DelResponse Object
2172    
2173                        // And we associate it to the ldapMessage Object
2174                        ldapMessage.setProtocolOP( new DelResponseCodec() );
2175    
2176                        log.debug( "Del response " );
2177                    }
2178                } );
2179    
2180            // --------------------------------------------------------------------------------------------
2181            // DelResponse Message.
2182            // --------------------------------------------------------------------------------------------
2183            // LdapMessage ::= ... DelResponse ...
2184            // DelResponse ::= [APPLICATION 11] LDAPResult
2185            //
2186            // LDAPResult ::= SEQUENCE {
2187            //     resultCode    ENUMERATED {
2188            //         ...
2189            // 
2190            // Stores the result code
2191            super.transitions[LdapStatesEnum.DEL_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
2192                LdapStatesEnum.DEL_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
2193                new ResultCodeAction() );
2194    
2195            // --------------------------------------------------------------------------------------------
2196            // Transition from MessageID to ModifydDNRequest Message.
2197            // --------------------------------------------------------------------------------------------
2198            // LdapMessage ::= ... ModifyDNRequest ...
2199            // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { ...
2200            //
2201            // Create the ModifyDNRequest Object
2202            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.MODIFY_DN_REQUEST_TAG] = new GrammarTransition(
2203                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.MODIFY_DN_REQUEST_STATE,
2204                LdapConstants.MODIFY_DN_REQUEST_TAG, new GrammarAction( "Init Modify DN Request" )
2205                {
2206                    public void action( IAsn1Container container )
2207                    {
2208    
2209                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2210                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2211    
2212                        // Now, we can allocate the ModifyDNRequest Object
2213                        // And we associate it to the ldapMessage Object
2214                        ldapMessage.setProtocolOP( new ModifyDNRequestCodec() );
2215    
2216                    }
2217                } );
2218    
2219            // --------------------------------------------------------------------------------------------
2220            // Transition from ModifydDNRequest Message to EntryModDN
2221            // --------------------------------------------------------------------------------------------
2222            // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { ...
2223            //     entry LDAPDN,
2224            //     ...
2225            //
2226            // Stores the entry DN
2227            super.transitions[LdapStatesEnum.MODIFY_DN_REQUEST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2228                LdapStatesEnum.MODIFY_DN_REQUEST_STATE, LdapStatesEnum.ENTRY_MOD_DN_STATE, UniversalTag.OCTET_STRING_TAG,
2229                new GrammarAction( "Store entry" )
2230                {
2231                    public void action( IAsn1Container container ) throws DecoderException
2232                    {
2233    
2234                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2235                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2236    
2237                        ModifyDNRequestCodec modifyDNRequest = ldapMessage.getModifyDNRequest();
2238    
2239                        // Get the Value and store it in the modifyDNRequest
2240                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2241    
2242                        // We have to handle the special case of a 0 length matched
2243                        // DN
2244                        LdapDN entry = null;
2245    
2246                        if ( tlv.getLength() == 0 )
2247                        {
2248                            // This will generate a PROTOCOL_ERROR
2249                            throw new DecoderException( "The entry must nut be null" );
2250                        }
2251                        else
2252                        {
2253                            byte[] dnBytes = tlv.getValue().getData();
2254    
2255                            try
2256                            {
2257                                entry = new LdapDN( dnBytes );
2258                            }
2259                            catch ( InvalidNameException ine )
2260                            {
2261                                String msg = "Invalid DN given : " + StringTools.utf8ToString( dnBytes ) + " ("
2262                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
2263                                log.error( "{} : {}", msg, ine.getMessage() );
2264    
2265                                ModifyDnResponseImpl response = new ModifyDnResponseImpl( ldapMessage.getMessageId() );
2266                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
2267                                    LdapDN.EMPTY_LDAPDN, ine );
2268                            }
2269    
2270                            modifyDNRequest.setEntry( entry );
2271                        }
2272    
2273                        if ( IS_DEBUG )
2274                        {
2275                            log.debug( "Modifying DN {}", entry );
2276                        }
2277    
2278                        return;
2279                    }
2280                } );
2281    
2282            // --------------------------------------------------------------------------------------------
2283            // Transition from EntryModDN to NewRDN
2284            // --------------------------------------------------------------------------------------------
2285            // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { ...
2286            //     ...
2287            //     newrdn  RelativeRDN,
2288            //     ...
2289            //
2290            // RelativeRDN :: LDAPString
2291            //
2292            // Stores the new RDN
2293            super.transitions[LdapStatesEnum.ENTRY_MOD_DN_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2294                LdapStatesEnum.ENTRY_MOD_DN_STATE, LdapStatesEnum.NEW_RDN_STATE, UniversalTag.OCTET_STRING_TAG,
2295                new GrammarAction( "Store new RDN" )
2296                {
2297                    public void action( IAsn1Container container ) throws DecoderException
2298                    {
2299    
2300                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2301                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2302    
2303                        ModifyDNRequestCodec modifyDNRequest = ldapMessage.getModifyDNRequest();
2304    
2305                        // Get the Value and store it in the modifyDNRequest
2306                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2307    
2308                        // We have to handle the special case of a 0 length matched
2309                        // newDN
2310                        Rdn newRdn = null;
2311    
2312                        if ( tlv.getLength() == 0 )
2313                        {
2314                            String msg = "The newrdn must not be null";
2315                            log.error( msg );
2316    
2317                            ModifyDnResponseImpl response = new ModifyDnResponseImpl( ldapMessage.getMessageId() );
2318                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
2319                                modifyDNRequest.getEntry(), null );
2320                        }
2321                        else
2322                        {
2323                            byte[] dnBytes = tlv.getValue().getData();
2324    
2325                            try
2326                            {
2327                                LdapDN dn = new LdapDN( dnBytes );
2328                                newRdn = dn.getRdn( 0 );
2329                            }
2330                            catch ( InvalidNameException ine )
2331                            {
2332                                String msg = "Invalid new RDN given : " + StringTools.utf8ToString( dnBytes ) + " ("
2333                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
2334                                log.error( "{} : {}", msg, ine.getMessage() );
2335    
2336                                ModifyDnResponseImpl response = new ModifyDnResponseImpl( ldapMessage.getMessageId() );
2337                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
2338                                    modifyDNRequest.getEntry(), ine );
2339                            }
2340    
2341                            modifyDNRequest.setNewRDN( newRdn );
2342                        }
2343    
2344                        if ( IS_DEBUG )
2345                        {
2346                            log.debug( "Modifying with new RDN {}", newRdn );
2347                        }
2348                    }
2349                } );
2350    
2351            // --------------------------------------------------------------------------------------------
2352            // Transition from NewRDN to DeleteOldRDN
2353            // --------------------------------------------------------------------------------------------
2354            // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { ...
2355            //     ...
2356            //     deleteoldrdn BOOLEAN,
2357            //     ...
2358            //
2359            // Stores the deleteOldRDN flag
2360            super.transitions[LdapStatesEnum.NEW_RDN_STATE][UniversalTag.BOOLEAN_TAG] = new GrammarTransition(
2361                LdapStatesEnum.NEW_RDN_STATE, LdapStatesEnum.DELETE_OLD_RDN_STATE, UniversalTag.BOOLEAN_TAG,
2362                new GrammarAction( "Store matching dnAttributes Value" )
2363                {
2364                    public void action( IAsn1Container container ) throws DecoderException
2365                    {
2366    
2367                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2368                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2369    
2370                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2371    
2372                        // Store the value.
2373                        ModifyDNRequestCodec modifyDNRequest = ldapMessage.getModifyDNRequest();
2374    
2375                        // We get the value. If it's a 0, it's a FALSE. If it's
2376                        // a FF, it's a TRUE. Any other value should be an error,
2377                        // but we could relax this constraint. So if we have
2378                        // something
2379                        // which is not 0, it will be interpreted as TRUE, but we
2380                        // will generate a warning.
2381                        Value value = tlv.getValue();
2382    
2383                        try
2384                        {
2385                            modifyDNRequest.setDeleteOldRDN( BooleanDecoder.parse( value ) );
2386                        }
2387                        catch ( BooleanDecoderException bde )
2388                        {
2389                            log.error( "The oldRDN flag {} is invalid : {}. It should be 0 or 255", StringTools
2390                                .dumpBytes( value.getData() ), bde.getMessage() );
2391    
2392                            // This will generate a PROTOCOL_ERROR                        
2393                            throw new DecoderException( bde.getMessage() );
2394                        }
2395    
2396                        // We can have an END transition
2397                        ldapMessageContainer.grammarEndAllowed( true );
2398    
2399                        if ( IS_DEBUG )
2400                        {
2401                            if ( modifyDNRequest.isDeleteOldRDN() )
2402                            {
2403                                log.debug( " Old RDN attributes will be deleted" );
2404                            }
2405                            else
2406                            {
2407                                log.debug( " Old RDN attributes will be retained" );
2408                            }
2409                        }
2410                    }
2411                } );
2412    
2413            // --------------------------------------------------------------------------------------------
2414            // Transition from DeleteOldRDN to NewSuperior
2415            // --------------------------------------------------------------------------------------------
2416            // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { ...
2417            //     ...
2418            //     newSuperior [0] LDAPDN OPTIONAL }
2419            //
2420            // Stores the new superior
2421            super.transitions[LdapStatesEnum.DELETE_OLD_RDN_STATE][LdapConstants.MODIFY_DN_REQUEST_NEW_SUPERIOR_TAG] = 
2422                new GrammarTransition(
2423                LdapStatesEnum.DELETE_OLD_RDN_STATE, LdapStatesEnum.NEW_SUPERIOR_STATE,
2424                LdapConstants.MODIFY_DN_REQUEST_NEW_SUPERIOR_TAG, new GrammarAction( "Store new superior" )
2425                {
2426                    public void action( IAsn1Container container ) throws DecoderException
2427                    {
2428    
2429                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2430                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2431    
2432                        ModifyDNRequestCodec modifyDNRequest = ldapMessage.getModifyDNRequest();
2433    
2434                        // Get the Value and store it in the modifyDNRequest
2435                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2436    
2437                        // We have to handle the special case of a 0 length matched
2438                        // DN
2439                        LdapDN newSuperior = LdapDN.EMPTY_LDAPDN;
2440    
2441                        if ( tlv.getLength() == 0 )
2442                        {
2443    
2444                            if ( modifyDNRequest.isDeleteOldRDN() )
2445                            {
2446                                // This will generate a PROTOCOL_ERROR
2447                                throw new DecoderException(
2448                                    "The new superior must nut be null if the flag 'delete old DN' is set to true" );
2449                            }
2450                            else
2451                            {
2452                                log.warn( "The new superior is null, so we will change the entry" );
2453                            }
2454    
2455                            modifyDNRequest.setNewSuperior( newSuperior );
2456                        }
2457                        else
2458                        {
2459                            byte[] dnBytes = tlv.getValue().getData();
2460    
2461                            try
2462                            {
2463                                newSuperior = new LdapDN( dnBytes );
2464                            }
2465                            catch ( InvalidNameException ine )
2466                            {
2467                                String msg = "Invalid new superior DN given : " + StringTools.utf8ToString( dnBytes )
2468                                    + " (" + StringTools.dumpBytes( dnBytes ) + ") is invalid";
2469                                log.error( "{} : {}", msg, ine.getMessage() );
2470    
2471                                ModifyDnResponseImpl response = new ModifyDnResponseImpl( ldapMessage.getMessageId() );
2472                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
2473                                    modifyDNRequest.getEntry(), ine );
2474                            }
2475    
2476                            modifyDNRequest.setNewSuperior( newSuperior );
2477                        }
2478    
2479                        // We can have an END transition
2480                        ldapMessageContainer.grammarEndAllowed( true );
2481    
2482                        if ( IS_DEBUG )
2483                        {
2484                            log.debug( "New superior DN {}", newSuperior );
2485                        }
2486    
2487                        return;
2488                    }
2489                } );
2490    
2491            // --------------------------------------------------------------------------------------------
2492            // Transition from DeleteOldRDN to Controls
2493            // --------------------------------------------------------------------------------------------
2494            //     modifyDNRequest ModifyDNRequest,
2495            //     ... },
2496            // controls   [0] Controls OPTIONAL }
2497            //
2498            // Stores the new superior
2499            super.transitions[LdapStatesEnum.DELETE_OLD_RDN_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2500                LdapStatesEnum.DELETE_OLD_RDN_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2501                new ControlsInitAction() );
2502    
2503            // --------------------------------------------------------------------------------------------
2504            // Transition from DeleteOldRDN to Controls
2505            // --------------------------------------------------------------------------------------------
2506            //     modifyDNRequest ModifyDNRequest,
2507            //     ... },
2508            // controls   [0] Controls OPTIONAL }
2509            //
2510            // Stores the new superior
2511            super.transitions[LdapStatesEnum.NEW_SUPERIOR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2512                LdapStatesEnum.NEW_SUPERIOR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2513                new ControlsInitAction() );
2514    
2515            // --------------------------------------------------------------------------------------------
2516            // Transition from MessageID to ModifyDNResponse Message.
2517            // --------------------------------------------------------------------------------------------
2518            // ModifyDNResponse ::= [APPLICATION 13] SEQUENCE {
2519            //     ...
2520            //
2521            // Creates the ModifyDNResponse
2522            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.MODIFY_DN_RESPONSE_TAG] = new GrammarTransition(
2523                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.MODIFY_DN_RESPONSE_STATE,
2524                LdapConstants.MODIFY_DN_RESPONSE_TAG, new GrammarAction( "Init ModifyDNResponse" )
2525                {
2526                    public void action( IAsn1Container container )
2527                    {
2528    
2529                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2530                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2531    
2532                        // And we associate it to the ldapMessage Object
2533                        ldapMessage.setProtocolOP( new ModifyDNResponseCodec() );
2534    
2535                        log.debug( "Modify DN response " );
2536                    }
2537                } );
2538    
2539            // --------------------------------------------------------------------------------------------
2540            // Transition from ModifyDNResponse Message to Result Code
2541            // --------------------------------------------------------------------------------------------
2542            // LdapMessage ::= ... ModifyDNResponse ...
2543            // ModifyDNResponse ::= [APPLICATION 13] LDAPResult
2544            //
2545            // LDAPResult ::= SEQUENCE {
2546            //     resultCode    ENUMERATED {
2547            //         ...
2548            // 
2549            // Stores the result co        //     modifyDNRequest ModifyDNRequest,
2550            //     ... },
2551            // controls   [0] Controls OPTIONAL }
2552            super.transitions[LdapStatesEnum.MODIFY_DN_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
2553                LdapStatesEnum.MODIFY_DN_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
2554                new ResultCodeAction() );
2555    
2556            // --------------------------------------------------------------------------------------------
2557            // Transition from Message ID to CompareResquest
2558            // --------------------------------------------------------------------------------------------
2559            // LdapMessage ::= ... CompareRequest ...
2560            // 
2561            // CompareRequest ::= [APPLICATION 14] SEQUENCE {
2562            // ...
2563            //
2564            // Initialize the Compare Request object 
2565            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.COMPARE_REQUEST_TAG] = new GrammarTransition(
2566                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.COMPARE_REQUEST_STATE, LdapConstants.COMPARE_REQUEST_TAG,
2567                new GrammarAction( "Init Compare Request" )
2568                {
2569                    public void action( IAsn1Container container )
2570                    {
2571    
2572                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2573                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2574    
2575                        // We can allocate the CompareRequest Object
2576                        ldapMessage.setProtocolOP( new CompareRequestCodec() );
2577                    }
2578                } );
2579    
2580            // --------------------------------------------------------------------------------------------
2581            // Transition from CompareResquest to entryComp
2582            // --------------------------------------------------------------------------------------------
2583            // CompareRequest ::= [APPLICATION 14] SEQUENCE {
2584            //     entry    LDAPDN,
2585            //     ...
2586            //
2587            // Stores the compared DN
2588            super.transitions[LdapStatesEnum.COMPARE_REQUEST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2589                LdapStatesEnum.COMPARE_REQUEST_STATE, LdapStatesEnum.ENTRY_COMP_STATE, UniversalTag.OCTET_STRING_TAG,
2590                new GrammarAction( "Store entry" )
2591                {
2592                    public void action( IAsn1Container container ) throws DecoderException
2593                    {
2594    
2595                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2596                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2597    
2598                        // We can allocate the CompareRequest Object
2599                        CompareRequestCodec compareRequest = ldapMessage.getCompareRequest();
2600    
2601                        // Get the Value and store it in the CompareRequest
2602                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2603                        LdapDN entry = null;
2604    
2605                        // We have to handle the special case of a 0 length matched
2606                        // DN
2607                        if ( tlv.getLength() == 0 )
2608                        {
2609                            // This will generate a PROTOCOL_ERROR
2610                            throw new DecoderException( "The entry must not be null" );
2611                        }
2612                        else
2613                        {
2614                            byte[] dnBytes = tlv.getValue().getData();
2615    
2616                            try
2617                            {
2618                                entry = new LdapDN( dnBytes );
2619                            }
2620                            catch ( InvalidNameException ine )
2621                            {
2622                                String msg = "Invalid DN given : " + StringTools.utf8ToString( dnBytes ) + " ("
2623                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
2624                                log.error( "{} : {}", msg, ine.getMessage() );
2625    
2626                                CompareResponseImpl response = new CompareResponseImpl( ldapMessage.getMessageId() );
2627                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
2628                                    LdapDN.EMPTY_LDAPDN, ine );
2629                            }
2630    
2631                            compareRequest.setEntry( entry );
2632                        }
2633    
2634                        if ( IS_DEBUG )
2635                        {
2636                            log.debug( "Comparing DN {}", entry );
2637                        }
2638                    }
2639                } );
2640    
2641            // --------------------------------------------------------------------------------------------
2642            // Transition from entryComp to ava
2643            // --------------------------------------------------------------------------------------------
2644            // CompareRequest ::= [APPLICATION 14] SEQUENCE {
2645            //     ...
2646            //     ava AttributeValueAssertion }
2647            //
2648            // AttributeValueAssertion ::= SEQUENCE {
2649            // 
2650            // Nothing to do
2651            super.transitions[LdapStatesEnum.ENTRY_COMP_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
2652                LdapStatesEnum.ENTRY_COMP_STATE, LdapStatesEnum.AVA_STATE, UniversalTag.SEQUENCE_TAG, null );
2653    
2654            // --------------------------------------------------------------------------------------------
2655            // Transition from ava to AttributeDesc
2656            // --------------------------------------------------------------------------------------------
2657            // AttributeValueAssertion ::= SEQUENCE {
2658            //     attributeDesc AttributeDescription,
2659            //     ...
2660            //
2661            // AttributeDescription LDAPString
2662            // 
2663            // Stores the attribute description
2664            super.transitions[LdapStatesEnum.AVA_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2665                LdapStatesEnum.AVA_STATE, LdapStatesEnum.ATTRIBUTE_DESC_STATE, UniversalTag.OCTET_STRING_TAG,
2666                new GrammarAction( "Store attribute desc" )
2667                {
2668                    public void action( IAsn1Container container ) throws DecoderException
2669                    {
2670    
2671                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2672                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2673    
2674                        // Get the CompareRequest Object
2675                        CompareRequestCodec compareRequest = ldapMessage.getCompareRequest();
2676    
2677                        // Get the Value and store it in the CompareRequest
2678                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2679    
2680                        // We have to handle the special case of a 0 length matched
2681                        // DN
2682                        if ( tlv.getLength() == 0 )
2683                        {
2684                            String msg = "The attribute description must not be null";
2685                            log.error( msg );
2686                            CompareResponseImpl response = new CompareResponseImpl( ldapMessage.getMessageId() );
2687    
2688                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
2689                                compareRequest.getEntry(), null );
2690                        }
2691    
2692                        String type = StringTools.getType( tlv.getValue().getData() );
2693                        compareRequest.setAttributeDesc( type );
2694    
2695                        if ( IS_DEBUG )
2696                        {
2697                            log.debug( "Comparing attribute description {}", compareRequest.getAttributeDesc() );
2698                        }
2699                    }
2700                } );
2701    
2702            // --------------------------------------------------------------------------------------------
2703            // Transition from AttributeDesc to Assertion Value
2704            // --------------------------------------------------------------------------------------------
2705            // AttributeValueAssertion ::= SEQUENCE {
2706            //     ...
2707            //     assertionValue AssertionValue }
2708            //
2709            // AssertionValue OCTET STRING
2710            // 
2711            // Stores the attribute value
2712            super.transitions[LdapStatesEnum.ATTRIBUTE_DESC_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2713                LdapStatesEnum.ATTRIBUTE_DESC_STATE, LdapStatesEnum.ASSERTION_VALUE_STATE, UniversalTag.OCTET_STRING_TAG,
2714                new GrammarAction( "Store assertion value" )
2715                {
2716                    public void action( IAsn1Container container )
2717                    {
2718    
2719                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2720                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2721    
2722                        // Get the CompareRequest Object
2723                        CompareRequestCodec compareRequest = ldapMessage.getCompareRequest();
2724    
2725                        // Get the Value and store it in the CompareRequest
2726                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2727    
2728                        // We have to handle the special case of a 0 length value
2729                        if ( tlv.getLength() == 0 )
2730                        {
2731                            compareRequest.setAssertionValue( "" );
2732                        }
2733                        else
2734                        {
2735                            if ( ldapMessageContainer.isBinary( compareRequest.getAttributeDesc() ) )
2736                            {
2737                                compareRequest.setAssertionValue( tlv.getValue().getData() );
2738    
2739                                if ( IS_DEBUG )
2740                                {
2741                                    log.debug( "Comparing attribute value {}", StringTools
2742                                        .dumpBytes( ( byte[] ) compareRequest.getAssertionValue() ) );
2743                                }
2744                            }
2745                            else
2746                            {
2747                                compareRequest.setAssertionValue( StringTools.utf8ToString( tlv.getValue().getData() ) );
2748    
2749                                if ( log.isDebugEnabled() )
2750                                {
2751                                    log.debug( "Comparing attribute value {}", compareRequest.getAssertionValue() );
2752                                }
2753                            }
2754                        }
2755    
2756                        // We can have an END transition
2757                        ldapMessageContainer.grammarEndAllowed( true );
2758                    }
2759                } );
2760    
2761            // --------------------------------------------------------------------------------------------
2762            // Transition from Assertion Value to Controls
2763            // --------------------------------------------------------------------------------------------
2764            // AttributeValueAssertion ::= SEQUENCE {
2765            //     ...
2766            //     assertionValue AssertionValue }
2767            //
2768            // AssertionValue OCTET STRING
2769            // 
2770            // Stores the attribute value
2771            super.transitions[LdapStatesEnum.ASSERTION_VALUE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2772                LdapStatesEnum.ASSERTION_VALUE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2773                new ControlsInitAction() );
2774    
2775            // --------------------------------------------------------------------------------------------
2776            // CompareResponse Message.
2777            // --------------------------------------------------------------------------------------------
2778            // LdapMessage ::= ... CompareResponse ...
2779            // CompareResponse ::= [APPLICATION 15] LDAPResult
2780            // We have to switch to the CompareResponse grammar
2781            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.COMPARE_RESPONSE_TAG] = new GrammarTransition(
2782                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.COMPARE_RESPONSE_STATE, LdapConstants.COMPARE_RESPONSE_TAG,
2783                new GrammarAction( "Init CompareResponse" )
2784                {
2785                    public void action( IAsn1Container container ) throws DecoderException
2786                    {
2787    
2788                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2789                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2790    
2791                        // We will check that the request is not null
2792                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2793    
2794                        if ( tlv.getLength() == 0 )
2795                        {
2796                            String msg = "The CompareResponse must not be null";
2797                            log.error( msg );
2798                            throw new DecoderException( msg );
2799                        }
2800    
2801                        // Now, we can allocate the CompareResponse Object
2802                        // And we associate it to the ldapMessage Object
2803                        ldapMessage.setProtocolOP( new CompareResponseCodec() );
2804    
2805                        log.debug( "Compare response " );
2806                    }
2807                } );
2808    
2809            // --------------------------------------------------------------------------------------------
2810            // CompareResponse Message.
2811            // --------------------------------------------------------------------------------------------
2812            // LdapMessage ::= ... CompareResponse ...
2813            // CompareResponse ::= [APPLICATION 15] LDAPResult
2814            //
2815            // LDAPResult ::= SEQUENCE {
2816            //     resultCode    ENUMERATED {
2817            //         ...
2818            // 
2819            // Stores the result code
2820            super.transitions[LdapStatesEnum.COMPARE_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
2821                LdapStatesEnum.COMPARE_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
2822                new ResultCodeAction() );
2823    
2824            // --------------------------------------------------------------------------------------------
2825            // Transition from MessageID to SearchResultReference Message.
2826            // --------------------------------------------------------------------------------------------
2827            // LdapMessage ::= ... SearchResultReference ...
2828            // SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
2829            //
2830            // Initialization of SearchResultReference object
2831            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.SEARCH_RESULT_REFERENCE_TAG] = new GrammarTransition(
2832                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_RESULT_REFERENCE_STATE,
2833                LdapConstants.SEARCH_RESULT_REFERENCE_TAG, new GrammarAction( "Init SearchResultReference" )
2834                {
2835                    public void action( IAsn1Container container ) throws DecoderException
2836                    {
2837    
2838                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2839                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2840    
2841                        // Now, we can allocate the BindRequest Object
2842                        SearchResultReferenceCodec searchResultReference = new SearchResultReferenceCodec();
2843    
2844                        // As this is a new Constructed object, we have to init its
2845                        // length
2846                        searchResultReference.setParent( ldapMessage );
2847    
2848                        // And we associate it to the ldapMessage Object
2849                        ldapMessage.setProtocolOP( searchResultReference );
2850                    }
2851                } );
2852    
2853            // --------------------------------------------------------------------------------------------
2854            // Transition from SearchResultReference Message to Reference
2855            // --------------------------------------------------------------------------------------------
2856            // LdapMessage ::= ... SearchResultReference ...
2857            // SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
2858            //
2859            // Initialization of SearchResultReference object
2860            super.transitions[LdapStatesEnum.SEARCH_RESULT_REFERENCE_STATE][UniversalTag.OCTET_STRING] = new GrammarTransition(
2861                LdapStatesEnum.SEARCH_RESULT_REFERENCE_STATE, LdapStatesEnum.REFERENCE_STATE, UniversalTag.OCTET_STRING,
2862                new StoreReferenceAction() );
2863    
2864            // --------------------------------------------------------------------------------------------
2865            // Transition from Reference to Reference
2866            // --------------------------------------------------------------------------------------------
2867            // LdapMessage ::= ... SearchResultReference ...
2868            // SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
2869            //
2870            // Initialization of SearchResultReference object
2871            super.transitions[LdapStatesEnum.REFERENCE_STATE][UniversalTag.OCTET_STRING] = new GrammarTransition(
2872                LdapStatesEnum.REFERENCE_STATE, LdapStatesEnum.REFERENCE_STATE, UniversalTag.OCTET_STRING,
2873                new StoreReferenceAction() );
2874    
2875            // --------------------------------------------------------------------------------------------
2876            // Transition from Reference to Controls
2877            // --------------------------------------------------------------------------------------------
2878            //     searchResultReference SearchResultReference,
2879            //     ... },
2880            // controls   [0] Controls OPTIONAL }
2881            //
2882            // Initialization the controls
2883            super.transitions[LdapStatesEnum.REFERENCE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2884                LdapStatesEnum.REFERENCE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2885                new ControlsInitAction() );
2886    
2887            // --------------------------------------------------------------------------------------------
2888            // Transition from Message Id to ExtendedRequest Message
2889            // --------------------------------------------------------------------------------------------
2890            // LdapMessage ::= ... ExtendedRequest ...
2891            // ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
2892            //
2893            // Creates the ExtendedRequest object
2894            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.EXTENDED_REQUEST_TAG] = new GrammarTransition(
2895                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.EXTENDED_REQUEST_STATE, LdapConstants.EXTENDED_REQUEST_TAG,
2896                new GrammarAction( "Init Extended Request" )
2897                {
2898                    public void action( IAsn1Container container ) throws DecoderException
2899                    {
2900    
2901                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2902                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2903    
2904                        // We can allocate the ExtendedRequest Object
2905                        ldapMessage.setProtocolOP( new ExtendedRequestCodec() );
2906                    }
2907                } );
2908    
2909            // --------------------------------------------------------------------------------------------
2910            // Transition from ExtendedRequest Message to RequestName
2911            // --------------------------------------------------------------------------------------------
2912            // ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
2913            //     requestName [0] LDAPOID,
2914            //     ...
2915            //
2916            // Stores the name
2917            super.transitions[LdapStatesEnum.EXTENDED_REQUEST_STATE][LdapConstants.EXTENDED_REQUEST_NAME_TAG] = new GrammarTransition(
2918                LdapStatesEnum.EXTENDED_REQUEST_STATE, LdapStatesEnum.REQUEST_NAME_STATE,
2919                LdapConstants.EXTENDED_REQUEST_NAME_TAG, new GrammarAction( "Store name" )
2920                {
2921                    public void action( IAsn1Container container ) throws DecoderException
2922                    {
2923    
2924                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2925                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2926    
2927                        // We can allocate the ExtendedRequest Object
2928                        ExtendedRequestCodec extendedRequest = ldapMessage.getExtendedRequest();
2929    
2930                        // Get the Value and store it in the ExtendedRequest
2931                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2932    
2933                        // We have to handle the special case of a 0 length matched
2934                        // OID
2935                        if ( tlv.getLength() == 0 )
2936                        {
2937                            log.error( "The name must not be null" );
2938                            // This will generate a PROTOCOL_ERROR                        
2939                            throw new DecoderException( "The name must not be null" );
2940                        }
2941                        else
2942                        {
2943                            byte[] requestNameBytes = tlv.getValue().getData();
2944    
2945                            try
2946                            {
2947                                OID oid = new OID( StringTools.utf8ToString( requestNameBytes ) );
2948                                extendedRequest.setRequestName( oid );
2949                            }
2950                            catch ( DecoderException de )
2951                            {
2952                                String msg = "The Request name is not a valid OID : "
2953                                    + StringTools.utf8ToString( requestNameBytes ) + " ("
2954                                    + StringTools.dumpBytes( requestNameBytes ) + ") is invalid";
2955                                log.error( "{} : {}", msg, de.getMessage() );
2956    
2957                                // Rethrow the exception, we will get a PROTOCOL_ERROR
2958                                throw de;
2959                            }
2960                        }
2961    
2962                        // We can have an END transition
2963                        ldapMessageContainer.grammarEndAllowed( true );
2964    
2965                        if ( IS_DEBUG )
2966                        {
2967                            log.debug( "OID read : {}", extendedRequest.getRequestName() );
2968                        }
2969                    }
2970                } );
2971    
2972            // --------------------------------------------------------------------------------------------
2973            // Transition from RequestName to RequestValue
2974            // --------------------------------------------------------------------------------------------
2975            // ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
2976            //     ...
2977            //     requestValue  [1] OCTET STRING OPTIONAL }
2978            //
2979            // Stores the value
2980            super.transitions[LdapStatesEnum.REQUEST_NAME_STATE][LdapConstants.EXTENDED_REQUEST_VALUE_TAG] = new GrammarTransition(
2981                LdapStatesEnum.REQUEST_NAME_STATE, LdapStatesEnum.REQUEST_VALUE_STATE,
2982                LdapConstants.EXTENDED_REQUEST_VALUE_TAG, new GrammarAction( "Store value" )
2983                {
2984                    public void action( IAsn1Container container ) throws DecoderException
2985                    {
2986    
2987                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2988                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
2989    
2990                        // We can allocate the ExtendedRequest Object
2991                        ExtendedRequestCodec extendedRequest = ldapMessage.getExtendedRequest();
2992    
2993                        // Get the Value and store it in the ExtendedRequest
2994                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2995    
2996                        // We have to handle the special case of a 0 length matched
2997                        // value
2998                        if ( tlv.getLength() == 0 )
2999                        {
3000                            extendedRequest.setRequestValue( StringTools.EMPTY_BYTES );
3001                        }
3002                        else
3003                        {
3004                            extendedRequest.setRequestValue( tlv.getValue().getData() );
3005                        }
3006    
3007                        // We can have an END transition
3008                        ldapMessageContainer.grammarEndAllowed( true );
3009    
3010                        if ( IS_DEBUG )
3011                        {
3012                            log.debug( "Extended value : {}", extendedRequest.getRequestValue() );
3013                        }
3014                    }
3015                } );
3016    
3017            // --------------------------------------------------------------------------------------------
3018            // Transition from RequestName to Controls
3019            // --------------------------------------------------------------------------------------------
3020            //         extendedRequest   EtendedRequest,
3021            //         ... },
3022            //     controls       [0] Controls OPTIONAL }
3023            //
3024            // Stores the value
3025            super.transitions[LdapStatesEnum.REQUEST_NAME_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3026                LdapStatesEnum.REQUEST_NAME_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3027                new ControlsInitAction() );
3028    
3029            // --------------------------------------------------------------------------------------------
3030            // Transition from RequestValue to Controls
3031            // --------------------------------------------------------------------------------------------
3032            //         extendedRequest   EtendedRequest,
3033            //         ... },
3034            //     controls       [0] Controls OPTIONAL }
3035            //
3036            // Stores the value
3037            super.transitions[LdapStatesEnum.REQUEST_VALUE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3038                LdapStatesEnum.REQUEST_VALUE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3039                new ControlsInitAction() );
3040    
3041            // --------------------------------------------------------------------------------------------
3042            // Transition from MessageId to ExtendedResponse Message.
3043            // --------------------------------------------------------------------------------------------
3044            // LdapMessage ::= ... ExtendedResponse ...
3045            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3046            //
3047            // Creates the ExtendeResponse object
3048            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.EXTENDED_RESPONSE_TAG] = new GrammarTransition(
3049                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.EXTENDED_RESPONSE_STATE,
3050                LdapConstants.EXTENDED_RESPONSE_TAG, new GrammarAction( "Init Extended Reponse" )
3051                {
3052                    public void action( IAsn1Container container ) throws DecoderException
3053                    {
3054    
3055                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3056                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
3057    
3058                        // We can allocate the ExtendedResponse Object
3059                        ldapMessage.setProtocolOP( new ExtendedResponseCodec() );
3060                    }
3061                } );
3062    
3063            // --------------------------------------------------------------------------------------------
3064            // Transition from ExtendedResponse Message to Result Code ER
3065            // --------------------------------------------------------------------------------------------
3066            // LdapMessage ::= ... ExtendedResponse ...
3067            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3068            //     COMPONENTS OF LDAPResult,
3069            //     ...
3070            //
3071            // Stores the result code
3072            super.transitions[LdapStatesEnum.EXTENDED_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
3073                LdapStatesEnum.EXTENDED_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_ER_STATE, UniversalTag.ENUMERATED_TAG,
3074                new ResultCodeAction() );
3075    
3076            // --------------------------------------------------------------------------------------------
3077            // Transition from Result Code ER to Matched DN ER
3078            // --------------------------------------------------------------------------------------------
3079            // LdapMessage ::= ... ExtendedResponse ...
3080            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3081            //     COMPONENTS OF LDAPResult,
3082            //     ...
3083            //
3084            // 
3085            super.transitions[LdapStatesEnum.RESULT_CODE_ER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3086                LdapStatesEnum.RESULT_CODE_ER_STATE, LdapStatesEnum.MATCHED_DN_ER_STATE, UniversalTag.OCTET_STRING_TAG,
3087                new MatchedDNAction() );
3088    
3089            // --------------------------------------------------------------------------------------------
3090            // Transition from Matched DN ER to Error Message ER 
3091            // --------------------------------------------------------------------------------------------
3092            // LdapMessage ::= ... ExtendedResponse ...
3093            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3094            //     COMPONENTS OF LDAPResult,
3095            //     ...
3096            //
3097            // 
3098            super.transitions[LdapStatesEnum.MATCHED_DN_ER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3099                LdapStatesEnum.MATCHED_DN_ER_STATE, LdapStatesEnum.ERROR_MESSAGE_ER_STATE, UniversalTag.OCTET_STRING_TAG,
3100                new ErrorMessageAction() );
3101    
3102            // --------------------------------------------------------------------------------------------
3103            // Transition from Error Message ER to Referrals ER 
3104            // --------------------------------------------------------------------------------------------
3105            // LdapMessage ::= ... ExtendedResponse ...
3106            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3107            //     COMPONENTS OF LDAPResult,
3108            //     ...
3109            //
3110            // 
3111            super.transitions[LdapStatesEnum.ERROR_MESSAGE_ER_STATE][LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG] = 
3112                new GrammarTransition(
3113                LdapStatesEnum.ERROR_MESSAGE_ER_STATE, LdapStatesEnum.REFERRALS_ER_STATE,
3114                LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, new InitReferralsAction() );
3115    
3116            // --------------------------------------------------------------------------------------------
3117            // Transition from Referrals ER to Referral ER 
3118            // --------------------------------------------------------------------------------------------
3119            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
3120            // URI ::= LDAPString
3121            //
3122            // Add a first Referral
3123            super.transitions[LdapStatesEnum.REFERRALS_ER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3124                LdapStatesEnum.REFERRALS_ER_STATE, LdapStatesEnum.REFERRAL_ER_STATE, UniversalTag.OCTET_STRING_TAG,
3125                new ReferralAction() );
3126    
3127            // --------------------------------------------------------------------------------------------
3128            // Transition from Referral ER to Referral ER 
3129            // --------------------------------------------------------------------------------------------
3130            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
3131            // URI ::= LDAPString
3132            //
3133            // Adda new Referral
3134            super.transitions[LdapStatesEnum.REFERRAL_ER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3135                LdapStatesEnum.REFERRAL_ER_STATE, LdapStatesEnum.REFERRAL_ER_STATE, UniversalTag.OCTET_STRING_TAG,
3136                new ReferralAction() );
3137    
3138            // --------------------------------------------------------------------------------------------
3139            // Transition from Referral ER to ResponseName 
3140            // --------------------------------------------------------------------------------------------
3141            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
3142            // URI ::= LDAPString
3143            //
3144            // Adda new Referral
3145            super.transitions[LdapStatesEnum.REFERRAL_ER_STATE][LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG] = 
3146                new GrammarTransition(
3147                LdapStatesEnum.REFERRAL_ER_STATE, LdapStatesEnum.RESPONSE_NAME_STATE,
3148                LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG, new ResponseNameAction() );
3149    
3150            // --------------------------------------------------------------------------------------------
3151            // Transition from Referral ER to Response 
3152            // --------------------------------------------------------------------------------------------
3153            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
3154            // URI ::= LDAPString
3155            //
3156            // Adda new Referral
3157            super.transitions[LdapStatesEnum.REFERRAL_ER_STATE][LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG] = new GrammarTransition(
3158                LdapStatesEnum.REFERRAL_ER_STATE, LdapStatesEnum.RESPONSE_STATE,
3159                LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG, new ResponseAction() );
3160    
3161            // --------------------------------------------------------------------------------------------
3162            // Transition from Referral ER to Controls 
3163            // --------------------------------------------------------------------------------------------
3164            //         extendedResponse   ExtendedResponse,
3165            //         ... },
3166            //     controls       [0] Controls OPTIONAL }
3167            //
3168            // Adda new Referral
3169            super.transitions[LdapStatesEnum.REFERRAL_ER_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3170                LdapStatesEnum.REFERRAL_ER_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3171                new ControlsInitAction() );
3172    
3173            // --------------------------------------------------------------------------------------------
3174            // Transition from Error Message ER to Controls 
3175            // --------------------------------------------------------------------------------------------
3176            // LdapMessage ::= ... ExtendedResponse ...
3177            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3178            //     COMPONENTS OF LDAPResult,
3179            //     ...
3180            //
3181            // 
3182            super.transitions[LdapStatesEnum.ERROR_MESSAGE_ER_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3183                LdapStatesEnum.ERROR_MESSAGE_ER_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3184                new ControlsInitAction() );
3185    
3186            // --------------------------------------------------------------------------------------------
3187            // Transition from Error Message ER to ResponseName 
3188            // --------------------------------------------------------------------------------------------
3189            // LdapMessage ::= ... ExtendedResponse ...
3190            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3191            //     COMPONENTS OF LDAPResult,
3192            //     responseName   [10] LDAPOID OPTIONAL,
3193            //     ...
3194            //
3195            // Stores the response name
3196            super.transitions[LdapStatesEnum.ERROR_MESSAGE_ER_STATE][LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG] = 
3197                new GrammarTransition(
3198                LdapStatesEnum.ERROR_MESSAGE_ER_STATE, LdapStatesEnum.RESPONSE_NAME_STATE,
3199                LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG, new ResponseNameAction() );
3200    
3201            // --------------------------------------------------------------------------------------------
3202            // Transition from Response Name to Response 
3203            // --------------------------------------------------------------------------------------------
3204            // LdapMessage ::= ... ExtendedResponse ...
3205            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3206            //     ...
3207            //     responseName   [10] LDAPOID OPTIONAL,
3208            //     response       [11] OCTET STRING OPTIONAL}
3209            //
3210            // Stores the response
3211            super.transitions[LdapStatesEnum.RESPONSE_NAME_STATE][LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG] = new GrammarTransition(
3212                LdapStatesEnum.RESPONSE_NAME_STATE, LdapStatesEnum.RESPONSE_STATE,
3213                LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG, new ResponseAction() );
3214    
3215            // --------------------------------------------------------------------------------------------
3216            // Transition from ResponseName to Controls 
3217            // --------------------------------------------------------------------------------------------
3218            //         extendedRequest   EtendedRequest,
3219            //         ... },
3220            //     controls       [0] Controls OPTIONAL }
3221            //
3222            // Init the controls
3223            super.transitions[LdapStatesEnum.RESPONSE_NAME_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3224                LdapStatesEnum.RESPONSE_NAME_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3225                new ControlsInitAction() );
3226    
3227            // --------------------------------------------------------------------------------------------
3228            // Transition from Error Message ER to Response 
3229            // --------------------------------------------------------------------------------------------
3230            // LdapMessage ::= ... ExtendedResponse ...
3231            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3232            //     COMPONENTS OF LDAPResult,
3233            //     ...
3234            //     response       [11] OCTET STRING OPTIONAL}
3235            //
3236            // Stores the response
3237            super.transitions[LdapStatesEnum.ERROR_MESSAGE_ER_STATE][LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG] = 
3238                new GrammarTransition(
3239                LdapStatesEnum.ERROR_MESSAGE_ER_STATE, LdapStatesEnum.RESPONSE_STATE,
3240                LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG, new ResponseAction() );
3241    
3242            // --------------------------------------------------------------------------------------------
3243            // Transition from Response to Controls 
3244            // --------------------------------------------------------------------------------------------
3245            //         extendedRequest   EtendedRequest,
3246            //         ... },
3247            //     controls       [0] Controls OPTIONAL }
3248            //
3249            // Init the controls
3250            super.transitions[LdapStatesEnum.RESPONSE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3251                LdapStatesEnum.RESPONSE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3252                new ControlsInitAction() );
3253    
3254    
3255            // --------------------------------------------------------------------------------------------
3256            // Transition from Message Id to IntermediateResponse Message
3257            // --------------------------------------------------------------------------------------------
3258            // LdapMessage ::= ... IntermediateResponse ...
3259            // IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
3260            //
3261            // Creates the IntermediateResponse object
3262            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.INTERMEDIATE_RESPONSE_TAG] = new GrammarTransition(
3263                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.INTERMEDIATE_RESPONSE_STATE, LdapConstants.INTERMEDIATE_RESPONSE_TAG,
3264                new GrammarAction( "Init Intermediate Response" )
3265                {
3266                    public void action( IAsn1Container container ) throws DecoderException
3267                    {
3268    
3269                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3270                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
3271    
3272                        // We can allocate the IntermediateResponse Object
3273                        ldapMessage.setProtocolOP( new IntermediateResponseCodec() );
3274                    }
3275                } );
3276    
3277            // --------------------------------------------------------------------------------------------
3278            // Transition from IntermediateResponse Message to ResponseName
3279            // --------------------------------------------------------------------------------------------
3280            // IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
3281            //     responseName [0] LDAPOID OPTIONAL,
3282            //     ...
3283            //
3284            // Stores the name
3285            super.transitions[LdapStatesEnum.INTERMEDIATE_RESPONSE_STATE][LdapConstants.INTERMEDIATE_RESPONSE_NAME_TAG] = new GrammarTransition(
3286                LdapStatesEnum.INTERMEDIATE_RESPONSE_STATE, LdapStatesEnum.INTERMEDIATE_RESPONSE_NAME_STATE,
3287                LdapConstants.INTERMEDIATE_RESPONSE_NAME_TAG, new GrammarAction( "Store response name" )
3288                {
3289                    public void action( IAsn1Container container ) throws DecoderException
3290                    {
3291    
3292                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3293                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
3294    
3295                        // We can get the IntermediateResponse Object
3296                        IntermediateResponseCodec intermediateResponse = ldapMessage.getIntermediateResponse();
3297    
3298                        // Get the Value and store it in the IntermediateResponse
3299                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3300    
3301                        // We have to handle the special case of a 0 length matched
3302                        // OID.
3303                        if ( tlv.getLength() == 0 )
3304                        {
3305                            log.error( "The name must not be null" );
3306                            // This will generate a PROTOCOL_ERROR                        
3307                            throw new DecoderException( "The name must not be null" );
3308                        }
3309                        else
3310                        {
3311                            byte[] responseNameBytes = tlv.getValue().getData();
3312    
3313                            try
3314                            {
3315                                OID oid = new OID( StringTools.utf8ToString( responseNameBytes ) );
3316                                intermediateResponse.setResponseName( oid );
3317                            }
3318                            catch ( DecoderException de )
3319                            {
3320                                String msg = "The Intermediate Response name is not a valid OID : "
3321                                    + StringTools.utf8ToString( responseNameBytes ) + " ("
3322                                    + StringTools.dumpBytes( responseNameBytes ) + ") is invalid";
3323                                log.error( "{} : {}", msg, de.getMessage() );
3324    
3325                                // Rethrow the exception, we will get a PROTOCOL_ERROR
3326                                throw de;
3327                            }
3328                        }
3329    
3330                        // We can have an END transition
3331                        ldapMessageContainer.grammarEndAllowed( true );
3332    
3333                        if ( IS_DEBUG )
3334                        {
3335                            log.debug( "OID read : {}", intermediateResponse.getResponseName() );
3336                        }
3337                    }
3338                } );
3339    
3340            // --------------------------------------------------------------------------------------------
3341            // Transition from IntermediateResponse Message to ResponseValue (ResponseName is null)
3342            // --------------------------------------------------------------------------------------------
3343            // IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
3344            //     ...
3345            //     responseValue [1] OCTET STRING OPTIONAL
3346            //     }
3347            //
3348            // Stores the value
3349            super.transitions[LdapStatesEnum.INTERMEDIATE_RESPONSE_STATE][LdapConstants.INTERMEDIATE_RESPONSE_VALUE_TAG] = new GrammarTransition(
3350                LdapStatesEnum.INTERMEDIATE_RESPONSE_STATE, LdapStatesEnum.INTERMEDIATE_RESPONSE_VALUE_STATE,
3351                LdapConstants.INTERMEDIATE_RESPONSE_VALUE_TAG, new GrammarAction( "Store response value" )
3352                {
3353                    public void action( IAsn1Container container ) throws DecoderException
3354                    {
3355    
3356                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3357                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
3358    
3359                        // We can get the IntermediateResponse Object
3360                        IntermediateResponseCodec intermediateResponse = ldapMessage.getIntermediateResponse();
3361    
3362                        // Get the Value and store it in the IntermediateResponse
3363                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3364    
3365                        // We have to handle the special case of a 0 length matched
3366                        // value
3367                        if ( tlv.getLength() == 0 )
3368                        {
3369                            intermediateResponse.setResponseValue( StringTools.EMPTY_BYTES );
3370                        }
3371                        else
3372                        {
3373                            intermediateResponse.setResponseValue( tlv.getValue().getData() );
3374                        }
3375    
3376                        // We can have an END transition
3377                        ldapMessageContainer.grammarEndAllowed( true );
3378    
3379                        if ( IS_DEBUG )
3380                        {
3381                            log.debug( "Value read : {}", StringTools.dumpBytes( intermediateResponse.getResponseValue() ) );
3382                        }
3383                    }
3384                } );
3385    
3386            // --------------------------------------------------------------------------------------------
3387            // Transition from ResponseName to ResponseValue
3388            // --------------------------------------------------------------------------------------------
3389            // IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
3390            //     ...
3391            //     responseValue  [1] OCTET STRING OPTIONAL }
3392            //
3393            // Stores the value
3394            super.transitions[LdapStatesEnum.INTERMEDIATE_RESPONSE_NAME_STATE][LdapConstants.INTERMEDIATE_RESPONSE_VALUE_TAG] = new GrammarTransition(
3395                LdapStatesEnum.INTERMEDIATE_RESPONSE_NAME_STATE, LdapStatesEnum.INTERMEDIATE_RESPONSE_VALUE_STATE,
3396                LdapConstants.INTERMEDIATE_RESPONSE_VALUE_TAG, new GrammarAction( "Store value" )
3397                {
3398                    public void action( IAsn1Container container ) throws DecoderException
3399                    {
3400    
3401                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3402                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
3403    
3404                        // We can allocate the ExtendedRequest Object
3405                        IntermediateResponseCodec intermediateResponse = ldapMessage.getIntermediateResponse();
3406    
3407                        // Get the Value and store it in the IntermediateResponse
3408                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3409    
3410                        // We have to handle the special case of a 0 length matched
3411                        // value
3412                        if ( tlv.getLength() == 0 )
3413                        {
3414                            intermediateResponse.setResponseValue( StringTools.EMPTY_BYTES );
3415                        }
3416                        else
3417                        {
3418                            intermediateResponse.setResponseValue( tlv.getValue().getData() );
3419                        }
3420    
3421                        // We can have an END transition
3422                        ldapMessageContainer.grammarEndAllowed( true );
3423    
3424                        if ( IS_DEBUG )
3425                        {
3426                            log.debug( "Response value : {}", intermediateResponse.getResponseValue() );
3427                        }
3428                    }
3429                } );
3430    
3431            // --------------------------------------------------------------------------------------------
3432            // Transition from ResponseName to Controls
3433            // --------------------------------------------------------------------------------------------
3434            //         intermediateResponse   IntermediateResponse,
3435            //         ... },
3436            //     controls       [0] Controls OPTIONAL }
3437            //
3438            // Stores the value
3439            super.transitions[LdapStatesEnum.INTERMEDIATE_RESPONSE_NAME_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3440                LdapStatesEnum.INTERMEDIATE_RESPONSE_NAME_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3441                new ControlsInitAction() );
3442    
3443            // --------------------------------------------------------------------------------------------
3444            // Transition from ResponseValue to Controls
3445            // --------------------------------------------------------------------------------------------
3446            //         intermediateResponse   IntermediateResponse,
3447            //         ... },
3448            //     controls       [0] Controls OPTIONAL }
3449            //
3450            // Stores the value
3451            super.transitions[LdapStatesEnum.INTERMEDIATE_RESPONSE_VALUE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3452                LdapStatesEnum.INTERMEDIATE_RESPONSE_VALUE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3453                new ControlsInitAction() );
3454    
3455    
3456            // --------------------------------------------------------------------------------------------
3457            // Controls
3458            // --------------------------------------------------------------------------------------------
3459            IAction addControl = new GrammarAction( "Add Control" )
3460            {
3461                public void action( IAsn1Container container ) throws DecoderException
3462                {
3463                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3464                    LdapMessageCodec message = ldapMessageContainer.getLdapMessage();
3465    
3466                    TLV tlv = ldapMessageContainer.getCurrentTLV();
3467                    int expectedLength = tlv.getLength();
3468    
3469                    // The Length should be null
3470                    if ( expectedLength == 0 )
3471                    {
3472                        log.error( "The length of a control must not be null" );
3473    
3474                        // This will generate a PROTOCOL_ERROR
3475                        throw new DecoderException( "The length of a control must not be null" );
3476                    }
3477    
3478                    // Create a new control
3479                    ControlCodec control = new ControlCodec();
3480    
3481                    // Store the control into the container
3482                    message.addControl( control );
3483                }
3484            };
3485    
3486            // ============================================================================================
3487            // Transition from Controls to Control
3488            // ============================================================================================
3489            // ...
3490            // Controls ::= SEQUENCE OF Control
3491            //  ...
3492            //
3493            // Initialize the controls 
3494            super.transitions[LdapStatesEnum.CONTROLS_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
3495                LdapStatesEnum.CONTROLS_STATE, LdapStatesEnum.CONTROL_STATE, UniversalTag.SEQUENCE_TAG, addControl );
3496    
3497            // ============================================================================================
3498            // Transition from Control to ControlType
3499            // ============================================================================================
3500            // Control ::= SEQUENCE {
3501            //     ...
3502            //
3503            // Create a new Control object, and store it in the message Container
3504            super.transitions[LdapStatesEnum.CONTROL_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3505                LdapStatesEnum.CONTROL_STATE, LdapStatesEnum.CONTROL_TYPE_STATE, UniversalTag.OCTET_STRING_TAG,
3506                new GrammarAction( "Set Control Type" )
3507                {
3508                    public void action( IAsn1Container container ) throws DecoderException
3509                    {
3510                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3511                        LdapMessageCodec message = ldapMessageContainer.getLdapMessage();
3512    
3513                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3514    
3515                        // Get the current control
3516                        ControlCodec control = message.getCurrentControl();
3517    
3518                        // Store the type
3519                        // We have to handle the special case of a 0 length OID
3520                        if ( tlv.getLength() == 0 )
3521                        {
3522                            log.error( "The OID must not be null" );
3523    
3524                            // This will generate a PROTOCOL_ERROR
3525                            throw new DecoderException( "The OID must not be null" );
3526                        }
3527                        else
3528                        {
3529                            byte[] value = tlv.getValue().getData();
3530                            String oidValue = StringTools.asciiBytesToString( value );
3531    
3532                            // The OID is encoded as a String, not an Object Id
3533                            try
3534                            {
3535                                new OID( oidValue );
3536                            }
3537                            catch ( DecoderException de )
3538                            {
3539                                log.error( "The control type " + StringTools.dumpBytes( value ) + " is not a valid OID : "
3540                                    + de.getMessage() );
3541    
3542                                // This will generate a PROTOCOL_ERROR
3543                                throw de;
3544                            }
3545    
3546                            control.setControlType( oidValue );
3547                        }
3548    
3549                        // We can have an END transition
3550                        ldapMessageContainer.grammarEndAllowed( true );
3551    
3552                        if ( IS_DEBUG )
3553                        {
3554                            log.debug( "Control OID : " + control.getControlType() );
3555                        }
3556                    }
3557                } );
3558    
3559            // ============================================================================================
3560            // Transition from ControlType to Control Criticality
3561            // ============================================================================================
3562            // Control ::= SEQUENCE {
3563            //     ...
3564            //     criticality BOOLEAN DEFAULT FALSE,
3565            //     ...
3566            //
3567            // Store the value in the control object created before
3568            super.transitions[LdapStatesEnum.CONTROL_TYPE_STATE][UniversalTag.BOOLEAN_TAG] = new GrammarTransition(
3569                LdapStatesEnum.CONTROL_TYPE_STATE, LdapStatesEnum.CRITICALITY_STATE, UniversalTag.OCTET_STRING_TAG,
3570                new GrammarAction( "Set Criticality" )
3571                {
3572                    public void action( IAsn1Container container ) throws DecoderException
3573                    {
3574                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3575                        LdapMessageCodec message = ldapMessageContainer.getLdapMessage();
3576    
3577                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3578    
3579                        // Get the current control
3580                        ControlCodec control = message.getCurrentControl();
3581    
3582                        // Store the criticality
3583                        // We get the value. If it's a 0, it's a FALSE. If it's
3584                        // a FF, it's a TRUE. Any other value should be an error,
3585                        // but we could relax this constraint. So if we have
3586                        // something
3587                        // which is not 0, it will be interpreted as TRUE, but we
3588                        // will generate a warning.
3589                        Value value = tlv.getValue();
3590    
3591                        try
3592                        {
3593                            control.setCriticality( BooleanDecoder.parse( value ) );
3594                        }
3595                        catch ( BooleanDecoderException bde )
3596                        {
3597                            log.error( "The control criticality flag " + StringTools.dumpBytes( value.getData() )
3598                                + " is invalid : " + bde.getMessage() + ". It should be 0 or 255" );
3599    
3600                            // This will generate a PROTOCOL_ERROR
3601                            throw new DecoderException( bde.getMessage() );
3602                        }
3603    
3604                        // We can have an END transition
3605                        ldapMessageContainer.grammarEndAllowed( true );
3606    
3607                        if ( IS_DEBUG )
3608                        {
3609                            log.debug( "Control criticality : " + control.getCriticality() );
3610                        }
3611                    }
3612                } );
3613    
3614            // ============================================================================================
3615            // Transition from Control Criticality to Control Value
3616            // ============================================================================================
3617            // Control ::= SEQUENCE {
3618            //     ...
3619            //     controlValue OCTET STRING OPTIONAL }
3620            //
3621            // Store the value in the control object created before
3622            super.transitions[LdapStatesEnum.CRITICALITY_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3623                LdapStatesEnum.CRITICALITY_STATE, LdapStatesEnum.CONTROL_VALUE_STATE, UniversalTag.OCTET_STRING_TAG,
3624                new ControlValueAction() );
3625    
3626            // ============================================================================================
3627            // Transition from Control Type to Control Value
3628            // ============================================================================================
3629            // Control ::= SEQUENCE {
3630            //     ...
3631            //     controlValue OCTET STRING OPTIONAL }
3632            //
3633            // Store the value in the control object created before
3634            super.transitions[LdapStatesEnum.CONTROL_TYPE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3635                LdapStatesEnum.CONTROL_TYPE_STATE, LdapStatesEnum.CONTROL_VALUE_STATE, UniversalTag.OCTET_STRING_TAG,
3636                new ControlValueAction() );
3637    
3638            // ============================================================================================
3639            // Transition from Control Type to Control
3640            // ============================================================================================
3641            // Control ::= SEQUENCE {
3642            //     ...
3643            //     controlValue OCTET STRING OPTIONAL }
3644            //
3645            // Store the value in the control object created before
3646            super.transitions[LdapStatesEnum.CONTROL_TYPE_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
3647                LdapStatesEnum.CONTROL_TYPE_STATE, LdapStatesEnum.CONTROL_STATE, UniversalTag.SEQUENCE_TAG, addControl );
3648    
3649            // ============================================================================================
3650            // Transition from Control Criticality to Control
3651            // ============================================================================================
3652            // Control ::= SEQUENCE {
3653            //     ...
3654            //     controlValue OCTET STRING OPTIONAL }
3655            //
3656            // Store the value in the control object created before
3657            super.transitions[LdapStatesEnum.CRITICALITY_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
3658                LdapStatesEnum.CRITICALITY_STATE, LdapStatesEnum.CONTROL_STATE, UniversalTag.SEQUENCE_TAG, addControl );
3659    
3660            // ============================================================================================
3661            // Transition from Control Value to Control
3662            // ============================================================================================
3663            // Control ::= SEQUENCE {
3664            //     ...
3665            //     controlValue OCTET STRING OPTIONAL }
3666            //
3667            // Store the value in the control object created before
3668            super.transitions[LdapStatesEnum.CONTROL_VALUE_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
3669                LdapStatesEnum.CONTROL_VALUE_STATE, LdapStatesEnum.CONTROL_STATE, UniversalTag.SEQUENCE_TAG, addControl );
3670    
3671            // --------------------------------------------------------------------------------------------
3672            // Transition from message ID to SearchRequest Message
3673            // --------------------------------------------------------------------------------------------
3674            // LdapMessage ::= ... SearchRequest ...
3675            // SearchRequest ::= [APPLICATION 3] SEQUENCE { ...
3676            //
3677            // Initialize the searchRequest object
3678            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.SEARCH_REQUEST_TAG] = new GrammarTransition(
3679                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_REQUEST_STATE, LdapConstants.SEARCH_REQUEST_TAG,
3680                new GrammarAction( "Init SearchRequest" )
3681                {
3682                    public void action( IAsn1Container container )
3683                    {
3684    
3685                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3686                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
3687    
3688                        // Now, we can allocate the SearchRequest
3689                        // And we associate it to the ldapMessage Object
3690                        ldapMessage.setProtocolOP( new SearchRequestCodec() );
3691                    }
3692                } );
3693    
3694            // --------------------------------------------------------------------------------------------
3695            // Transition from SearchRequest Message to BaseObject
3696            // --------------------------------------------------------------------------------------------
3697            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3698            //     baseObject LDAPDN,
3699            //     ...
3700            //
3701            // We have a value for the base object, we will store it in the message
3702            super.transitions[LdapStatesEnum.SEARCH_REQUEST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3703                LdapStatesEnum.SEARCH_REQUEST_STATE, LdapStatesEnum.BASE_OBJECT_STATE, UniversalTag.OCTET_STRING_TAG,
3704                new GrammarAction( "store base object value" )
3705                {
3706                    public void action( IAsn1Container container ) throws DecoderException
3707                    {
3708    
3709                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3710                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
3711                        SearchRequestCodec searchRequest = ldapMessage.getSearchRequest();
3712    
3713                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3714    
3715                        // We have to check that this is a correct DN
3716                        LdapDN baseObject = LdapDN.EMPTY_LDAPDN;
3717    
3718                        // We have to handle the special case of a 0 length base
3719                        // object,
3720                        // which means that the search is done from the default
3721                        // root.
3722                        if ( tlv.getLength() != 0 )
3723                        {
3724                            byte[] dnBytes = tlv.getValue().getData();
3725    
3726                            try
3727                            {
3728                                baseObject = new LdapDN( dnBytes );
3729                            }
3730                            catch ( InvalidNameException ine )
3731                            {
3732                                String msg = "Invalid root DN given : " + StringTools.utf8ToString( dnBytes ) + " ("
3733                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
3734                                log.error( "{} : {}", msg, ine.getMessage() );
3735    
3736                                SearchResponseDoneImpl response = new SearchResponseDoneImpl( ldapMessage.getMessageId() );
3737                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
3738                                    LdapDN.EMPTY_LDAPDN, ine );
3739                            }
3740                        }
3741    
3742                        searchRequest.setBaseObject( baseObject );
3743    
3744                        log.debug( "Searching with root DN : {}", baseObject );
3745    
3746                        return;
3747                    }
3748                } );
3749    
3750            // --------------------------------------------------------------------------------------------
3751            // Transition from BaseObject to Scope
3752            // --------------------------------------------------------------------------------------------
3753            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3754            //     ...
3755            //     scope ENUMERATED {
3756            //         baseObject   (0),
3757            //         singleLevel  (1),
3758            //         wholeSubtree (2) },
3759            //     ...
3760            //
3761            // We have a value for the scope, we will store it in the message
3762            super.transitions[LdapStatesEnum.BASE_OBJECT_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
3763                LdapStatesEnum.BASE_OBJECT_STATE, LdapStatesEnum.SCOPE_STATE, UniversalTag.ENUMERATED_TAG,
3764                new GrammarAction( "store scope value" )
3765                {
3766                    public void action( IAsn1Container container ) throws DecoderException
3767                    {
3768    
3769                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3770    
3771                        SearchRequestCodec searchRequest = ldapMessageContainer.getLdapMessage().getSearchRequest();
3772    
3773                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3774    
3775                        // We have to check that this is a correct scope
3776                        Value value = tlv.getValue();
3777                        int scope = 0;
3778    
3779                        try
3780                        {
3781                            scope = IntegerDecoder.parse( value, LdapConstants.SCOPE_BASE_OBJECT,
3782                                LdapConstants.SCOPE_WHOLE_SUBTREE );
3783                        }
3784                        catch ( IntegerDecoderException ide )
3785                        {
3786                            log.error( "The scope is not in [0..2] : {}", value.toString() );
3787                            throw new DecoderException( "The scope is not in [0..2] : " + value.toString() );
3788                        }
3789    
3790                        searchRequest.setScope( SearchScope.getSearchScope( scope ) );
3791    
3792                        if ( IS_DEBUG )
3793                        {
3794                            switch ( scope )
3795                            {
3796                                case LdapConstants.SCOPE_BASE_OBJECT:
3797                                    log.debug( "Searching within BASE_OBJECT scope " );
3798                                    break;
3799    
3800                                case LdapConstants.SCOPE_SINGLE_LEVEL:
3801                                    log.debug( "Searching within SINGLE_LEVEL scope " );
3802                                    break;
3803    
3804                                case LdapConstants.SCOPE_WHOLE_SUBTREE:
3805                                    log.debug( "Searching within WHOLE_SUBTREE scope " );
3806                                    break;
3807                            }
3808                        }
3809    
3810                        return;
3811                    }
3812                } );
3813    
3814            // --------------------------------------------------------------------------------------------
3815            // Transition from Scope to DerefAlias
3816            // --------------------------------------------------------------------------------------------
3817            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3818            //     ...
3819            //     derefAliases ENUMERATED {
3820            //         neverDerefAliases   (0),
3821            //         derefInSearching    (1),
3822            //         derefFindingBaseObj (2),
3823            //         derefAlways         (3) },
3824            //     ...
3825            //
3826            // We have a value for the derefAliases, we will store it in the message
3827            super.transitions[LdapStatesEnum.SCOPE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
3828                LdapStatesEnum.SCOPE_STATE, LdapStatesEnum.DEREF_ALIAS_STATE, UniversalTag.ENUMERATED_TAG,
3829                new GrammarAction( "store derefAliases value" )
3830                {
3831                    public void action( IAsn1Container container ) throws DecoderException
3832                    {
3833    
3834                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3835    
3836                        SearchRequestCodec searchRequest = ldapMessageContainer.getLdapMessage().getSearchRequest();
3837    
3838                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3839    
3840                        // We have to check that this is a correct derefAliases
3841                        Value value = tlv.getValue();
3842                        int derefAliases = 0;
3843    
3844                        try
3845                        {
3846                            derefAliases = IntegerDecoder.parse( value, LdapConstants.NEVER_DEREF_ALIASES,
3847                                LdapConstants.DEREF_ALWAYS );
3848                        }
3849                        catch ( IntegerDecoderException ide )
3850                        {
3851                            log.error( "The derefAlias is not in [0..3] : {}", value.toString() );
3852                            throw new DecoderException( "The derefAlias is not in [0..3] : " + value.toString() );
3853                        }
3854    
3855                        searchRequest.setDerefAliases( derefAliases );
3856    
3857                        if ( IS_DEBUG )
3858                        {
3859                            switch ( derefAliases )
3860                            {
3861                                case LdapConstants.NEVER_DEREF_ALIASES:
3862                                    log.debug( "Handling object strategy : NEVER_DEREF_ALIASES" );
3863                                    break;
3864    
3865                                case LdapConstants.DEREF_IN_SEARCHING:
3866                                    log.debug( "Handling object strategy : DEREF_IN_SEARCHING" );
3867                                    break;
3868    
3869                                case LdapConstants.DEREF_FINDING_BASE_OBJ:
3870                                    log.debug( "Handling object strategy : DEREF_FINDING_BASE_OBJ" );
3871                                    break;
3872    
3873                                case LdapConstants.DEREF_ALWAYS:
3874                                    log.debug( "Handling object strategy : DEREF_ALWAYS" );
3875                                    break;
3876                            }
3877                        }
3878                        return;
3879                    }
3880                } );
3881    
3882            // --------------------------------------------------------------------------------------------
3883            // Transition from DerefAlias to SizeLimit
3884            // --------------------------------------------------------------------------------------------
3885            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3886            //     ...
3887            //     sizeLimit INTEGER (0 .. maxInt),
3888            //     ...
3889            //
3890            // We have a value for the sizeLimit, we will store it in the message
3891            super.transitions[LdapStatesEnum.DEREF_ALIAS_STATE][UniversalTag.INTEGER_TAG] = new GrammarTransition(
3892                LdapStatesEnum.DEREF_ALIAS_STATE, LdapStatesEnum.SIZE_LIMIT_STATE, UniversalTag.INTEGER_TAG,
3893                new GrammarAction( "store sizeLimit value" )
3894                {
3895                    public void action( IAsn1Container container ) throws DecoderException
3896                    {
3897    
3898                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3899    
3900                        SearchRequestCodec searchRequest = ldapMessageContainer.getLdapMessage().getSearchRequest();
3901    
3902                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3903    
3904                        // The current TLV should be a integer
3905                        // We get it and store it in sizeLimit
3906                        Value value = tlv.getValue();
3907                        int sizeLimit = 0;
3908    
3909                        try
3910                        {
3911                            sizeLimit = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
3912                        }
3913                        catch ( IntegerDecoderException ide )
3914                        {
3915                            log.error( "The sizeLimit is not a valid Integer: {}", value.toString() );
3916                            throw new DecoderException( "The sizeLimit is not a valid Integer: " + value.toString() );
3917                        }
3918    
3919                        searchRequest.setSizeLimit( sizeLimit );
3920    
3921                        if ( IS_DEBUG )
3922                        {
3923                            log.debug( "The sizeLimit value is set to {} objects", Integer.valueOf( sizeLimit ) );
3924                        }
3925    
3926                        return;
3927                    }
3928                } );
3929    
3930            // --------------------------------------------------------------------------------------------
3931            // Transition from SizeLimit to TimeLimit
3932            // --------------------------------------------------------------------------------------------
3933            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3934            //     ...
3935            //     timeLimit INTEGER (0 .. maxInt),
3936            //     ...
3937            //
3938            // We have a value for the timeLimit, we will store it in the message
3939            super.transitions[LdapStatesEnum.SIZE_LIMIT_STATE][UniversalTag.INTEGER_TAG] = new GrammarTransition(
3940                LdapStatesEnum.SIZE_LIMIT_STATE, LdapStatesEnum.TIME_LIMIT_STATE, UniversalTag.INTEGER_TAG,
3941                new GrammarAction( "store timeLimit value" )
3942                {
3943                    public void action( IAsn1Container container ) throws DecoderException
3944                    {
3945    
3946                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3947    
3948                        SearchRequestCodec searchRequest = ldapMessageContainer.getLdapMessage().getSearchRequest();
3949    
3950                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3951    
3952                        // The current TLV should be a integer
3953                        // We get it and store it in timeLimit
3954                        Value value = tlv.getValue();
3955    
3956                        int timeLimit = 0;
3957    
3958                        try
3959                        {
3960                            timeLimit = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
3961                        }
3962                        catch ( IntegerDecoderException ide )
3963                        {
3964                            log.error( "The timeLimit is not a valid Integer: {}", value.toString() );
3965                            throw new DecoderException( "The timeLimit is not a valid Integer: " + value.toString() );
3966                        }
3967    
3968                        searchRequest.setTimeLimit( timeLimit );
3969    
3970                        if ( IS_DEBUG )
3971                        {
3972                            log.debug( "The timeLimit value is set to {} seconds", Integer.valueOf( timeLimit ) );
3973                        }
3974    
3975                        return;
3976                    }
3977                } );
3978    
3979            // --------------------------------------------------------------------------------------------
3980            // Transition from TimeLimit to TypesOnly
3981            // --------------------------------------------------------------------------------------------
3982            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3983            //     ...
3984            //     typesOnly BOOLEAN,
3985            //     ...
3986            //
3987            // We have a value for the typesOnly, we will store it in the message.
3988            super.transitions[LdapStatesEnum.TIME_LIMIT_STATE][UniversalTag.BOOLEAN_TAG] = new GrammarTransition(
3989                LdapStatesEnum.TIME_LIMIT_STATE, LdapStatesEnum.TYPES_ONLY_STATE, UniversalTag.BOOLEAN_TAG,
3990                new GrammarAction( "store typesOnly value" )
3991                {
3992                    public void action( IAsn1Container container ) throws DecoderException
3993                    {
3994    
3995                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3996    
3997                        SearchRequestCodec searchRequest = ldapMessageContainer.getLdapMessage().getSearchRequest();
3998    
3999                        TLV tlv = ldapMessageContainer.getCurrentTLV();
4000    
4001                        // We get the value. If it's a 0, it's a FALSE. If it's
4002                        // a FF, it's a TRUE. Any other value should be an error,
4003                        // but we could relax this constraint. So if we have
4004                        // something
4005                        // which is not 0, it will be interpreted as TRUE, but we
4006                        // will generate a warning.
4007                        Value value = tlv.getValue();
4008    
4009                        try
4010                        {
4011                            searchRequest.setTypesOnly( BooleanDecoder.parse( value ) );
4012                        }
4013                        catch ( BooleanDecoderException bde )
4014                        {
4015                            log.error( "The types only flag {} is invalid : {}. It should be 0 or 255", StringTools
4016                                .dumpBytes( value.getData() ), bde.getMessage() );
4017    
4018                            throw new DecoderException( bde.getMessage() );
4019                        }
4020    
4021                        if ( IS_DEBUG )
4022                        {
4023                            log.debug( "The search will return {}", ( searchRequest.isTypesOnly() ? "only attributs type"
4024                                : "attributes types and values" ) );
4025                        }
4026                        return;
4027                    }
4028                } );
4029    
4030            //============================================================================================
4031            // Search Request And Filter
4032            // This is quite complicated, because we have a tree structure to build,
4033            // and we may have many elements on each node. For instance, considering the 
4034            // search filter :
4035            // (& (| (a = b) (c = d)) (! (e = f)) (attr =* h))
4036            // We will have to create an And filter with three children :
4037            //  - an Or child,
4038            //  - a Not child
4039            //  - and a Present child.
4040            // The Or child will also have two children.
4041            //
4042            // We know when we have a children while decoding the PDU, because the length
4043            // of its parent has not yet reached its expected length.
4044            //
4045            // This search filter :
4046            // (&(|(objectclass=top)(ou=contacts))(!(objectclass=ttt))(objectclass=*top))
4047            // is encoded like this :
4048            //                              +----------------+---------------+
4049            //                              | ExpectedLength | CurrentLength |
4050            //+-----------------------------+----------------+---------------+
4051            //|A0 52                        | 82             | 0             | new level 1
4052            //|   A1 24                     | 82 36          | 0 0           | new level 2
4053            //|      A3 12                  | 82 36 18       | 0 0 0         | new level 3
4054            //|         04 0B 'objectclass' | 82 36 18       | 0 0 13        |
4055            //|         04 03 'top'         | 82 36 18       | 0 20 18       | 
4056            //|                             |       ^               ^        |
4057            //|                             |       |               |        |
4058            //|                             |       +---------------+        |
4059            //+-----------------------------* end level 3 -------------------*
4060            //|      A3 0E                  | 82 36 14       | 0 0 0         | new level 3
4061            //|         04 02 'ou'          | 82 36 14       | 0 0 4         |
4062            //|         04 08 'contacts'    | 82 36 14       | 38 36 14      | 
4063            //|                             |    ^  ^             ^  ^       |
4064            //|                             |    |  |             |  |       |
4065            //|                             |    |  +-------------|--+       |
4066            //|                             |    +----------------+          |
4067            //+-----------------------------* end level 3, end level 2 ------*
4068            //|   A2 14                     | 82 20          | 38 0          | new level 2
4069            //|      A3 12                  | 82 20 18       | 38 0 0        | new level 3
4070            //|         04 0B 'objectclass' | 82 20 18       | 38 0 13       | 
4071            //|         04 03 'ttt'         | 82 20 18       | 60 20 18      |
4072            //|                             |    ^  ^             ^  ^       |
4073            //|                             |    |  |             |  |       |
4074            //|                             |    |  +-------------|--+       |
4075            //|                             |    +----------------+          |
4076            //+-----------------------------* end level 3, end level 2 ------*
4077            //|   A4 14                     | 82 20          | 60 0          | new level 2
4078            //|      04 0B 'objectclass'    | 82 20          | 60 13         |
4079            //|      30 05                  | 82 20          | 60 13         |
4080            //|         82 03 'top'         | 82 20          | 82 20         | 
4081            //|                             | ^  ^             ^  ^          |
4082            //|                             | |  |             |  |          |
4083            //|                             | |  +-------------|--+          |
4084            //|                             | +----------------+             |
4085            //+-----------------------------* end level 2, end level 1 ------*
4086            //+-----------------------------+----------------+---------------+
4087            //
4088            // When the current length equals the expected length of the parent PDU,
4089            // then we are able to 'close' the parent : it has all its children. This
4090            // is propagated through all the tree, until either there are no more
4091            // parents, or the expected length of the parent is different from the
4092            // current length.
4093    
4094            // --------------------------------------------------------------------------------------------
4095            // Transition from TypesOnly to AND filter
4096            // --------------------------------------------------------------------------------------------
4097            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4098            //     ...
4099            //     filter Filter,
4100            //     ...
4101            //
4102            // Filter ::= CHOICE {
4103            //     and             [0] SET OF Filter,
4104            //     ...
4105            //
4106            // Init AND filter
4107            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
4108                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
4109                new InitAndFilterAction() );
4110    
4111            // --------------------------------------------------------------------------------------------
4112            // Transition from TypesOnly to OR filter
4113            // --------------------------------------------------------------------------------------------
4114            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4115            //     ...
4116            //     filter Filter,
4117            //     ...
4118            //
4119            // Filter ::= CHOICE {
4120            //     ...
4121            //     or              [1] SET OF Filter,
4122            //     ...
4123            //
4124            // Init OR filter
4125            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
4126                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
4127                new InitOrFilterAction() );
4128    
4129            // --------------------------------------------------------------------------------------------
4130            // Transition from TypesOnly to NOT filter
4131            // --------------------------------------------------------------------------------------------
4132            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4133            //     ...
4134            //     filter Filter,
4135            //     ...
4136            //
4137            // Filter ::= CHOICE {
4138            //     ...
4139            //     not             [2] SET OF Filter,
4140            //     ...
4141            //
4142            // Init NOT filter
4143            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
4144                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
4145                new InitNotFilterAction() );
4146    
4147            // --------------------------------------------------------------------------------------------
4148            // Transition from TypesOnly to Equality Match filter
4149            // --------------------------------------------------------------------------------------------
4150            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4151            //     ...
4152            //     filter Filter,
4153            //     ...
4154            //
4155            // Filter ::= CHOICE {
4156            //     ...
4157            //     equalityMatch   [3] AttributeValueAssertion,
4158            //     ...
4159            //
4160            // Init NOT filter
4161            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
4162                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE,
4163                LdapConstants.EQUALITY_MATCH_FILTER_TAG, new InitEqualityMatchFilterAction() );
4164    
4165            // --------------------------------------------------------------------------------------------
4166            // Transition from TypesOnly to Substrings filter
4167            // --------------------------------------------------------------------------------------------
4168            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4169            //     ...
4170            //     filter Filter,
4171            //     ...
4172            //
4173            // Filter ::= CHOICE {
4174            //     ...
4175            //     substrings     [4] SubstringFilter,
4176            //     ...
4177            //
4178            // Init Substrings filter
4179            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
4180                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE,
4181                LdapConstants.SUBSTRINGS_FILTER_TAG, new InitSubstringsFilterAction() );
4182    
4183            // --------------------------------------------------------------------------------------------
4184            // Transition from TypesOnly to GreaterOrEqual filter
4185            // --------------------------------------------------------------------------------------------
4186            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4187            //     ...
4188            //     filter Filter,
4189            //     ...
4190            //
4191            // Filter ::= CHOICE {
4192            //     ...
4193            //     greaterOrEqual  [5] AttributeValueAssertion,
4194            //     ...
4195            //
4196            // Init Greater Or Equal filter
4197            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4198                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
4199                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
4200    
4201            // --------------------------------------------------------------------------------------------
4202            // Transition from TypesOnly to LessOrEqual filter
4203            // --------------------------------------------------------------------------------------------
4204            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4205            //     ...
4206            //     filter Filter,
4207            //     ...
4208            //
4209            // Filter ::= CHOICE {
4210            //     ...
4211            //     LessOrEqual    [6] AttributeValueAssertion,
4212            //     ...
4213            //
4214            // Init Less Or Equal filter
4215            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4216                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE,
4217                LdapConstants.LESS_OR_EQUAL_FILTER_TAG, new InitLessOrEqualFilterAction() );
4218    
4219            // --------------------------------------------------------------------------------------------
4220            // Transition from TypesOnly to Present filter
4221            // --------------------------------------------------------------------------------------------
4222            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4223            //     ...
4224            //     filter Filter,
4225            //     ...
4226            //
4227            // Filter ::= CHOICE {
4228            //     ...
4229            //     present        [7] AttributeDescription,
4230            //     ...
4231            //
4232            // Init Approx Match filter
4233            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
4234                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
4235                new InitPresentFilterAction() );
4236    
4237            // --------------------------------------------------------------------------------------------
4238            // Transition from TypesOnly to Approx Match filter
4239            // --------------------------------------------------------------------------------------------
4240            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4241            //     ...
4242            //     filter Filter,
4243            //     ...
4244            //
4245            // Filter ::= CHOICE {
4246            //     ...
4247            //     approxMatch     [8] AttributeValueAssertion,
4248            //     ...
4249            //
4250            // Init Approx Match filter
4251            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
4252                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
4253                new InitApproxMatchFilterAction() );
4254    
4255            // --------------------------------------------------------------------------------------------
4256            // Transition from TypesOnly to Extensible Match filter
4257            // --------------------------------------------------------------------------------------------
4258            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4259            //     ...
4260            //     filter Filter,
4261            //     ...
4262            //
4263            // Filter ::= CHOICE {
4264            //     ...
4265            //     extensibleMatch  [9] MatchingRuleAssertion,
4266            //     ...
4267            //
4268            // Init Approx Match filter
4269            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
4270                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
4271                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
4272    
4273            // --------------------------------------------------------------------------------------------
4274            // Transition from AND to AND filter
4275            // --------------------------------------------------------------------------------------------
4276            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4277            //     ...
4278            //     filter Filter,
4279            //     ...
4280            //
4281            // Filter ::= CHOICE {
4282            //     and             [0] SET OF Filter,
4283            //     ...
4284            //
4285            // Init AND filter
4286            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
4287                LdapStatesEnum.AND_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG, new InitAndFilterAction() );
4288    
4289            // --------------------------------------------------------------------------------------------
4290            // Transition from AND to OR filter
4291            // --------------------------------------------------------------------------------------------
4292            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4293            //     ...
4294            //     filter Filter,
4295            //     ...
4296            //
4297            // Filter ::= CHOICE {
4298            //     ...
4299            //     or              [1] SET OF Filter,
4300            //     ...
4301            //
4302            // Init OR filter
4303            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
4304                LdapStatesEnum.AND_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG, new InitOrFilterAction() );
4305    
4306            // --------------------------------------------------------------------------------------------
4307            // Transition from AND to NOT filter
4308            // --------------------------------------------------------------------------------------------
4309            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4310            //     ...
4311            //     filter Filter,
4312            //     ...
4313            //
4314            // Filter ::= CHOICE {
4315            //     ...
4316            //     not             [2] SET OF Filter,
4317            //     ...
4318            //
4319            // Init NOT filter
4320            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
4321                LdapStatesEnum.AND_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG, new InitNotFilterAction() );
4322    
4323            // --------------------------------------------------------------------------------------------
4324            // Transition from AND to Equality Match filter
4325            // --------------------------------------------------------------------------------------------
4326            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4327            //     ...
4328            //     filter Filter,
4329            //     ...
4330            //
4331            // Filter ::= CHOICE {
4332            //     ...
4333            //     equalityMatch   [3] AttributeValueAssertion,
4334            //     ...
4335            //
4336            // Init NOT filter
4337            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
4338                LdapStatesEnum.AND_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
4339                new InitEqualityMatchFilterAction() );
4340    
4341            // --------------------------------------------------------------------------------------------
4342            // Transition from AND to Substrings filter
4343            // --------------------------------------------------------------------------------------------
4344            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4345            //     ...
4346            //     filter Filter,
4347            //     ...
4348            //
4349            // Filter ::= CHOICE {
4350            //     ...
4351            //     substrings     [4] SubstringFilter,
4352            //     ...
4353            //
4354            // Init Substrings filter
4355            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
4356                LdapStatesEnum.AND_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
4357                new InitSubstringsFilterAction() );
4358    
4359            // --------------------------------------------------------------------------------------------
4360            // Transition from AND to GreaterOrEqual filter
4361            // --------------------------------------------------------------------------------------------
4362            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4363            //     ...
4364            //     filter Filter,
4365            //     ...
4366            //
4367            // Filter ::= CHOICE {
4368            //     ...
4369            //     greaterOrEqual  [5] AttributeValueAssertion,
4370            //     ...
4371            //
4372            // Init Greater Or Equal filter
4373            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4374                LdapStatesEnum.AND_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE, LdapConstants.GREATER_OR_EQUAL_FILTER_TAG,
4375                new InitGreaterOrEqualFilterAction() );
4376    
4377            // --------------------------------------------------------------------------------------------
4378            // Transition from AND to LessOrEqual filter
4379            // --------------------------------------------------------------------------------------------
4380            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4381            //     ...
4382            //     filter Filter,
4383            //     ...
4384            //
4385            // Filter ::= CHOICE {
4386            //     ...
4387            //     LessOrEqual    [6] AttributeValueAssertion,
4388            //     ...
4389            //
4390            // Init Less Or Equal filter
4391            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4392                LdapStatesEnum.AND_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
4393                new InitLessOrEqualFilterAction() );
4394    
4395            // --------------------------------------------------------------------------------------------
4396            // Transition from AND to Present filter
4397            // --------------------------------------------------------------------------------------------
4398            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4399            //     ...
4400            //     filter Filter,
4401            //     ...
4402            //
4403            // Filter ::= CHOICE {
4404            //     ...
4405            //     present        [7] AttributeDescription,
4406            //     ...
4407            //
4408            // Init Approx Match filter
4409            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
4410                LdapStatesEnum.AND_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
4411                new InitPresentFilterAction() );
4412    
4413            // --------------------------------------------------------------------------------------------
4414            // Transition from AND to Approx Match filter
4415            // --------------------------------------------------------------------------------------------
4416            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4417            //     ...
4418            //     filter Filter,
4419            //     ...
4420            //
4421            // Filter ::= CHOICE {
4422            //     ...
4423            //     approxMatch     [8] AttributeValueAssertion,
4424            //     ...
4425            //
4426            // Init Approx Match filter
4427            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
4428                LdapStatesEnum.AND_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
4429                new InitApproxMatchFilterAction() );
4430    
4431            // --------------------------------------------------------------------------------------------
4432            // Transition from AND to Extensible Match filter
4433            // --------------------------------------------------------------------------------------------
4434            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4435            //     ...
4436            //     filter Filter,
4437            //     ...
4438            //
4439            // Filter ::= CHOICE {
4440            //     ...
4441            //     extensibleMatch  [9] MatchingRuleAssertion,
4442            //     ...
4443            //
4444            // Init Approx Match filter
4445            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
4446                LdapStatesEnum.AND_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG,
4447                new InitExtensibleMatchFilterAction() );
4448    
4449            // --------------------------------------------------------------------------------------------
4450            // Transition from OR to AND filter
4451            // --------------------------------------------------------------------------------------------
4452            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4453            //     ...
4454            //     filter Filter,
4455            //     ...
4456            //
4457            // Filter ::= CHOICE {
4458            //     and             [0] SET OF Filter,
4459            //     ...
4460            //
4461            // Init AND filter
4462            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
4463                LdapStatesEnum.OR_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG, new InitAndFilterAction() );
4464    
4465            // --------------------------------------------------------------------------------------------
4466            // Transition from OR to OR filter
4467            // --------------------------------------------------------------------------------------------
4468            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4469            //     ...
4470            //     filter Filter,
4471            //     ...
4472            //
4473            // Filter ::= CHOICE {
4474            //     ...
4475            //     or              [1] SET OF Filter,
4476            //     ...
4477            //
4478            // Init OR filter
4479            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
4480                LdapStatesEnum.OR_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG, new InitOrFilterAction() );
4481    
4482            // --------------------------------------------------------------------------------------------
4483            // Transition from OR to NOT filter
4484            // --------------------------------------------------------------------------------------------
4485            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4486            //     ...
4487            //     filter Filter,
4488            //     ...
4489            //
4490            // Filter ::= CHOICE {
4491            //     ...
4492            //     not             [2] SET OF Filter,
4493            //     ...
4494            //
4495            // Init NOT filter
4496            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
4497                LdapStatesEnum.OR_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG, new InitNotFilterAction() );
4498    
4499            // --------------------------------------------------------------------------------------------
4500            // Transition from OR to Equality Match filter
4501            // --------------------------------------------------------------------------------------------
4502            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4503            //     ...
4504            //     filter Filter,
4505            //     ...
4506            //
4507            // Filter ::= CHOICE {
4508            //     ...
4509            //     equalityMatch   [3] AttributeValueAssertion,
4510            //     ...
4511            //
4512            // Init NOT filter
4513            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
4514                LdapStatesEnum.OR_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
4515                new InitEqualityMatchFilterAction() );
4516    
4517            // --------------------------------------------------------------------------------------------
4518            // Transition from OR to Substrings filter
4519            // --------------------------------------------------------------------------------------------
4520            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4521            //     ...
4522            //     filter Filter,
4523            //     ...
4524            //
4525            // Filter ::= CHOICE {
4526            //     ...
4527            //     substrings     [4] SubstringFilter,
4528            //     ...
4529            //
4530            // Init Substrings filter
4531            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
4532                LdapStatesEnum.OR_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
4533                new InitSubstringsFilterAction() );
4534    
4535            // --------------------------------------------------------------------------------------------
4536            // Transition from OR to GreaterOrEqual filter
4537            // --------------------------------------------------------------------------------------------
4538            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4539            //     ...
4540            //     filter Filter,
4541            //     ...
4542            //
4543            // Filter ::= CHOICE {
4544            //     ...
4545            //     greaterOrEqual  [5] AttributeValueAssertion,
4546            //     ...
4547            //
4548            // Init Greater Or Equal filter
4549            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4550                LdapStatesEnum.OR_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE, LdapConstants.GREATER_OR_EQUAL_FILTER_TAG,
4551                new InitGreaterOrEqualFilterAction() );
4552    
4553            // --------------------------------------------------------------------------------------------
4554            // Transition from OR to LessOrEqual filter
4555            // --------------------------------------------------------------------------------------------
4556            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4557            //     ...
4558            //     filter Filter,
4559            //     ...
4560            //
4561            // Filter ::= CHOICE {
4562            //     ...
4563            //     LessOrEqual    [6] AttributeValueAssertion,
4564            //     ...
4565            //
4566            // Init Less Or Equal filter
4567            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4568                LdapStatesEnum.OR_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
4569                new InitLessOrEqualFilterAction() );
4570    
4571            // --------------------------------------------------------------------------------------------
4572            // Transition from OR to Present filter
4573            // --------------------------------------------------------------------------------------------
4574            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4575            //     ...
4576            //     filter Filter,
4577            //     ...
4578            //
4579            // Filter ::= CHOICE {
4580            //     ...
4581            //     present        [7] AttributeDescription,
4582            //     ...
4583            //
4584            // Init Approx Match filter
4585            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
4586                LdapStatesEnum.OR_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
4587                new InitPresentFilterAction() );
4588    
4589            // --------------------------------------------------------------------------------------------
4590            // Transition from OR to Approx Match filter
4591            // --------------------------------------------------------------------------------------------
4592            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4593            //     ...
4594            //     filter Filter,
4595            //     ...
4596            //
4597            // Filter ::= CHOICE {
4598            //     ...
4599            //     approxMatch     [8] AttributeValueAssertion,
4600            //     ...
4601            //
4602            // Init Approx Match filter
4603            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
4604                LdapStatesEnum.OR_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
4605                new InitApproxMatchFilterAction() );
4606    
4607            // --------------------------------------------------------------------------------------------
4608            // Transition from OR to Extensible Match filter
4609            // --------------------------------------------------------------------------------------------
4610            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4611            //     ...
4612            //     filter Filter,
4613            //     ...
4614            //
4615            // Filter ::= CHOICE {
4616            //     ...
4617            //     extensibleMatch  [9] MatchingRuleAssertion,
4618            //     ...
4619            //
4620            // Init Approx Match filter
4621            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
4622                LdapStatesEnum.OR_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG,
4623                new InitExtensibleMatchFilterAction() );
4624    
4625            // --------------------------------------------------------------------------------------------
4626            // Transition from NOT to AND filter
4627            // --------------------------------------------------------------------------------------------
4628            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4629            //     ...
4630            //     filter Filter,
4631            //     ...
4632            //
4633            // Filter ::= CHOICE {
4634            //     and             [0] SET OF Filter,
4635            //     ...
4636            //
4637            // Init AND filter
4638            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
4639                LdapStatesEnum.NOT_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG, new InitAndFilterAction() );
4640    
4641            // --------------------------------------------------------------------------------------------
4642            // Transition from NOT to OR filter
4643            // --------------------------------------------------------------------------------------------
4644            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4645            //     ...
4646            //     filter Filter,
4647            //     ...
4648            //
4649            // Filter ::= CHOICE {
4650            //     ...
4651            //     or              [1] SET OF Filter,
4652            //     ...
4653            //
4654            // Init OR filter
4655            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
4656                LdapStatesEnum.NOT_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG, new InitOrFilterAction() );
4657    
4658            // --------------------------------------------------------------------------------------------
4659            // Transition from NOT to NOT filter
4660            // --------------------------------------------------------------------------------------------
4661            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4662            //     ...
4663            //     filter Filter,
4664            //     ...
4665            //
4666            // Filter ::= CHOICE {
4667            //     ...
4668            //     not             [2] SET OF Filter,
4669            //     ...
4670            //
4671            // Init NOT filter
4672            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
4673                LdapStatesEnum.NOT_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG, new InitNotFilterAction() );
4674    
4675            // --------------------------------------------------------------------------------------------
4676            // Transition from NOT to Equality Match filter
4677            // --------------------------------------------------------------------------------------------
4678            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4679            //     ...
4680            //     filter Filter,
4681            //     ...
4682            //
4683            // Filter ::= CHOICE {
4684            //     ...
4685            //     equalityMatch   [3] AttributeValueAssertion,
4686            //     ...
4687            //
4688            // Init NOT filter
4689            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
4690                LdapStatesEnum.NOT_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
4691                new InitEqualityMatchFilterAction() );
4692    
4693            // --------------------------------------------------------------------------------------------
4694            // Transition from NOT to Substrings filter
4695            // --------------------------------------------------------------------------------------------
4696            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4697            //     ...
4698            //     filter Filter,
4699            //     ...
4700            //
4701            // Filter ::= CHOICE {
4702            //     ...
4703            //     substrings     [4] SubstringFilter,
4704            //     ...
4705            //
4706            // Init Substrings filter
4707            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
4708                LdapStatesEnum.NOT_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
4709                new InitSubstringsFilterAction() );
4710    
4711            // --------------------------------------------------------------------------------------------
4712            // Transition from NOT to GreaterOrEqual filter
4713            // --------------------------------------------------------------------------------------------
4714            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4715            //     ...
4716            //     filter Filter,
4717            //     ...
4718            //
4719            // Filter ::= CHOICE {
4720            //     ...
4721            //     greaterOrEqual  [5] AttributeValueAssertion,
4722            //     ...
4723            //
4724            // Init Greater Or Equal filter
4725            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4726                LdapStatesEnum.NOT_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE, LdapConstants.GREATER_OR_EQUAL_FILTER_TAG,
4727                new InitGreaterOrEqualFilterAction() );
4728    
4729            // --------------------------------------------------------------------------------------------
4730            // Transition from NOT to LessOrEqual filter
4731            // --------------------------------------------------------------------------------------------
4732            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4733            //     ...
4734            //     filter Filter,
4735            //     ...
4736            //
4737            // Filter ::= CHOICE {
4738            //     ...
4739            //     LessOrEqual    [6] AttributeValueAssertion,
4740            //     ...
4741            //
4742            // Init Less Or Equal filter
4743            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4744                LdapStatesEnum.NOT_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
4745                new InitLessOrEqualFilterAction() );
4746    
4747            // --------------------------------------------------------------------------------------------
4748            // Transition from NOT to Present filter
4749            // --------------------------------------------------------------------------------------------
4750            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4751            //     ...
4752            //     filter Filter,
4753            //     ...
4754            //
4755            // Filter ::= CHOICE {
4756            //     ...
4757            //     present        [7] AttributeDescription,
4758            //     ...
4759            //
4760            // Init present filter
4761            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
4762                LdapStatesEnum.NOT_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
4763                new InitPresentFilterAction() );
4764    
4765            // --------------------------------------------------------------------------------------------
4766            // Transition from NOT to Approx Match filter
4767            // --------------------------------------------------------------------------------------------
4768            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4769            //     ...
4770            //     filter Filter,
4771            //     ...
4772            //
4773            // Filter ::= CHOICE {
4774            //     ...
4775            //     approxMatch     [8] AttributeValueAssertion,
4776            //     ...
4777            //
4778            // Init Approx Match filter
4779            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
4780                LdapStatesEnum.NOT_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
4781                new InitApproxMatchFilterAction() );
4782    
4783            // --------------------------------------------------------------------------------------------
4784            // Transition from NOT to Extensible Match filter
4785            // --------------------------------------------------------------------------------------------
4786            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4787            //     ...
4788            //     filter Filter,
4789            //     ...
4790            //
4791            // Filter ::= CHOICE {
4792            //     ...
4793            //     extensibleMatch  [9] MatchingRuleAssertion,
4794            //     ...
4795            //
4796            // Init extensible match filter
4797            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
4798                LdapStatesEnum.NOT_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG,
4799                new InitExtensibleMatchFilterAction() );
4800    
4801            // --------------------------------------------------------------------------------------------
4802            // Transition from Equality match to Attribute Desc Filter
4803            // --------------------------------------------------------------------------------------------
4804            // Filter ::= CHOICE {
4805            //     ...
4806            //     equalityMatch  [3] AttributeValueAssertion,
4807            //     ...
4808            //
4809            // AttributeValueAssertion ::= SEQUENCE {
4810            //     attributeDesc   AttributeDescription,
4811            //     ...
4812            //
4813            // Init Attribute Desc filter
4814            super.transitions[LdapStatesEnum.EQUALITY_MATCH_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
4815                LdapStatesEnum.EQUALITY_MATCH_STATE, LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE,
4816                UniversalTag.OCTET_STRING_TAG, new InitAttributeDescFilterAction() );
4817    
4818            // --------------------------------------------------------------------------------------------
4819            // Transition from Attribute Desc Filter to Assertion Value Filter
4820            // --------------------------------------------------------------------------------------------
4821            // Filter ::= CHOICE {
4822            //     ...
4823            //     equalityMatch  [3] AttributeValueAssertion,
4824            //     ...
4825            //
4826            // AttributeValueAssertion ::= SEQUENCE {
4827            //     ...
4828            //     assertionValue   AssertionValue }
4829            //
4830            // Init Assertion Value filter
4831            super.transitions[LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
4832                LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE, LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE,
4833                UniversalTag.OCTET_STRING_TAG, new InitAssertionValueFilterAction() );
4834    
4835            // --------------------------------------------------------------------------------------------
4836            // Transition from Assertion Value Filter to AND filter
4837            // --------------------------------------------------------------------------------------------
4838            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4839            //     ...
4840            //     filter Filter,
4841            //     ...
4842            //
4843            // Filter ::= CHOICE {
4844            //     and             [0] SET OF Filter,
4845            //     ...
4846            //
4847            // Init AND filter
4848            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
4849                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
4850                new InitAndFilterAction() );
4851    
4852            // --------------------------------------------------------------------------------------------
4853            // Transition from Assertion Value Filter to OR filter
4854            // --------------------------------------------------------------------------------------------
4855            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4856            //     ...
4857            //     filter Filter,
4858            //     ...
4859            //
4860            // Filter ::= CHOICE {
4861            //     ...
4862            //     or              [1] SET OF Filter,
4863            //     ...
4864            //
4865            // Init OR filter
4866            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
4867                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
4868                new InitOrFilterAction() );
4869    
4870            // --------------------------------------------------------------------------------------------
4871            // Transition from Assertion Value Filter to NOT filter
4872            // --------------------------------------------------------------------------------------------
4873            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4874            //     ...
4875            //     filter Filter,
4876            //     ...
4877            //
4878            // Filter ::= CHOICE {
4879            //     ...
4880            //     not             [2] SET OF Filter,
4881            //     ...
4882            //
4883            // Init NOT filter
4884            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
4885                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
4886                new InitNotFilterAction() );
4887    
4888            // --------------------------------------------------------------------------------------------
4889            // Transition from Assertion Value Filter to Equality Match filter
4890            // --------------------------------------------------------------------------------------------
4891            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4892            //     ...
4893            //     filter Filter,
4894            //     ...
4895            //
4896            // Filter ::= CHOICE {
4897            //     ...
4898            //     equalityMatch   [3] AttributeValueAssertion,
4899            //     ...
4900            //
4901            // Init NOT filter
4902            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = 
4903                new GrammarTransition(
4904                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE,
4905                LdapConstants.EQUALITY_MATCH_FILTER_TAG, new InitEqualityMatchFilterAction() );
4906    
4907            // --------------------------------------------------------------------------------------------
4908            // Transition from Assertion Value Filter to Substrings filter
4909            // --------------------------------------------------------------------------------------------
4910            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4911            //     ...
4912            //     filter Filter,
4913            //     ...
4914            //
4915            // Filter ::= CHOICE {
4916            //     ...
4917            //     substrings     [4] SubstringFilter,
4918            //     ...
4919            //
4920            // Init Substrings filter
4921            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
4922                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE,
4923                LdapConstants.SUBSTRINGS_FILTER_TAG, new InitSubstringsFilterAction() );
4924    
4925            // --------------------------------------------------------------------------------------------
4926            // Transition from Assertion Value Filter to GreaterOrEqual filter
4927            // --------------------------------------------------------------------------------------------
4928            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4929            //     ...
4930            //     filter Filter,
4931            //     ...
4932            //
4933            // Filter ::= CHOICE {
4934            //     ...
4935            //     greaterOrEqual  [5] AttributeValueAssertion,
4936            //     ...
4937            //
4938            // Init Greater Or Equal filter
4939            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = 
4940                new GrammarTransition(
4941                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
4942                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
4943    
4944            // --------------------------------------------------------------------------------------------
4945            // Transition from Assertion Value Filter to LessOrEqual filter
4946            // --------------------------------------------------------------------------------------------
4947            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4948            //     ...
4949            //     filter Filter,
4950            //     ...
4951            //
4952            // Filter ::= CHOICE {
4953            //     ...
4954            //     LessOrEqual    [6] AttributeValueAssertion,
4955            //     ...
4956            //
4957            // Init Less Or Equal filter
4958            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = 
4959                new GrammarTransition(
4960                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE,
4961                LdapConstants.LESS_OR_EQUAL_FILTER_TAG, new InitLessOrEqualFilterAction() );
4962    
4963            // --------------------------------------------------------------------------------------------
4964            // Transition from Assertion Value Filter to Present filter
4965            // --------------------------------------------------------------------------------------------
4966            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4967            //     ...
4968            //     filter Filter,
4969            //     ...
4970            //
4971            // Filter ::= CHOICE {
4972            //     ...
4973            //     present        [7] AttributeDescription,
4974            //     ...
4975            //
4976            // Init present filter
4977            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
4978                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.PRESENT_STATE,
4979                LdapConstants.PRESENT_FILTER_TAG, new InitPresentFilterAction() );
4980    
4981            // --------------------------------------------------------------------------------------------
4982            // Transition from Assertion Value Filter to Approx Match filter
4983            // --------------------------------------------------------------------------------------------
4984            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4985            //     ...
4986            //     filter Filter,
4987            //     ...
4988            //
4989            // Filter ::= CHOICE {
4990            //     ...
4991            //     approxMatch     [8] AttributeValueAssertion,
4992            //     ...
4993            //
4994            // Init Approx Match filter
4995            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = 
4996                new GrammarTransition(
4997                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.APPROX_MATCH_STATE,
4998                LdapConstants.APPROX_MATCH_FILTER_TAG, new InitApproxMatchFilterAction() );
4999    
5000            // --------------------------------------------------------------------------------------------
5001            // Transition from Assertion Value Filter to Extensible Match filter
5002            // --------------------------------------------------------------------------------------------
5003            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5004            //     ...
5005            //     filter Filter,
5006            //     ...
5007            //
5008            // Filter ::= CHOICE {
5009            //     ...
5010            //     extensibleMatch  [9] MatchingRuleAssertion,
5011            //     ...
5012            //
5013            // Init Assertion Value Filter filter
5014            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = 
5015                new GrammarTransition(
5016                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
5017                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
5018    
5019            // --------------------------------------------------------------------------------------------
5020            // Transition from Assertion Value Filter to Attribute Description List
5021            // --------------------------------------------------------------------------------------------
5022            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5023            //     ...
5024            //     filter      Filter,
5025            //     attributes  AttributeDescriptionList }
5026            //
5027            // AttributeDescriptionList ::= SEQUENCE OF
5028            //     AttributeDescription
5029            //
5030            // Init attribute description list
5031            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
5032                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE,
5033                UniversalTag.SEQUENCE_TAG, new InitAttributeDescListAction() );
5034    
5035            // --------------------------------------------------------------------------------------------
5036            // Transition from Attribute Description List to AttributeDescription
5037            // --------------------------------------------------------------------------------------------
5038            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5039            //     ...
5040            //     filter      Filter,
5041            //     attributes  AttributeDescriptionList }
5042            //
5043            // AttributeDescriptionList ::= SEQUENCE OF
5044            //     AttributeDescription
5045            //
5046            // Store attribute description
5047            super.transitions[LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
5048                LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE,
5049                UniversalTag.OCTET_STRING_TAG, new AttributeDescAction() );
5050    
5051            // --------------------------------------------------------------------------------------------
5052            // Transition from Attribute Description List to Controls
5053            // --------------------------------------------------------------------------------------------
5054            //         searchRequest   SearchRequest,
5055            //         ... },
5056            //     controls       [0] Controls OPTIONAL }
5057            //
5058            // Empty attribute description list, with controls
5059            super.transitions[LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
5060                LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
5061                new ControlsInitAction() );
5062    
5063            // --------------------------------------------------------------------------------------------
5064            // Transition from Attribute Description to AttributeDescription
5065            // --------------------------------------------------------------------------------------------
5066            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5067            //     ...
5068            //     filter      Filter,
5069            //     attributes  AttributeDescriptionList }
5070            //
5071            // AttributeDescriptionList ::= SEQUENCE OF
5072            //     AttributeDescription
5073            //
5074            // Store attribute description
5075            super.transitions[LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
5076                LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE,
5077                UniversalTag.OCTET_STRING_TAG, new AttributeDescAction() );
5078    
5079            // --------------------------------------------------------------------------------------------
5080            // transition from Attribute Description to Controls.
5081            // --------------------------------------------------------------------------------------------
5082            //         searchRequest   SearchRequest,
5083            //         ... },
5084            //     controls       [0] Controls OPTIONAL }
5085            //
5086            super.transitions[LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
5087                LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
5088                new ControlsInitAction() );
5089    
5090            // --------------------------------------------------------------------------------------------
5091            // Transition from Greater Or Equal to Attribute Desc Filter
5092            // --------------------------------------------------------------------------------------------
5093            // Filter ::= CHOICE {
5094            //     ...
5095            //     greaterOrEqual  [5] AttributeValueAssertion,
5096            //     ...
5097            //
5098            // AttributeValueAssertion ::= SEQUENCE {
5099            //     attributeDesc   AttributeDescription,
5100            //     ...
5101            //
5102            // Init Attribute Desc filter
5103            super.transitions[LdapStatesEnum.GREATER_OR_EQUAL_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
5104                LdapStatesEnum.GREATER_OR_EQUAL_STATE, LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE,
5105                UniversalTag.OCTET_STRING_TAG, new InitAttributeDescFilterAction() );
5106    
5107            // --------------------------------------------------------------------------------------------
5108            // Transition from Less Or Equal to Attribute Desc Filter
5109            // --------------------------------------------------------------------------------------------
5110            // Filter ::= CHOICE {
5111            //     ...
5112            //     lessOrEqual  [6] AttributeValueAssertion,
5113            //     ...
5114            //
5115            // AttributeValueAssertion ::= SEQUENCE {
5116            //     attributeDesc   AttributeDescription,
5117            //     ...
5118            //
5119            // Init Attribute Desc filter
5120            super.transitions[LdapStatesEnum.LESS_OR_EQUAL_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
5121                LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE,
5122                UniversalTag.OCTET_STRING_TAG, new InitAttributeDescFilterAction() );
5123    
5124            // --------------------------------------------------------------------------------------------
5125            // Transition from Substrings to typeSubstring
5126            // --------------------------------------------------------------------------------------------
5127            // Filter ::= CHOICE {
5128            //     ...
5129            //     substrings  [4] SubstringFilter,
5130            //     ...
5131            //
5132            // SubstringFilter ::= SEQUENCE {
5133            //     type   AttributeDescription,
5134            //     ...
5135            //
5136            // Init substring type
5137            super.transitions[LdapStatesEnum.SUBSTRING_FILTER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
5138                LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapStatesEnum.TYPE_SUBSTRING_STATE, UniversalTag.OCTET_STRING_TAG,
5139                new GrammarAction( "Store substring filter type" )
5140                {
5141                    public void action( IAsn1Container container ) throws DecoderException
5142                    {
5143                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
5144                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
5145                        SearchRequestCodec searchRequest = ldapMessage.getSearchRequest();
5146    
5147                        TLV tlv = ldapMessageContainer.getCurrentTLV();
5148    
5149                        // Store the value.
5150                        SubstringFilter substringFilter = ( SubstringFilter ) searchRequest.getTerminalFilter();
5151    
5152                        if ( tlv.getLength() == 0 )
5153                        {
5154                            log.error( "The attribute description should not be null" );
5155                            throw new DecoderException( "The attribute description should not be null" );
5156                        }
5157                        else
5158                        {
5159                            String type = StringTools.getType( tlv.getValue().getData() );
5160                            substringFilter.setType( type );
5161    
5162                            // We now have to get back to the nearest filter which
5163                            // is not terminal.
5164                            searchRequest.setTerminalFilter( substringFilter );
5165                        }
5166                    }
5167                } );
5168    
5169            // --------------------------------------------------------------------------------------------
5170            // Transition from typeSubstring to substrings
5171            // --------------------------------------------------------------------------------------------
5172            // Filter ::= CHOICE {
5173            //     ...
5174            //     substrings  [4] SubstringFilter,
5175            //     ...
5176            //
5177            // SubstringFilter ::= SEQUENCE {
5178            //     ...
5179            //     substrings SEQUENCE OF CHOICE {
5180            //     ...
5181            //
5182            // Init substring type
5183            super.transitions[LdapStatesEnum.TYPE_SUBSTRING_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
5184                LdapStatesEnum.TYPE_SUBSTRING_STATE, LdapStatesEnum.SUBSTRINGS_STATE, UniversalTag.SEQUENCE_TAG,
5185                new GrammarAction( "Substring Filter substringsSequence " )
5186                {
5187                    public void action( IAsn1Container container ) throws DecoderException
5188                    {
5189                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
5190    
5191                        TLV tlv = ldapMessageContainer.getCurrentTLV();
5192    
5193                        if ( tlv.getLength() == 0 )
5194                        {
5195                            log.error( "The substrings sequence is empty" );
5196                            throw new DecoderException( "The substring sequence is empty" );
5197                        }
5198                    }
5199                } );
5200    
5201            // --------------------------------------------------------------------------------------------
5202            // Transition from substrings to Initial
5203            // --------------------------------------------------------------------------------------------
5204            // SubstringFilter ::= SEQUENCE {
5205            //     ...
5206            //     substrings SEQUENCE OF CHOICE {
5207            //         initial  [0] LDAPSTRING,
5208            //         ...
5209            //
5210            // Store initial value
5211            super.transitions[LdapStatesEnum.SUBSTRINGS_STATE][LdapConstants.SUBSTRINGS_FILTER_INITIAL_TAG] = new GrammarTransition(
5212                LdapStatesEnum.SUBSTRINGS_STATE, LdapStatesEnum.INITIAL_STATE, LdapConstants.SUBSTRINGS_FILTER_INITIAL_TAG,
5213                new GrammarAction( "Store substring filter initial Value" )
5214                {
5215                    public void action( IAsn1Container container ) throws DecoderException
5216                    {
5217                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
5218                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
5219                        SearchRequestCodec searchRequest = ldapMessage.getSearchRequest();
5220    
5221                        TLV tlv = ldapMessageContainer.getCurrentTLV();
5222    
5223                        // Store the value.
5224                        SubstringFilter substringFilter = ( SubstringFilter ) searchRequest.getTerminalFilter();
5225    
5226                        if ( tlv.getLength() == 0 )
5227                        {
5228                            log.error( "The substring initial filter is empty" );
5229                            throw new DecoderException( "The substring initial filter is empty" );
5230                        }
5231    
5232                        substringFilter.setInitialSubstrings( StringTools.utf8ToString( tlv.getValue().getData() ) );
5233    
5234                        // We now have to get back to the nearest filter which is
5235                        // not terminal.
5236                        searchRequest.unstackFilters( container );
5237                    }
5238                } );
5239    
5240            // --------------------------------------------------------------------------------------------
5241            // Transition from substrings to any
5242            // --------------------------------------------------------------------------------------------
5243            // SubstringFilter ::= SEQUENCE {
5244            //     ...
5245            //     substrings SEQUENCE OF CHOICE {
5246            //         ...
5247            //         any  [1] LDAPSTRING,
5248            //         ...
5249            //
5250            // Store substring any type
5251            super.transitions[LdapStatesEnum.SUBSTRINGS_STATE][LdapConstants.SUBSTRINGS_FILTER_ANY_TAG] = new GrammarTransition(
5252                LdapStatesEnum.SUBSTRINGS_STATE, LdapStatesEnum.ANY_STATE, LdapConstants.SUBSTRINGS_FILTER_ANY_TAG,
5253                new StoreAnyAction() );
5254    
5255            // --------------------------------------------------------------------------------------------
5256            // Transition from substrings to final
5257            // --------------------------------------------------------------------------------------------
5258            // SubstringFilter ::= SEQUENCE {
5259            //     ...
5260            //     substrings SEQUENCE OF CHOICE {
5261            //         ...
5262            //         final  [2] LDAPSTRING }
5263            //
5264            // Store substring final type
5265            super.transitions[LdapStatesEnum.SUBSTRINGS_STATE][LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG] = new GrammarTransition(
5266                LdapStatesEnum.SUBSTRINGS_STATE, LdapStatesEnum.FINAL_STATE, LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG,
5267                new StoreFinalAction() );
5268    
5269            // --------------------------------------------------------------------------------------------
5270            // Transition from initial to any
5271            // --------------------------------------------------------------------------------------------
5272            // SubstringFilter ::= SEQUENCE {
5273            //     ...
5274            //     substrings SEQUENCE OF CHOICE {
5275            //         ...
5276            //         any  [1] LDAPSTRING,
5277            //         ...
5278            //
5279            // Store substring any type
5280            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.SUBSTRINGS_FILTER_ANY_TAG] = new GrammarTransition(
5281                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.ANY_STATE, LdapConstants.SUBSTRINGS_FILTER_ANY_TAG,
5282                new StoreAnyAction() );
5283    
5284            // --------------------------------------------------------------------------------------------
5285            // Transition from initial to final
5286            // --------------------------------------------------------------------------------------------
5287            // SubstringFilter ::= SEQUENCE {
5288            //     ...
5289            //     substrings SEQUENCE OF CHOICE {
5290            //         ...
5291            //         final  [2] LDAPSTRING }
5292            //
5293            // Store substring final type
5294            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG] = new GrammarTransition(
5295                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.FINAL_STATE, LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG,
5296                new StoreFinalAction() );
5297    
5298            // --------------------------------------------------------------------------------------------
5299            // Transition from initial to Attribute Description List
5300            // --------------------------------------------------------------------------------------------
5301            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5302            //     ...
5303            //     filter      Filter,
5304            //     attributes  AttributeDescriptionList }
5305            //
5306            // AttributeDescriptionList ::= SEQUENCE OF
5307            //     AttributeDescription
5308            //
5309            // Init attribute description list
5310            super.transitions[LdapStatesEnum.INITIAL_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
5311                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, UniversalTag.SEQUENCE_TAG,
5312                new InitAttributeDescListAction() );
5313    
5314            // --------------------------------------------------------------------------------------------
5315            // Transition from initial to AND filter
5316            // --------------------------------------------------------------------------------------------
5317            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5318            //     ...
5319            //     filter Filter,
5320            //     ...
5321            //
5322            // Filter ::= CHOICE {
5323            //     and             [0] SET OF Filter,
5324            //     ...
5325            //
5326            // Init AND filter
5327            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
5328                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
5329                new InitAndFilterAction() );
5330    
5331            // --------------------------------------------------------------------------------------------
5332            // Transition from initial to OR filter
5333            // --------------------------------------------------------------------------------------------
5334            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5335            //     ...
5336            //     filter Filter,
5337            //     ...
5338            //
5339            // Filter ::= CHOICE {
5340            //     ...
5341            //     or              [1] SET OF Filter,
5342            //     ...
5343            //
5344            // Init OR filter
5345            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
5346                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
5347                new InitOrFilterAction() );
5348    
5349            // --------------------------------------------------------------------------------------------
5350            // Transition from initial to NOT filter
5351            // --------------------------------------------------------------------------------------------
5352            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5353            //     ...
5354            //     filter Filter,
5355            //     ...
5356            //
5357            // Filter ::= CHOICE {
5358            //     ...
5359            //     not             [2] SET OF Filter,
5360            //     ...
5361            //
5362            // Init NOT filter
5363            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
5364                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
5365                new InitNotFilterAction() );
5366    
5367            // --------------------------------------------------------------------------------------------
5368            // Transition from initial to Equality Match filter
5369            // --------------------------------------------------------------------------------------------
5370            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5371            //     ...
5372            //     filter Filter,
5373            //     ...
5374            //
5375            // Filter ::= CHOICE {
5376            //     ...
5377            //     equalityMatch   [3] AttributeValueAssertion,
5378            //     ...
5379            //
5380            // Init NOT filter
5381            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
5382                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
5383                new InitEqualityMatchFilterAction() );
5384    
5385            // --------------------------------------------------------------------------------------------
5386            // Transition from initial to Substrings filter
5387            // --------------------------------------------------------------------------------------------
5388            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5389            //     ...
5390            //     filter Filter,
5391            //     ...
5392            //
5393            // Filter ::= CHOICE {
5394            //     ...
5395            //     substrings     [4] SubstringFilter,
5396            //     ...
5397            //
5398            // Init Substrings filter
5399            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
5400                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
5401                new InitSubstringsFilterAction() );
5402    
5403            // --------------------------------------------------------------------------------------------
5404            // Transition from initial to GreaterOrEqual filter
5405            // --------------------------------------------------------------------------------------------
5406            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5407            //     ...
5408            //     filter Filter,
5409            //     ...
5410            //
5411            // Filter ::= CHOICE {
5412            //     ...
5413            //     greaterOrEqual  [5] AttributeValueAssertion,
5414            //     ...
5415            //
5416            // Init Greater Or Equal filter
5417            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5418                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
5419                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
5420    
5421            // --------------------------------------------------------------------------------------------
5422            // Transition from initial to LessOrEqual filter
5423            // --------------------------------------------------------------------------------------------
5424            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5425            //     ...
5426            //     filter Filter,
5427            //     ...
5428            //
5429            // Filter ::= CHOICE {
5430            //     ...
5431            //     LessOrEqual    [6] AttributeValueAssertion,
5432            //     ...
5433            //
5434            // Init Less Or Equal filter
5435            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5436                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
5437                new InitLessOrEqualFilterAction() );
5438    
5439            // --------------------------------------------------------------------------------------------
5440            // Transition from initial to Present filter
5441            // --------------------------------------------------------------------------------------------
5442            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5443            //     ...
5444            //     filter Filter,
5445            //     ...
5446            //
5447            // Filter ::= CHOICE {
5448            //     ...
5449            //     present        [7] AttributeDescription,
5450            //     ...
5451            //
5452            // Init present filter
5453            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
5454                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
5455                new InitPresentFilterAction() );
5456    
5457            // --------------------------------------------------------------------------------------------
5458            // Transition from initial to Approx Match filter
5459            // --------------------------------------------------------------------------------------------
5460            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5461            //     ...
5462            //     filter Filter,
5463            //     ...
5464            //
5465            // Filter ::= CHOICE {
5466            //     ...
5467            //     approxMatch     [8] AttributeValueAssertion,
5468            //     ...
5469            //
5470            // Init Approx Match filter
5471            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
5472                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
5473                new InitApproxMatchFilterAction() );
5474    
5475            // --------------------------------------------------------------------------------------------
5476            // Transition from initial to Extensible Match filter
5477            // --------------------------------------------------------------------------------------------
5478            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5479            //     ...
5480            //     filter Filter,
5481            //     ...
5482            //
5483            // Filter ::= CHOICE {
5484            //     ...
5485            //     extensibleMatch  [9] MatchingRuleAssertion,
5486            //     ...
5487            //
5488            // Init Assertion Value Filter filter
5489            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
5490                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
5491                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
5492    
5493            // --------------------------------------------------------------------------------------------
5494            // Transition from any to final
5495            // --------------------------------------------------------------------------------------------
5496            // SubstringFilter ::= SEQUENCE {
5497            //     ...
5498            //     substrings SEQUENCE OF CHOICE {
5499            //         ...
5500            //         final  [2] LDAPSTRING }
5501            //
5502            // Store substring final type
5503            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG] = new GrammarTransition(
5504                LdapStatesEnum.ANY_STATE, LdapStatesEnum.FINAL_STATE, LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG,
5505                new StoreFinalAction() );
5506    
5507            // --------------------------------------------------------------------------------------------
5508            // Transition from any to any
5509            // --------------------------------------------------------------------------------------------
5510            // SubstringFilter ::= SEQUENCE {
5511            //     ...
5512            //     substrings SEQUENCE OF CHOICE {
5513            //         ...
5514            //         any  [1] LDAPSTRING 
5515            //         ...
5516            //
5517            // Store substring any type
5518            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.SUBSTRINGS_FILTER_ANY_TAG] = new GrammarTransition(
5519                LdapStatesEnum.ANY_STATE, LdapStatesEnum.ANY_STATE, LdapConstants.SUBSTRINGS_FILTER_ANY_TAG,
5520                new StoreAnyAction() );
5521    
5522            // --------------------------------------------------------------------------------------------
5523            // Transition from any to Attribute Description List
5524            // --------------------------------------------------------------------------------------------
5525            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5526            //     ...
5527            //     filter      Filter,
5528            //     attributes  AttributeDescriptionList }
5529            //
5530            // AttributeDescriptionList ::= SEQUENCE OF
5531            //     AttributeDescription
5532            //
5533            // Init attribute description list
5534            super.transitions[LdapStatesEnum.ANY_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
5535                LdapStatesEnum.ANY_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, UniversalTag.SEQUENCE_TAG,
5536                new InitAttributeDescListAction() );
5537    
5538            // --------------------------------------------------------------------------------------------
5539            // Transition from any to AND filter
5540            // --------------------------------------------------------------------------------------------
5541            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5542            //     ...
5543            //     filter Filter,
5544            //     ...
5545            //
5546            // Filter ::= CHOICE {
5547            //     and             [0] SET OF Filter,
5548            //     ...
5549            //
5550            // Init AND filter
5551            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
5552                LdapStatesEnum.ANY_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG, new InitAndFilterAction() );
5553    
5554            // --------------------------------------------------------------------------------------------
5555            // Transition from any to OR filter
5556            // --------------------------------------------------------------------------------------------
5557            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5558            //     ...
5559            //     filter Filter,
5560            //     ...
5561            //
5562            // Filter ::= CHOICE {
5563            //     ...
5564            //     or              [1] SET OF Filter,
5565            //     ...
5566            //
5567            // Init OR filter
5568            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
5569                LdapStatesEnum.ANY_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG, new InitOrFilterAction() );
5570    
5571            // --------------------------------------------------------------------------------------------
5572            // Transition from any to NOT filter
5573            // --------------------------------------------------------------------------------------------
5574            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5575            //     ...
5576            //     filter Filter,
5577            //     ...
5578            //
5579            // Filter ::= CHOICE {
5580            //     ...
5581            //     not             [2] SET OF Filter,
5582            //     ...
5583            //
5584            // Init NOT filter
5585            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
5586                LdapStatesEnum.ANY_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG, new InitNotFilterAction() );
5587    
5588            // --------------------------------------------------------------------------------------------
5589            // Transition from any to Equality Match filter
5590            // --------------------------------------------------------------------------------------------
5591            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5592            //     ...
5593            //     filter Filter,
5594            //     ...
5595            //
5596            // Filter ::= CHOICE {
5597            //     ...
5598            //     equalityMatch   [3] AttributeValueAssertion,
5599            //     ...
5600            //
5601            // Init NOT filter
5602            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
5603                LdapStatesEnum.ANY_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
5604                new InitEqualityMatchFilterAction() );
5605    
5606            // --------------------------------------------------------------------------------------------
5607            // Transition from any to Substrings filter
5608            // --------------------------------------------------------------------------------------------
5609            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5610            //     ...
5611            //     filter Filter,
5612            //     ...
5613            //
5614            // Filter ::= CHOICE {
5615            //     ...
5616            //     substrings     [4] SubstringFilter,
5617            //     ...
5618            //
5619            // Init Substrings filter
5620            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
5621                LdapStatesEnum.ANY_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
5622                new InitSubstringsFilterAction() );
5623    
5624            // --------------------------------------------------------------------------------------------
5625            // Transition from any to GreaterOrEqual filter
5626            // --------------------------------------------------------------------------------------------
5627            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5628            //     ...
5629            //     filter Filter,
5630            //     ...
5631            //
5632            // Filter ::= CHOICE {
5633            //     ...
5634            //     greaterOrEqual  [5] AttributeValueAssertion,
5635            //     ...
5636            //
5637            // Init Greater Or Equal filter
5638            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5639                LdapStatesEnum.ANY_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE, LdapConstants.GREATER_OR_EQUAL_FILTER_TAG,
5640                new InitGreaterOrEqualFilterAction() );
5641    
5642            // --------------------------------------------------------------------------------------------
5643            // Transition from any to LessOrEqual filter
5644            // --------------------------------------------------------------------------------------------
5645            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5646            //     ...
5647            //     filter Filter,
5648            //     ...
5649            //
5650            // Filter ::= CHOICE {
5651            //     ...
5652            //     LessOrEqual    [6] AttributeValueAssertion,
5653            //     ...
5654            //
5655            // Init Less Or Equal filter
5656            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5657                LdapStatesEnum.ANY_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
5658                new InitLessOrEqualFilterAction() );
5659    
5660            // --------------------------------------------------------------------------------------------
5661            // Transition from any to Present filter
5662            // --------------------------------------------------------------------------------------------
5663            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5664            //     ...
5665            //     filter Filter,
5666            //     ...
5667            //
5668            // Filter ::= CHOICE {
5669            //     ...
5670            //     present        [7] AttributeDescription,
5671            //     ...
5672            //
5673            // Init present filter
5674            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
5675                LdapStatesEnum.ANY_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
5676                new InitPresentFilterAction() );
5677    
5678            // --------------------------------------------------------------------------------------------
5679            // Transition from any to Approx Match filter
5680            // --------------------------------------------------------------------------------------------
5681            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5682            //     ...
5683            //     filter Filter,
5684            //     ...
5685            //
5686            // Filter ::= CHOICE {
5687            //     ...
5688            //     approxMatch     [8] AttributeValueAssertion,
5689            //     ...
5690            //
5691            // Init Approx Match filter
5692            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
5693                LdapStatesEnum.ANY_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
5694                new InitApproxMatchFilterAction() );
5695    
5696            // --------------------------------------------------------------------------------------------
5697            // Transition from any to Extensible Match filter
5698            // --------------------------------------------------------------------------------------------
5699            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5700            //     ...
5701            //     filter Filter,
5702            //     ...
5703            //
5704            // Filter ::= CHOICE {
5705            //     ...
5706            //     extensibleMatch  [9] MatchingRuleAssertion,
5707            //     ...
5708            //
5709            // Init Assertion Value Filter filter
5710            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
5711                LdapStatesEnum.ANY_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG,
5712                new InitExtensibleMatchFilterAction() );
5713    
5714            // --------------------------------------------------------------------------------------------
5715            // Transition from final to Attribute Description List
5716            // --------------------------------------------------------------------------------------------
5717            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5718            //     ...
5719            //     filter      Filter,
5720            //     attributes  AttributeDescriptionList }
5721            //
5722            // AttributeDescriptionList ::= SEQUENCE OF
5723            //     AttributeDescription
5724            //
5725            // Init attribute description list
5726            super.transitions[LdapStatesEnum.FINAL_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
5727                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, UniversalTag.SEQUENCE_TAG,
5728                new InitAttributeDescListAction() );
5729    
5730            // --------------------------------------------------------------------------------------------
5731            // Transition from final to AND filter
5732            // --------------------------------------------------------------------------------------------
5733            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5734            //     ...
5735            //     filter Filter,
5736            //     ...
5737            //
5738            // Filter ::= CHOICE {
5739            //     and             [0] SET OF Filter,
5740            //     ...
5741            //
5742            // Init AND filter
5743            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
5744                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
5745                new InitAndFilterAction() );
5746    
5747            // --------------------------------------------------------------------------------------------
5748            // Transition from final to OR filter
5749            // --------------------------------------------------------------------------------------------
5750            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5751            //     ...
5752            //     filter Filter,
5753            //     ...
5754            //
5755            // Filter ::= CHOICE {
5756            //     ...
5757            //     or              [1] SET OF Filter,
5758            //     ...
5759            //
5760            // Init OR filter
5761            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
5762                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG, new InitOrFilterAction() );
5763    
5764            // --------------------------------------------------------------------------------------------
5765            // Transition from final to NOT filter
5766            // --------------------------------------------------------------------------------------------
5767            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5768            //     ...
5769            //     filter Filter,
5770            //     ...
5771            //
5772            // Filter ::= CHOICE {
5773            //     ...
5774            //     not             [2] SET OF Filter,
5775            //     ...
5776            //
5777            // Init NOT filter
5778            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
5779                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
5780                new InitNotFilterAction() );
5781    
5782            // --------------------------------------------------------------------------------------------
5783            // Transition from final to Equality Match filter
5784            // --------------------------------------------------------------------------------------------
5785            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5786            //     ...
5787            //     filter Filter,
5788            //     ...
5789            //
5790            // Filter ::= CHOICE {
5791            //     ...
5792            //     equalityMatch   [3] AttributeValueAssertion,
5793            //     ...
5794            //
5795            // Init NOT filter
5796            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
5797                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
5798                new InitEqualityMatchFilterAction() );
5799    
5800            // --------------------------------------------------------------------------------------------
5801            // Transition from final to Substrings filter
5802            // --------------------------------------------------------------------------------------------
5803            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5804            //     ...
5805            //     filter Filter,
5806            //     ...
5807            //
5808            // Filter ::= CHOICE {
5809            //     ...
5810            //     substrings     [4] SubstringFilter,
5811            //     ...
5812            //
5813            // Init Substrings filter
5814            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
5815                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
5816                new InitSubstringsFilterAction() );
5817    
5818            // --------------------------------------------------------------------------------------------
5819            // Transition from final to GreaterOrEqual filter
5820            // --------------------------------------------------------------------------------------------
5821            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5822            //     ...
5823            //     filter Filter,
5824            //     ...
5825            //
5826            // Filter ::= CHOICE {
5827            //     ...
5828            //     greaterOrEqual  [5] AttributeValueAssertion,
5829            //     ...
5830            //
5831            // Init Greater Or Equal filter
5832            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5833                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
5834                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
5835    
5836            // --------------------------------------------------------------------------------------------
5837            // Transition from final to LessOrEqual filter
5838            // --------------------------------------------------------------------------------------------
5839            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5840            //     ...
5841            //     filter Filter,
5842            //     ...
5843            //
5844            // Filter ::= CHOICE {
5845            //     ...
5846            //     LessOrEqual    [6] AttributeValueAssertion,
5847            //     ...
5848            //
5849            // Init Less Or Equal filter
5850            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5851                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
5852                new InitLessOrEqualFilterAction() );
5853    
5854            // --------------------------------------------------------------------------------------------
5855            // Transition from final to Present filter
5856            // --------------------------------------------------------------------------------------------
5857            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5858            //     ...
5859            //     filter Filter,
5860            //     ...
5861            //
5862            // Filter ::= CHOICE {
5863            //     ...
5864            //     present        [7] AttributeDescription,
5865            //     ...
5866            //
5867            // Init present filter
5868            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
5869                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
5870                new InitPresentFilterAction() );
5871    
5872            // --------------------------------------------------------------------------------------------
5873            // Transition from final to Approx Match filter
5874            // --------------------------------------------------------------------------------------------
5875            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5876            //     ...
5877            //     filter Filter,
5878            //     ...
5879            //
5880            // Filter ::= CHOICE {
5881            //     ...
5882            //     approxMatch     [8] AttributeValueAssertion,
5883            //     ...
5884            //
5885            // Init Approx Match filter
5886            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
5887                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
5888                new InitApproxMatchFilterAction() );
5889    
5890            // --------------------------------------------------------------------------------------------
5891            // Transition from final to Extensible Match filter
5892            // --------------------------------------------------------------------------------------------
5893            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5894            //     ...
5895            //     filter Filter,
5896            //     ...
5897            //
5898            // Filter ::= CHOICE {
5899            //     ...
5900            //     extensibleMatch  [9] MatchingRuleAssertion,
5901            //     ...
5902            //
5903            // Init Assertion Value Filter filter
5904            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
5905                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
5906                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
5907    
5908            // --------------------------------------------------------------------------------------------
5909            // Transition from Present Filter to AND filter
5910            // --------------------------------------------------------------------------------------------
5911            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5912            //     ...
5913            //     filter Filter,
5914            //     ...
5915            //
5916            // Filter ::= CHOICE {
5917            //     and             [0] SET OF Filter,
5918            //     ...
5919            //
5920            // Init AND filter
5921            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
5922                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
5923                new InitAndFilterAction() );
5924    
5925            // --------------------------------------------------------------------------------------------
5926            // Transition from Present Filter to OR filter
5927            // --------------------------------------------------------------------------------------------
5928            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5929            //     ...
5930            //     filter Filter,
5931            //     ...
5932            //
5933            // Filter ::= CHOICE {
5934            //     ...
5935            //     or              [1] SET OF Filter,
5936            //     ...
5937            //
5938            // Init OR filter
5939            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
5940                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
5941                new InitOrFilterAction() );
5942    
5943            // --------------------------------------------------------------------------------------------
5944            // Transition from Present Filter to NOT filter
5945            // --------------------------------------------------------------------------------------------
5946            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5947            //     ...
5948            //     filter Filter,
5949            //     ...
5950            //
5951            // Filter ::= CHOICE {
5952            //     ...
5953            //     not             [2] SET OF Filter,
5954            //     ...
5955            //
5956            // Init NOT filter
5957            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
5958                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
5959                new InitNotFilterAction() );
5960    
5961            // --------------------------------------------------------------------------------------------
5962            // Transition from Present Filter to Equality Match filter
5963            // --------------------------------------------------------------------------------------------
5964            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5965            //     ...
5966            //     filter Filter,
5967            //     ...
5968            //
5969            // Filter ::= CHOICE {
5970            //     ...
5971            //     equalityMatch   [3] AttributeValueAssertion,
5972            //     ...
5973            //
5974            // Init NOT filter
5975            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
5976                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
5977                new InitEqualityMatchFilterAction() );
5978    
5979            // --------------------------------------------------------------------------------------------
5980            // Transition from Present Filter to Substrings filter
5981            // --------------------------------------------------------------------------------------------
5982            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5983            //     ...
5984            //     filter Filter,
5985            //     ...
5986            //
5987            // Filter ::= CHOICE {
5988            //     ...
5989            //     substrings     [4] SubstringFilter,
5990            //     ...
5991            //
5992            // Init Substrings filter
5993            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
5994                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
5995                new InitSubstringsFilterAction() );
5996    
5997            // --------------------------------------------------------------------------------------------
5998            // Transition from Present Filter to GreaterOrEqual filter
5999            // --------------------------------------------------------------------------------------------
6000            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6001            //     ...
6002            //     filter Filter,
6003            //     ...
6004            //
6005            // Filter ::= CHOICE {
6006            //     ...
6007            //     greaterOrEqual  [5] AttributeValueAssertion,
6008            //     ...
6009            //
6010            // Init Greater Or Equal filter
6011            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
6012                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
6013                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
6014    
6015            // --------------------------------------------------------------------------------------------
6016            // Transition from Present Filter to LessOrEqual filter
6017            // --------------------------------------------------------------------------------------------
6018            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6019            //     ...
6020            //     filter Filter,
6021            //     ...
6022            //
6023            // Filter ::= CHOICE {
6024            //     ...
6025            //     LessOrEqual    [6] AttributeValueAssertion,
6026            //     ...
6027            //
6028            // Init Less Or Equal filter
6029            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
6030                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
6031                new InitLessOrEqualFilterAction() );
6032    
6033            // --------------------------------------------------------------------------------------------
6034            // Transition from Present Filter to Present filter
6035            // --------------------------------------------------------------------------------------------
6036            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6037            //     ...
6038            //     filter Filter,
6039            //     ...
6040            //
6041            // Filter ::= CHOICE {
6042            //     ...
6043            //     present        [7] AttributeDescription,
6044            //     ...
6045            //
6046            // Init present filter
6047            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
6048                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
6049                new InitPresentFilterAction() );
6050    
6051            // --------------------------------------------------------------------------------------------
6052            // Transition from Present Filter to Approx Match filter
6053            // --------------------------------------------------------------------------------------------
6054            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6055            //     ...
6056            //     filter Filter,
6057            //     ...
6058            //
6059            // Filter ::= CHOICE {
6060            //     ...
6061            //     approxMatch     [8] AttributeValueAssertion,
6062            //     ...
6063            //
6064            // Init Approx Match filter
6065            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
6066                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
6067                new InitApproxMatchFilterAction() );
6068    
6069            // --------------------------------------------------------------------------------------------
6070            // Transition from Present Filter to Extensible Match filter
6071            // --------------------------------------------------------------------------------------------
6072            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6073            //     ...
6074            //     filter Filter,
6075            //     ...
6076            //
6077            // Filter ::= CHOICE {
6078            //     ...
6079            //     extensibleMatch  [9] MatchingRuleAssertion,
6080            //     ...
6081            //
6082            // Init Assertion Value Filter filter
6083            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
6084                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
6085                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
6086    
6087            // --------------------------------------------------------------------------------------------
6088            // Transition from Present Filter to Attribute Description List
6089            // --------------------------------------------------------------------------------------------
6090            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6091            //     ...
6092            //     filter      Filter,
6093            //     attributes  AttributeDescriptionList }
6094            //
6095            // AttributeDescriptionList ::= SEQUENCE OF
6096            //     AttributeDescription
6097            //
6098            // Init attribute description list
6099            super.transitions[LdapStatesEnum.PRESENT_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
6100                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, UniversalTag.SEQUENCE_TAG,
6101                new InitAttributeDescListAction() );
6102    
6103            // --------------------------------------------------------------------------------------------
6104            // Transition from Approx Match to Attribute Desc Filter
6105            // --------------------------------------------------------------------------------------------
6106            // Filter ::= CHOICE {
6107            //     ...
6108            //     approxMatch  [8] AttributeValueAssertion,
6109            //     ...
6110            //
6111            // AttributeValueAssertion ::= SEQUENCE {
6112            //     attributeDesc   AttributeDescription,
6113            //     ...
6114            //
6115            // Init Attribute Desc filter
6116            super.transitions[LdapStatesEnum.APPROX_MATCH_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
6117                LdapStatesEnum.APPROX_MATCH_STATE, LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE,
6118                UniversalTag.OCTET_STRING_TAG, new InitAttributeDescFilterAction() );
6119    
6120            // --------------------------------------------------------------------------------------------
6121            // Transition from Extensible Match to MatchingRule
6122            // --------------------------------------------------------------------------------------------
6123            // Filter ::= CHOICE {
6124            //     ...
6125            //     extensibleMatch  [9] MatchingRuleAssertion }
6126            //
6127            // MatchingRuleAssertion ::= SEQUENCE {
6128            //     matchingRule [1] MatchingRuleId OPTIONAL,
6129            //     ...
6130            //
6131            // Store the matching rule ID 
6132            super.transitions[LdapStatesEnum.EXTENSIBLE_MATCH_STATE][LdapConstants.MATCHING_RULE_ID_TAG] = new GrammarTransition(
6133                LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapStatesEnum.MATCHING_RULE_STATE,
6134                LdapConstants.MATCHING_RULE_ID_TAG, new GrammarAction( "Store matching rule Value" )
6135                {
6136                    public void action( IAsn1Container container ) throws DecoderException
6137                    {
6138                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
6139                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
6140                        SearchRequestCodec searchRequest = ldapMessage.getSearchRequest();
6141    
6142                        TLV tlv = ldapMessageContainer.getCurrentTLV();
6143    
6144                        // Store the value.
6145                        ExtensibleMatchFilter extensibleMatchFilter = ( ExtensibleMatchFilter ) searchRequest
6146                            .getTerminalFilter();
6147    
6148                        if ( tlv.getLength() == 0 )
6149                        {
6150                            log.error( "The matching rule is empty" );
6151    
6152                            // It will generate a PROTOCOL_ERROR
6153                            throw new DecoderException( "Invalid matching rule : it can't be empty" );
6154                        }
6155                        else
6156                        {
6157                            extensibleMatchFilter.setMatchingRule( StringTools.utf8ToString( tlv.getValue().getData() ) );
6158                        }
6159                    }
6160                } );
6161    
6162            // --------------------------------------------------------------------------------------------
6163            // Transition from Extensible Match to type matching rule
6164            // --------------------------------------------------------------------------------------------
6165            // Filter ::= CHOICE {
6166            //     ...
6167            //     extensibleMatch  [9] MatchingRuleAssertion }
6168            //
6169            // MatchingRuleAssertion ::= SEQUENCE {
6170            //     ...
6171            //     type [2] AttributeDescription OPTIONAL,
6172            //     ...
6173            //
6174            // Store the matching rule ID 
6175            super.transitions[LdapStatesEnum.EXTENSIBLE_MATCH_STATE][LdapConstants.MATCHING_RULE_TYPE_TAG] = new GrammarTransition(
6176                LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapStatesEnum.TYPE_MATCHING_RULE_STATE,
6177                LdapConstants.MATCHING_RULE_TYPE_TAG, new StoreTypeMatchingRuleAction() );
6178    
6179            // --------------------------------------------------------------------------------------------
6180            // Transition from Extensible Match to match value
6181            // --------------------------------------------------------------------------------------------
6182            // Filter ::= CHOICE {
6183            //     ...
6184            //     extensibleMatch  [9] MatchingRuleAssertion }
6185            //
6186            // MatchingRuleAssertion ::= SEQUENCE {
6187            //     ...
6188            //     matchValue [3] AssertionValue,
6189            //     ...
6190            //
6191            // Store the matching rule ID 
6192            super.transitions[LdapStatesEnum.EXTENSIBLE_MATCH_STATE][LdapConstants.MATCH_VALUE_TAG] = new GrammarTransition(
6193                LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapStatesEnum.MATCH_VALUE_STATE, LdapConstants.MATCH_VALUE_TAG,
6194                new StoreMatchValueAction() );
6195    
6196            // --------------------------------------------------------------------------------------------
6197            // Transition from matching rule to type matching rule
6198            // --------------------------------------------------------------------------------------------
6199            // Filter ::= CHOICE {
6200            //     ...
6201            //     extensibleMatch  [9] MatchingRuleAssertion }
6202            //
6203            // MatchingRuleAssertion ::= SEQUENCE {
6204            //     ...
6205            //     type [2] AttributeDescription OPTIONAL,
6206            //     ...
6207            //
6208            // Store the matching rule ID 
6209            super.transitions[LdapStatesEnum.MATCHING_RULE_STATE][LdapConstants.MATCHING_RULE_TYPE_TAG] = new GrammarTransition(
6210                LdapStatesEnum.MATCHING_RULE_STATE, LdapStatesEnum.TYPE_MATCHING_RULE_STATE,
6211                LdapConstants.MATCHING_RULE_TYPE_TAG, new StoreTypeMatchingRuleAction() );
6212    
6213            // --------------------------------------------------------------------------------------------
6214            // Transition from matching rule to match value
6215            // --------------------------------------------------------------------------------------------
6216            // Filter ::= CHOICE {
6217            //     ...
6218            //     extensibleMatch  [9] MatchingRuleAssertion }
6219            //
6220            // MatchingRuleAssertion ::= SEQUENCE {
6221            //     ...
6222            //     matchValue [3] AssertionValue,
6223            //     ...
6224            //
6225            // Store the matching rule ID 
6226            super.transitions[LdapStatesEnum.MATCHING_RULE_STATE][LdapConstants.MATCH_VALUE_TAG] = new GrammarTransition(
6227                LdapStatesEnum.MATCHING_RULE_STATE, LdapStatesEnum.MATCH_VALUE_STATE, LdapConstants.MATCH_VALUE_TAG,
6228                new StoreMatchValueAction() );
6229    
6230            // --------------------------------------------------------------------------------------------
6231            // Transition from matching type to match value
6232            // --------------------------------------------------------------------------------------------
6233            // Filter ::= CHOICE {
6234            //     ...
6235            //     extensibleMatch  [9] MatchingRuleAssertion }
6236            //
6237            // MatchingRuleAssertion ::= SEQUENCE {
6238            //     ...
6239            //     matchValue [3] AssertionValue,
6240            //     ...
6241            //
6242            // Store the matching rule ID 
6243            super.transitions[LdapStatesEnum.TYPE_MATCHING_RULE_STATE][LdapConstants.MATCH_VALUE_TAG] = new GrammarTransition(
6244                LdapStatesEnum.TYPE_MATCHING_RULE_STATE, LdapStatesEnum.MATCH_VALUE_STATE, LdapConstants.MATCH_VALUE_TAG,
6245                new StoreMatchValueAction() );
6246    
6247            // --------------------------------------------------------------------------------------------
6248            // Transition from match value to dnAttributes
6249            // --------------------------------------------------------------------------------------------
6250            // Filter ::= CHOICE {
6251            //     ...
6252            //     extensibleMatch  [9] MatchingRuleAssertion }
6253            //
6254            // MatchingRuleAssertion ::= SEQUENCE {
6255            //     ...
6256            //     dnAttributes [4] BOOLEAN DEFAULT FALSE }
6257            //
6258            // Store the dnAttributes flag 
6259            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.DN_ATTRIBUTES_FILTER_TAG] = new GrammarTransition(
6260                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.DN_ATTRIBUTES_STATE,
6261                LdapConstants.DN_ATTRIBUTES_FILTER_TAG, new GrammarAction( "Store matching dnAttributes Value" )
6262                {
6263                    public void action( IAsn1Container container ) throws DecoderException
6264                    {
6265                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
6266                        LdapMessageCodec ldapMessage = ldapMessageContainer.getLdapMessage();
6267                        SearchRequestCodec searchRequest = ldapMessage.getSearchRequest();
6268    
6269                        TLV tlv = ldapMessageContainer.getCurrentTLV();
6270    
6271                        // Store the value.
6272                        ExtensibleMatchFilter extensibleMatchFilter = ( ExtensibleMatchFilter ) searchRequest
6273                            .getTerminalFilter();
6274    
6275                        // We get the value. If it's a 0, it's a FALSE. If it's
6276                        // a FF, it's a TRUE. Any other value should be an error,
6277                        // but we could relax this constraint. So if we have
6278                        // something
6279                        // which is not 0, it will be interpreted as TRUE, but we
6280                        // will generate a warning.
6281                        Value value = tlv.getValue();
6282    
6283                        try
6284                        {
6285                            extensibleMatchFilter.setDnAttributes( BooleanDecoder.parse( value ) );
6286                        }
6287                        catch ( BooleanDecoderException bde )
6288                        {
6289                            log.error( "The DN attributes flag {} is invalid : {}. It should be 0 or 255", StringTools
6290                                .dumpBytes( value.getData() ), bde.getMessage() );
6291    
6292                            throw new DecoderException( bde.getMessage() );
6293                        }
6294    
6295                        if ( IS_DEBUG )
6296                        {
6297                            log.debug( "DN Attributes : {}", Boolean.valueOf( extensibleMatchFilter.isDnAttributes() ) );
6298                        }
6299    
6300                        // unstack the filters if needed
6301                        searchRequest.unstackFilters( ldapMessageContainer );
6302                    }
6303                } );
6304    
6305            // --------------------------------------------------------------------------------------------
6306            // Transition from match value to AND filter
6307            // --------------------------------------------------------------------------------------------
6308            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6309            //     ...
6310            //     filter Filter,
6311            //     ...
6312            //
6313            // Filter ::= CHOICE {
6314            //     and             [0] SET OF Filter,
6315            //     ...
6316            //
6317            // Init AND filter
6318            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
6319                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
6320                new InitAndFilterAction() );
6321    
6322            // --------------------------------------------------------------------------------------------
6323            // Transition from match value to OR filter
6324            // --------------------------------------------------------------------------------------------
6325            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6326            //     ...
6327            //     filter Filter,
6328            //     ...
6329            //
6330            // Filter ::= CHOICE {
6331            //     ...
6332            //     or              [1] SET OF Filter,
6333            //     ...
6334            //
6335            // Init OR filter
6336            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
6337                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
6338                new InitOrFilterAction() );
6339    
6340            // --------------------------------------------------------------------------------------------
6341            // Transition from match value to NOT filter
6342            // --------------------------------------------------------------------------------------------
6343            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6344            //     ...
6345            //     filter Filter,
6346            //     ...
6347            //
6348            // Filter ::= CHOICE {
6349            //     ...
6350            //     not             [2] SET OF Filter,
6351            //     ...
6352            //
6353            // Init NOT filter
6354            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
6355                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
6356                new InitNotFilterAction() );
6357    
6358            // --------------------------------------------------------------------------------------------
6359            // Transition from match value to Equality Match filter
6360            // --------------------------------------------------------------------------------------------
6361            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6362            //     ...
6363            //     filter Filter,
6364            //     ...
6365            //
6366            // Filter ::= CHOICE {
6367            //     ...
6368            //     equalityMatch   [3] AttributeValueAssertion,
6369            //     ...
6370            //
6371            // Init NOT filter
6372            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
6373                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE,
6374                LdapConstants.EQUALITY_MATCH_FILTER_TAG, new InitEqualityMatchFilterAction() );
6375    
6376            // --------------------------------------------------------------------------------------------
6377            // Transition from match value to Substrings filter
6378            // --------------------------------------------------------------------------------------------
6379            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6380            //     ...
6381            //     filter Filter,
6382            //     ...
6383            //
6384            // Filter ::= CHOICE {
6385            //     ...
6386            //     substrings     [4] SubstringFilter,
6387            //     ...
6388            //
6389            // Init Substrings filter
6390            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
6391                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE,
6392                LdapConstants.SUBSTRINGS_FILTER_TAG, new InitSubstringsFilterAction() );
6393    
6394            // --------------------------------------------------------------------------------------------
6395            // Transition from match value to GreaterOrEqual filter
6396            // --------------------------------------------------------------------------------------------
6397            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6398            //     ...
6399            //     filter Filter,
6400            //     ...
6401            //
6402            // Filter ::= CHOICE {
6403            //     ...
6404            //     greaterOrEqual  [5] AttributeValueAssertion,
6405            //     ...
6406            //
6407            // Init Greater Or Equal filter
6408            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
6409                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
6410                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
6411    
6412            // --------------------------------------------------------------------------------------------
6413            // Transition from match value to LessOrEqual filter
6414            // --------------------------------------------------------------------------------------------
6415            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6416            //     ...
6417            //     filter Filter,
6418            //     ...
6419            //
6420            // Filter ::= CHOICE {
6421            //     ...
6422            //     LessOrEqual    [6] AttributeValueAssertion,
6423            //     ...
6424            //
6425            // Init Less Or Equal filter
6426            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
6427                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE,
6428                LdapConstants.LESS_OR_EQUAL_FILTER_TAG, new InitLessOrEqualFilterAction() );
6429    
6430            // --------------------------------------------------------------------------------------------
6431            // Transition from match value to Present filter
6432            // --------------------------------------------------------------------------------------------
6433            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6434            //     ...
6435            //     filter Filter,
6436            //     ...
6437            //
6438            // Filter ::= CHOICE {
6439            //     ...
6440            //     present        [7] AttributeDescription,
6441            //     ...
6442            //
6443            // Init present filter
6444            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
6445                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
6446                new InitPresentFilterAction() );
6447    
6448            // --------------------------------------------------------------------------------------------
6449            // Transition from match value to Approx Match filter
6450            // --------------------------------------------------------------------------------------------
6451            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6452            //     ...
6453            //     filter Filter,
6454            //     ...
6455            //
6456            // Filter ::= CHOICE {
6457            //     ...
6458            //     approxMatch     [8] AttributeValueAssertion,
6459            //     ...
6460            //
6461            // Init Approx Match filter
6462            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
6463                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
6464                new InitApproxMatchFilterAction() );
6465    
6466            // --------------------------------------------------------------------------------------------
6467            // Transition from match value to Extensible Match filter
6468            // --------------------------------------------------------------------------------------------
6469            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6470            //     ...
6471            //     filter Filter,
6472            //     ...
6473            //
6474            // Filter ::= CHOICE {
6475            //     ...
6476            //     extensibleMatch  [9] MatchingRuleAssertion,
6477            //     ...
6478            //
6479            // Init Assertion Value Filter filter
6480            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
6481                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
6482                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
6483    
6484            // --------------------------------------------------------------------------------------------
6485            // Transition from match value to Attribute Description List
6486            // --------------------------------------------------------------------------------------------
6487            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6488            //     ...
6489            //     filter      Filter,
6490            //     attributes  AttributeDescriptionList }
6491            //
6492            // AttributeDescriptionList ::= SEQUENCE OF
6493            //     AttributeDescription
6494            //
6495            // Init attribute description list
6496            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
6497                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE,
6498                UniversalTag.SEQUENCE_TAG, new InitAttributeDescListAction() );
6499    
6500            // --------------------------------------------------------------------------------------------
6501            // Transition from dnAttributes to AND filter
6502            // --------------------------------------------------------------------------------------------
6503            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6504            //     ...
6505            //     filter Filter,
6506            //     ...
6507            //
6508            // Filter ::= CHOICE {
6509            //     and             [0] SET OF Filter,
6510            //     ...
6511            //
6512            // Init AND filter
6513            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
6514                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
6515                new InitAndFilterAction() );
6516    
6517            // --------------------------------------------------------------------------------------------
6518            // Transition from dnAttributes to OR filter
6519            // --------------------------------------------------------------------------------------------
6520            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6521            //     ...
6522            //     filter Filter,
6523            //     ...
6524            //
6525            // Filter ::= CHOICE {
6526            //     ...
6527            //     or              [1] SET OF Filter,
6528            //     ...
6529            //
6530            // Init OR filter
6531            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
6532                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
6533                new InitOrFilterAction() );
6534    
6535            // --------------------------------------------------------------------------------------------
6536            // Transition from dnAttributes to NOT filter
6537            // --------------------------------------------------------------------------------------------
6538            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6539            //     ...
6540            //     filter Filter,
6541            //     ...
6542            //
6543            // Filter ::= CHOICE {
6544            //     ...
6545            //     not             [2] SET OF Filter,
6546            //     ...
6547            //
6548            // Init NOT filter
6549            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
6550                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
6551                new InitNotFilterAction() );
6552    
6553            // --------------------------------------------------------------------------------------------
6554            // Transition from dnAttributes to Equality Match filter
6555            // --------------------------------------------------------------------------------------------
6556            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6557            //     ...
6558            //     filter Filter,
6559            //     ...
6560            //
6561            // Filter ::= CHOICE {
6562            //     ...
6563            //     equalityMatch   [3] AttributeValueAssertion,
6564            //     ...
6565            //
6566            // Init NOT filter
6567            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
6568                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE,
6569                LdapConstants.EQUALITY_MATCH_FILTER_TAG, new InitEqualityMatchFilterAction() );
6570    
6571            // --------------------------------------------------------------------------------------------
6572            // Transition from dnAttributes to Substrings filter
6573            // --------------------------------------------------------------------------------------------
6574            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6575            //     ...
6576            //     filter Filter,
6577            //     ...
6578            //
6579            // Filter ::= CHOICE {
6580            //     ...
6581            //     substrings     [4] SubstringFilter,
6582            //     ...
6583            //
6584            // Init Substrings filter
6585            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
6586                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE,
6587                LdapConstants.SUBSTRINGS_FILTER_TAG, new InitSubstringsFilterAction() );
6588    
6589            // --------------------------------------------------------------------------------------------
6590            // Transition from dnAttributes to GreaterOrEqual filter
6591            // --------------------------------------------------------------------------------------------
6592            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6593            //     ...
6594            //     filter Filter,
6595            //     ...
6596            //
6597            // Filter ::= CHOICE {
6598            //     ...
6599            //     greaterOrEqual  [5] AttributeValueAssertion,
6600            //     ...
6601            //
6602            // Init Greater Or Equal filter
6603            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
6604                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
6605                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
6606    
6607            // --------------------------------------------------------------------------------------------
6608            // Transition from dnAttributes to LessOrEqual filter
6609            // --------------------------------------------------------------------------------------------
6610            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6611            //     ...
6612            //     filter Filter,
6613            //     ...
6614            //
6615            // Filter ::= CHOICE {
6616            //     ...
6617            //     LessOrEqual    [6] AttributeValueAssertion,
6618            //     ...
6619            //
6620            // Init Less Or Equal filter
6621            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
6622                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE,
6623                LdapConstants.LESS_OR_EQUAL_FILTER_TAG, new InitLessOrEqualFilterAction() );
6624    
6625            // --------------------------------------------------------------------------------------------
6626            // Transition from dnAttributes to Present filter
6627            // --------------------------------------------------------------------------------------------
6628            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6629            //     ...
6630            //     filter Filter,
6631            //     ...
6632            //
6633            // Filter ::= CHOICE {
6634            //     ...
6635            //     present        [7] AttributeDescription,
6636            //     ...
6637            //
6638            // Init present filter
6639            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
6640                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
6641                new InitPresentFilterAction() );
6642    
6643            // --------------------------------------------------------------------------------------------
6644            // Transition from dnAttributes to Approx Match filter
6645            // --------------------------------------------------------------------------------------------
6646            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6647            //     ...
6648            //     filter Filter,
6649            //     ...
6650            //
6651            // Filter ::= CHOICE {
6652            //     ...
6653            //     approxMatch     [8] AttributeValueAssertion,
6654            //     ...
6655            //
6656            // Init Approx Match filter
6657            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
6658                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.APPROX_MATCH_STATE,
6659                LdapConstants.APPROX_MATCH_FILTER_TAG, new InitApproxMatchFilterAction() );
6660    
6661            // --------------------------------------------------------------------------------------------
6662            // Transition from dnAttributes to Extensible Match filter
6663            // --------------------------------------------------------------------------------------------
6664            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6665            //     ...
6666            //     filter Filter,
6667            //     ...
6668            //
6669            // Filter ::= CHOICE {
6670            //     ...
6671            //     extensibleMatch  [9] MatchingRuleAssertion,
6672            //     ...
6673            //
6674            // Init Assertion Value Filter filter
6675            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
6676                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
6677                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
6678    
6679            // --------------------------------------------------------------------------------------------
6680            // Transition from dnAttributes to Attribute Description List
6681            // --------------------------------------------------------------------------------------------
6682            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6683            //     ...
6684            //     filter      Filter,
6685            //     attributes  AttributeDescriptionList }
6686            //
6687            // AttributeDescriptionList ::= SEQUENCE OF
6688            //     AttributeDescription
6689            //
6690            // Init attribute description list
6691            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
6692                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE,
6693                UniversalTag.SEQUENCE_TAG, new InitAttributeDescListAction() );
6694        }
6695    
6696    
6697        // ~ Methods
6698        // ------------------------------------------------------------------------------------
6699    
6700        /**
6701         * Get the instance of this grammar
6702         * 
6703         * @return An instance on the LdapMessage Grammar
6704         */
6705        public static IGrammar getInstance()
6706        {
6707            return instance;
6708        }
6709    }