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 *    https://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 */
020package org.apache.directory.api.dsmlv2.response;
021
022
023import java.io.IOException;
024import java.lang.reflect.Array;
025import java.util.HashMap;
026import java.util.HashSet;
027import java.util.Set;
028
029import org.apache.directory.api.asn1.DecoderException;
030import org.apache.directory.api.asn1.util.Oid;
031import org.apache.directory.api.dsmlv2.AbstractDsmlMessageDecorator;
032import org.apache.directory.api.dsmlv2.AbstractGrammar;
033import org.apache.directory.api.dsmlv2.DsmlControl;
034import org.apache.directory.api.dsmlv2.DsmlDecorator;
035import org.apache.directory.api.dsmlv2.Dsmlv2Container;
036import org.apache.directory.api.dsmlv2.Dsmlv2StatesEnum;
037import org.apache.directory.api.dsmlv2.Grammar;
038import org.apache.directory.api.dsmlv2.GrammarAction;
039import org.apache.directory.api.dsmlv2.GrammarTransition;
040import org.apache.directory.api.dsmlv2.ParserUtils;
041import org.apache.directory.api.dsmlv2.Tag;
042import org.apache.directory.api.dsmlv2.response.ErrorResponse.ErrorResponseType;
043import org.apache.directory.api.i18n.I18n;
044import org.apache.directory.api.ldap.codec.api.ControlFactory;
045import org.apache.directory.api.ldap.model.exception.LdapException;
046import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
047import org.apache.directory.api.ldap.model.exception.LdapURLEncodingException;
048import org.apache.directory.api.ldap.model.message.AddResponseImpl;
049import org.apache.directory.api.ldap.model.message.BindResponseImpl;
050import org.apache.directory.api.ldap.model.message.CompareResponseImpl;
051import org.apache.directory.api.ldap.model.message.Control;
052import org.apache.directory.api.ldap.model.message.DeleteResponseImpl;
053import org.apache.directory.api.ldap.model.message.ExtendedResponse;
054import org.apache.directory.api.ldap.model.message.LdapResult;
055import org.apache.directory.api.ldap.model.message.Message;
056import org.apache.directory.api.ldap.model.message.ModifyDnResponseImpl;
057import org.apache.directory.api.ldap.model.message.ModifyResponseImpl;
058import org.apache.directory.api.ldap.model.message.OpaqueExtendedResponse;
059import org.apache.directory.api.ldap.model.message.ReferralImpl;
060import org.apache.directory.api.ldap.model.message.Response;
061import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
062import org.apache.directory.api.ldap.model.message.ResultResponse;
063import org.apache.directory.api.ldap.model.message.SearchResultDoneImpl;
064import org.apache.directory.api.ldap.model.message.SearchResultEntryImpl;
065import org.apache.directory.api.ldap.model.message.SearchResultReference;
066import org.apache.directory.api.ldap.model.message.SearchResultReferenceImpl;
067import org.apache.directory.api.ldap.model.message.controls.OpaqueControl;
068import org.apache.directory.api.ldap.model.name.Dn;
069import org.apache.directory.api.ldap.model.url.LdapUrl;
070import org.apache.directory.api.util.Base64;
071import org.apache.directory.api.util.Strings;
072import org.xmlpull.v1.XmlPullParser;
073import org.xmlpull.v1.XmlPullParserException;
074
075
076/**
077 * This Class represents the DSMLv2 Response Grammar
078 *
079 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
080 */
081public final class Dsmlv2ResponseGrammar extends AbstractGrammar implements Grammar
082{
083    /** The instance of grammar. Dsmlv2ResponseGrammar is a singleton */
084    private static Dsmlv2ResponseGrammar instance = new Dsmlv2ResponseGrammar();
085
086    /** The DSMLv2 description tags */
087    private static final Set<String> DSMLV2_DESCR_TAGS;
088    static
089    {
090        DSMLV2_DESCR_TAGS = new HashSet<>();
091        DSMLV2_DESCR_TAGS.add( "success" );
092        DSMLV2_DESCR_TAGS.add( "operationsError" );
093        DSMLV2_DESCR_TAGS.add( "protocolError" );
094        DSMLV2_DESCR_TAGS.add( "timeLimitExceeded" );
095        DSMLV2_DESCR_TAGS.add( "sizeLimitExceeded" );
096        DSMLV2_DESCR_TAGS.add( "compareFalse" );
097        DSMLV2_DESCR_TAGS.add( "compareTrue" );
098        DSMLV2_DESCR_TAGS.add( "authMethodNotSupported" );
099        DSMLV2_DESCR_TAGS.add( "strongAuthRequired" );
100        DSMLV2_DESCR_TAGS.add( "referral" );
101        DSMLV2_DESCR_TAGS.add( "adminLimitExceeded" );
102        DSMLV2_DESCR_TAGS.add( "unavailableCriticalExtension" );
103        DSMLV2_DESCR_TAGS.add( "confidentialityRequired" );
104        DSMLV2_DESCR_TAGS.add( "saslBindInProgress" );
105        DSMLV2_DESCR_TAGS.add( "noSuchAttribute" );
106        DSMLV2_DESCR_TAGS.add( "undefinedAttributeType" );
107        DSMLV2_DESCR_TAGS.add( "inappropriateMatching" );
108        DSMLV2_DESCR_TAGS.add( "constraintViolation" );
109        DSMLV2_DESCR_TAGS.add( "attributeOrValueExists" );
110        DSMLV2_DESCR_TAGS.add( "invalidAttributeSyntax" );
111        DSMLV2_DESCR_TAGS.add( "noSuchObject" );
112        DSMLV2_DESCR_TAGS.add( "aliasProblem" );
113        DSMLV2_DESCR_TAGS.add( "invalidDNSyntax" );
114        DSMLV2_DESCR_TAGS.add( "aliasDereferencingProblem" );
115        DSMLV2_DESCR_TAGS.add( "inappropriateAuthentication" );
116        DSMLV2_DESCR_TAGS.add( "invalidCredentials" );
117        DSMLV2_DESCR_TAGS.add( "insufficientAccessRights" );
118        DSMLV2_DESCR_TAGS.add( "busy" );
119        DSMLV2_DESCR_TAGS.add( "unavailable" );
120        DSMLV2_DESCR_TAGS.add( "unwillingToPerform" );
121        DSMLV2_DESCR_TAGS.add( "loopDetect" );
122        DSMLV2_DESCR_TAGS.add( "namingViolation" );
123        DSMLV2_DESCR_TAGS.add( "objectClassViolation" );
124        DSMLV2_DESCR_TAGS.add( "notAllowedOnNonLeaf" );
125        DSMLV2_DESCR_TAGS.add( "notAllowedOnRDN" );
126        DSMLV2_DESCR_TAGS.add( "entryAlreadyExists" );
127        DSMLV2_DESCR_TAGS.add( "objectClassModsProhibited" );
128        DSMLV2_DESCR_TAGS.add( "affectMultipleDSAs" );
129        DSMLV2_DESCR_TAGS.add( "other" );
130    }
131
132    /**
133     * GrammarAction that creates the Batch Response
134     */
135    private final GrammarAction batchResponseCreation = new GrammarAction( "Create Batch Response" )
136    {
137        /**
138         * {@inheritDoc}
139         */
140        @Override
141        public void action( Dsmlv2Container container ) throws XmlPullParserException
142        {
143            BatchResponseDsml batchResponse = new BatchResponseDsml();
144
145            container.setBatchResponse( batchResponse );
146
147            XmlPullParser xpp = container.getParser();
148
149            // Checking and adding the batchRequest's attributes
150            String attributeValue;
151            // requestID
152            attributeValue = xpp.getAttributeValue( "", "requestID" );
153
154            if ( attributeValue != null )
155            {
156                batchResponse.setRequestID( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
157            }
158        }
159    };
160
161    /**
162     * GrammarAction that creates the Add Response
163     */
164    private final GrammarAction addResponseCreation = new GrammarAction( "Create Add Response" )
165    {
166        /**
167         * {@inheritDoc}
168         */
169        @Override
170        public void action( Dsmlv2Container container ) throws XmlPullParserException
171        {
172            AddResponseDsml addResponse = new AddResponseDsml(
173                container.getLdapCodecService(), new AddResponseImpl() );
174            container.getBatchResponse().addResponse( addResponse );
175
176            LdapResult ldapResult = addResponse.getLdapResult();
177
178            XmlPullParser xpp = container.getParser();
179
180            // Checking and adding the batchRequest's attributes
181            String attributeValue;
182            // requestID
183            attributeValue = xpp.getAttributeValue( "", "requestID" );
184
185            if ( attributeValue != null )
186            {
187                addResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
188            }
189
190            // MatchedDN
191            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
192
193            if ( attributeValue != null )
194            {
195                try
196                {
197                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
198                }
199                catch ( LdapInvalidDnException lide )
200                {
201                    throw new XmlPullParserException( lide.getMessage(), xpp, lide );
202                }
203            }
204        }
205    };
206
207    /**
208     * GrammarAction that creates the Auth Response
209     */
210    private final GrammarAction authResponseCreation = new GrammarAction( "Create Auth Response" )
211    {
212        /**
213         * {@inheritDoc}
214         */
215        @Override
216        public void action( Dsmlv2Container container ) throws XmlPullParserException
217        {
218            BindResponseDsml bindResponse = new BindResponseDsml(
219                container.getLdapCodecService(), new BindResponseImpl() );
220            container.getBatchResponse().addResponse( bindResponse );
221
222            LdapResult ldapResult = bindResponse.getLdapResult();
223
224            XmlPullParser xpp = container.getParser();
225
226            // Checking and adding the batchRequest's attributes
227            String attributeValue;
228            // requestID
229            attributeValue = xpp.getAttributeValue( "", "requestID" );
230
231            if ( attributeValue != null )
232            {
233                bindResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
234
235            }
236
237            // MatchedDN
238            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
239
240            if ( attributeValue != null )
241            {
242                try
243                {
244                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
245                }
246                catch ( LdapInvalidDnException lide )
247                {
248                    throw new XmlPullParserException( lide.getMessage(), xpp, lide );
249                }
250            }
251        }
252    };
253
254    /**
255     * GrammarAction that creates the Compare Response
256     */
257    private final GrammarAction compareResponseCreation = new GrammarAction( "Create Compare Response" )
258    {
259        /**
260         * {@inheritDoc}
261         */
262        @Override
263        public void action( Dsmlv2Container container ) throws XmlPullParserException
264        {
265            CompareResponseDsml compareResponse = new CompareResponseDsml(
266                container.getLdapCodecService(), new CompareResponseImpl() );
267            container.getBatchResponse().addResponse( compareResponse );
268
269            LdapResult ldapResult = compareResponse.getLdapResult();
270
271            XmlPullParser xpp = container.getParser();
272
273            // Checking and adding the batchRequest's attributes
274            String attributeValue;
275            // requestID
276            attributeValue = xpp.getAttributeValue( "", "requestID" );
277
278            if ( attributeValue != null )
279            {
280                compareResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
281            }
282
283            // MatchedDN
284            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
285
286            if ( attributeValue != null )
287            {
288                try
289                {
290                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
291                }
292                catch ( LdapInvalidDnException lide )
293                {
294                    throw new XmlPullParserException( lide.getMessage(), xpp, lide );
295                }
296            }
297        }
298    };
299
300    /**
301     * GrammarAction that creates the Del Response
302     */
303    private final GrammarAction delResponseCreation = new GrammarAction( "Create Del Response" )
304    {
305        /**
306         * {@inheritDoc}
307         */
308        @Override
309        public void action( Dsmlv2Container container ) throws XmlPullParserException
310        {
311            DelResponseDsml delResponse = new DelResponseDsml(
312                container.getLdapCodecService(), new DeleteResponseImpl() );
313            container.getBatchResponse().addResponse( delResponse );
314
315            LdapResult ldapResult = delResponse.getLdapResult();
316
317            XmlPullParser xpp = container.getParser();
318
319            // Checking and adding the batchRequest's attributes
320            String attributeValue;
321            // requestID
322            attributeValue = xpp.getAttributeValue( "", "requestID" );
323
324            if ( attributeValue != null )
325            {
326                delResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
327            }
328
329            // MatchedDN
330            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
331
332            if ( attributeValue != null )
333            {
334                try
335                {
336                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
337                }
338                catch ( LdapInvalidDnException lide )
339                {
340                    throw new XmlPullParserException( lide.getMessage(), xpp, lide );
341                }
342            }
343        }
344    };
345
346    /**
347     * GrammarAction that creates the Modify Response
348     */
349    private final GrammarAction modifyResponseCreation = new GrammarAction( "Create Modify Response" )
350    {
351        /**
352         * {@inheritDoc}
353         */
354        @Override
355        public void action( Dsmlv2Container container ) throws XmlPullParserException
356        {
357            ModifyResponseDsml modifyResponse = new ModifyResponseDsml(
358                container.getLdapCodecService(), new ModifyResponseImpl() );
359            container.getBatchResponse().addResponse( modifyResponse );
360
361            LdapResult ldapResult = modifyResponse.getLdapResult();
362
363            XmlPullParser xpp = container.getParser();
364
365            // Checking and adding the batchRequest's attributes
366            String attributeValue;
367            // requestID
368            attributeValue = xpp.getAttributeValue( "", "requestID" );
369
370            if ( attributeValue != null )
371            {
372                modifyResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
373            }
374
375            // MatchedDN
376            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
377
378            if ( attributeValue != null )
379            {
380                try
381                {
382                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
383                }
384                catch ( LdapInvalidDnException lide )
385                {
386                    throw new XmlPullParserException( lide.getMessage(), xpp, lide );
387                }
388            }
389        }
390    };
391
392    /**
393     * GrammarAction that creates the Mod Dn Response
394     */
395    private final GrammarAction modDNResponseCreation = new GrammarAction( "Create Mod Dn Response" )
396    {
397        /**
398         * {@inheritDoc}
399         */
400        @Override
401        public void action( Dsmlv2Container container ) throws XmlPullParserException
402        {
403            ModDNResponseDsml modDNResponse = new ModDNResponseDsml(
404                container.getLdapCodecService(), new ModifyDnResponseImpl() );
405            container.getBatchResponse().addResponse( modDNResponse );
406
407            LdapResult ldapResult = modDNResponse.getLdapResult();
408
409            XmlPullParser xpp = container.getParser();
410
411            // Checking and adding the batchRequest's attributes
412            String attributeValue;
413            // requestID
414            attributeValue = xpp.getAttributeValue( "", "requestID" );
415
416            if ( attributeValue != null )
417            {
418                modDNResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
419            }
420
421            // MatchedDN
422            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
423
424            if ( attributeValue != null )
425            {
426                try
427                {
428                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
429                }
430                catch ( LdapInvalidDnException lide )
431                {
432                    throw new XmlPullParserException( lide.getMessage(), xpp, lide );
433                }
434            }
435        }
436    };
437
438    /**
439     * GrammarAction that creates the Extended Response
440     */
441    private final GrammarAction extendedResponseCreation = new GrammarAction( "Create Extended Response" )
442    {
443        /**
444         * {@inheritDoc}
445         */
446        @Override
447        public void action( Dsmlv2Container container ) throws XmlPullParserException
448        {
449            ExtendedResponseDsml extendedResponse;
450
451            // Checking and adding the batchRequest's attributes
452            String attributeValue;
453
454            XmlPullParser xpp = container.getParser();
455
456            // requestID
457            attributeValue = xpp.getAttributeValue( "", "requestID" );
458
459            if ( attributeValue != null )
460            {
461                extendedResponse = new ExtendedResponseDsml(
462                    container.getLdapCodecService(), new OpaqueExtendedResponse(
463                        ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) ) );
464            }
465            else
466            {
467                extendedResponse = new ExtendedResponseDsml(
468                    container.getLdapCodecService(), new OpaqueExtendedResponse( -1 ) );
469            }
470
471            container.getBatchResponse().addResponse( extendedResponse );
472
473            LdapResult ldapResult = extendedResponse.getLdapResult();
474
475            // MatchedDN
476            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
477
478            if ( attributeValue != null )
479            {
480                try
481                {
482                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
483                }
484                catch ( LdapInvalidDnException lide )
485                {
486                    throw new XmlPullParserException( lide.getMessage(), xpp, lide );
487                }
488            }
489        }
490    };
491
492    /**
493     * GrammarAction that creates the Error Response
494     */
495    private final GrammarAction errorResponseCreation = new GrammarAction( "Create Error Response" )
496    {
497        /**
498         * {@inheritDoc}
499         */
500        @Override
501        public void action( Dsmlv2Container container ) throws XmlPullParserException
502        {
503            ErrorResponse errorResponse = null;
504            XmlPullParser xpp = container.getParser();
505
506            // Checking and adding the batchRequest's attributes
507            String attributeValue;
508
509            // requestID
510            attributeValue = xpp.getAttributeValue( "", "requestID" );
511
512            if ( attributeValue != null )
513            {
514                errorResponse = new ErrorResponse( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ), null );
515
516                container.getBatchResponse().addResponse( errorResponse );
517            }
518
519            // type
520            attributeValue = xpp.getAttributeValue( "", "type" );
521
522            if ( attributeValue != null )
523            {
524                if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.NOT_ATTEMPTED ) ) )
525                {
526                    errorResponse.setErrorType( ErrorResponseType.NOT_ATTEMPTED );
527                }
528                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.COULD_NOT_CONNECT ) ) )
529                {
530                    errorResponse.setErrorType( ErrorResponseType.COULD_NOT_CONNECT );
531                }
532                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.CONNECTION_CLOSED ) ) )
533                {
534                    errorResponse.setErrorType( ErrorResponseType.CONNECTION_CLOSED );
535                }
536                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.MALFORMED_REQUEST ) ) )
537                {
538                    errorResponse.setErrorType( ErrorResponseType.MALFORMED_REQUEST );
539                }
540                else if ( attributeValue
541                    .equals( errorResponse.getTypeDescr( ErrorResponseType.GATEWAY_INTERNAL_ERROR ) ) )
542                {
543                    errorResponse.setErrorType( ErrorResponseType.GATEWAY_INTERNAL_ERROR );
544                }
545                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.AUTHENTICATION_FAILED ) ) )
546                {
547                    errorResponse.setErrorType( ErrorResponseType.AUTHENTICATION_FAILED );
548                }
549                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.UNRESOLVABLE_URI ) ) )
550                {
551                    errorResponse.setErrorType( ErrorResponseType.UNRESOLVABLE_URI );
552                }
553                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.OTHER ) ) )
554                {
555                    errorResponse.setErrorType( ErrorResponseType.OTHER );
556                }
557                else
558                {
559                    throw new XmlPullParserException( I18n.err( I18n.ERR_03004_UNKNOWN_TYPE ), xpp, null );
560                }
561            }
562            else
563            {
564                throw new XmlPullParserException( I18n.err( I18n.ERR_03005_REQUIRE_ATTRIBUTE_TYPE ), xpp, null );
565            }
566        }
567    };
568
569    /**
570     * GrammarAction that adds Message to an Error Response
571     */
572    private final GrammarAction errorResponseAddMessage = new GrammarAction( "Add Message to Error Response" )
573    {
574        /**
575         * {@inheritDoc}
576         */
577        @Override
578        public void action( Dsmlv2Container container ) throws XmlPullParserException
579        {
580            ErrorResponse errorResponse = ( ErrorResponse ) container.getBatchResponse().getCurrentResponse();
581
582            XmlPullParser xpp = container.getParser();
583            try
584            {
585                String nextText = xpp.nextText();
586                if ( !Strings.isEmpty( nextText ) )
587                {
588                    errorResponse.setMessage( nextText.trim() );
589                }
590            }
591            catch ( IOException ioe )
592            {
593                throw new XmlPullParserException( ioe.getMessage(), xpp, ioe );
594            }
595        }
596    };
597
598    /**
599     * GrammarAction that adds Detail to an Error Response
600     */
601    // TODO Look for documentation about this Detail element (the DSML documentation doesn't give enough information)
602    private static final GrammarAction ERROR_RESPONSE_ADD_DETAIL = null;
603
604
605    /**
606     * GrammarAction that creates a Control for LDAP Result
607     */
608    private final GrammarAction ldapResultControlCreation = new GrammarAction( "Create Control for LDAP Result" )
609    {
610        /**
611         * {@inheritDoc}
612         */
613        @Override
614        public void action( Dsmlv2Container container ) throws XmlPullParserException
615        {
616            AbstractDsmlMessageDecorator<? extends Message> message =
617                ( AbstractDsmlMessageDecorator<? extends Message> )
618                container.getBatchResponse().getCurrentResponse();
619
620            if ( message instanceof SearchResponseDsml )
621            {
622                createAndAddControl( container,
623                    ( ( SearchResponse ) ( ( SearchResponseDsml ) message ).getDecorated() ).getSearchResultDone() );
624            }
625            else
626            {
627                createAndAddControl( container, message );
628            }
629        }
630    };
631
632    /**
633     * GrammarAction that creates a Control for Search Result Entry
634     */
635    private final GrammarAction searchResultEntryControlCreation = new GrammarAction(
636        "Create Control for Search Result Entry" )
637    {
638        /**
639         * {@inheritDoc}
640         */
641        @Override
642        public void action( Dsmlv2Container container ) throws XmlPullParserException
643        {
644            SearchResponse response = ( SearchResponse )
645                ( ( SearchResponseDsml ) container.getBatchResponse()
646                    .getCurrentResponse() ).getDecorated();
647
648            createAndAddControl( container, response.getCurrentSearchResultEntry() );
649        }
650    };
651
652    /**
653     * GrammarAction that creates a Control for Search Result Entry
654     */
655    private final GrammarAction searchResultReferenceControlCreation = new GrammarAction(
656        "Create Control for Search Result Reference" )
657    {
658        /**
659         * {@inheritDoc}
660         */
661        @Override
662        public void action( Dsmlv2Container container ) throws XmlPullParserException
663        {
664            SearchResponse response = ( SearchResponse )
665                ( ( SearchResponseDsml ) container.getBatchResponse()
666                    .getCurrentResponse() ).getDecorated();
667
668            createAndAddControl( container, response.getCurrentSearchResultReference() );
669        }
670    };
671
672    /**
673     * GrammarAction that creates a Control Value for LDAP Result
674     */
675    private final GrammarAction ldapResultControlValueCreation = new GrammarAction(
676        "Add ControlValue to Control for LDAP Result" )
677    {
678        /**
679         * {@inheritDoc}
680         */
681        @Override
682        public void action( Dsmlv2Container container ) throws XmlPullParserException
683        {
684            AbstractDsmlMessageDecorator<? extends Response> response
685            = ( AbstractDsmlMessageDecorator<? extends Response> )
686                container.getBatchResponse().getCurrentResponse();
687
688            if ( response instanceof SearchResponseDsml )
689            {
690                SearchResponse searchResponse = ( SearchResponse )
691                    response.getDecorated();
692                createAndAddControlValue( container,
693                    searchResponse.getSearchResultDone() );
694            }
695            else
696            {
697                createAndAddControlValue( container, response );
698            }
699        }
700    };
701
702    /**
703     * GrammarAction that creates a Control Value for Search Result Entry
704     */
705    private final GrammarAction searchResultEntryControlValueCreation = new GrammarAction(
706        "Add ControlValue to Control for Search Result Entry" )
707    {
708        /**
709         * {@inheritDoc}
710         */
711        @Override
712        public void action( Dsmlv2Container container ) throws XmlPullParserException
713        {
714            SearchResponse response = ( SearchResponse )
715                container.getBatchResponse().getCurrentResponse().getDecorated();
716            createAndAddControlValue( container,
717                response.getCurrentSearchResultEntry() );
718        }
719    };
720
721    /**
722     * GrammarAction that creates a Control Value for Search Result Reference
723     */
724    private final GrammarAction searchResultReferenceControlValueCreation = new GrammarAction(
725        "Add ControlValue to Control for Search Result Entry" )
726    {
727        /**
728         * {@inheritDoc}
729         */
730        @Override
731        public void action( Dsmlv2Container container ) throws XmlPullParserException
732        {
733            SearchResponseDsml response = ( SearchResponseDsml )
734                container.getBatchResponse().getCurrentResponse();
735            createAndAddControlValue( container,
736                ( ( SearchResponse ) response.getDecorated() ).getCurrentSearchResultReference() );
737        }
738    };
739
740    /**
741     * GrammarAction that adds a Result Code to a LDAP Result
742     */
743    private final GrammarAction ldapResultAddResultCode = new GrammarAction( "Add ResultCode to LDAP Result" )
744    {
745        /**
746         * {@inheritDoc}
747         */
748        @Override
749        public void action( Dsmlv2Container container ) throws XmlPullParserException
750        {
751            DsmlDecorator<? extends Response> ldapResponse =
752                container.getBatchResponse().getCurrentResponse();
753
754            LdapResult ldapResult;
755
756            // Search Response is a special case
757            // ResultCode can only occur in a case of Search Result Done in a Search Response
758            if ( ldapResponse.getDecorated() instanceof SearchResponse )
759            {
760                SearchResponse searchResponse = ( SearchResponse ) ldapResponse.getDecorated();
761                ldapResult = searchResponse.getSearchResultDone().getLdapResult();
762            }
763            else
764            {
765                ldapResult = ( ( ResultResponse ) ldapResponse.getDecorated() ).getLdapResult();
766            }
767
768            XmlPullParser xpp = container.getParser();
769
770            // Checking and adding the request's attributes
771            String attributeValue;
772            // code
773            attributeValue = xpp.getAttributeValue( "", "code" );
774
775            if ( attributeValue != null )
776            {
777                try
778                {
779                    ldapResult.setResultCode( ResultCodeEnum.getResultCode( Integer.parseInt( attributeValue ) ) );
780                }
781                catch ( NumberFormatException nfe )
782                {
783                    throw new XmlPullParserException( I18n.err( I18n.ERR_03009_RESULT_CODE_NOT_INTEGER ), xpp, nfe );
784                }
785            }
786            else
787            {
788                throw new XmlPullParserException( I18n.err( I18n.ERR_03010_CODE_ATTRIBUTE_REQUIRED ), xpp, null );
789            }
790
791            // descr
792            attributeValue = xpp.getAttributeValue( "", "descr" );
793
794            if ( ( attributeValue != null ) && !DSMLV2_DESCR_TAGS.contains( attributeValue ) )
795            {
796                throw new XmlPullParserException( I18n.err( I18n.ERR_03011_DESCR_DOESNT_MATCH_VALUES, attributeValue ), xpp, null );
797            }
798        }
799    };
800
801    /**
802     * GrammarAction that adds a Error Message to a LDAP Result
803     */
804    private final GrammarAction ldapResultAddErrorMessage = new GrammarAction( "Add Error Message to LDAP Result" )
805    {
806        /**
807         * {@inheritDoc}
808         */
809        @Override
810        public void action( Dsmlv2Container container ) throws XmlPullParserException
811        {
812            DsmlDecorator<? extends Response> ldapResponse =
813                container.getBatchResponse().getCurrentResponse();
814
815            LdapResult ldapResult;
816
817            // Search Response is a special case
818            // ResultCode can only occur in a case of Search Result Done in a Search Response
819            if ( ldapResponse.getDecorated() instanceof SearchResponse )
820            {
821                SearchResponse searchResponse = ( SearchResponse ) ldapResponse.getDecorated();
822                ldapResult = searchResponse.getSearchResultDone().getLdapResult();
823            }
824            else
825            {
826                ldapResult = ( ( ResultResponse ) ldapResponse.getDecorated() ).getLdapResult();
827            }
828
829            XmlPullParser xpp = container.getParser();
830
831            try
832            {
833                String nextText = xpp.nextText();
834
835                if ( !Strings.isEmpty( nextText ) )
836                {
837                    ldapResult.setDiagnosticMessage( nextText.trim() );
838                }
839            }
840            catch ( IOException ioe )
841            {
842                throw new XmlPullParserException( I18n.err( I18n.ERR_03008_UNEXPECTED_ERROR, ioe.getMessage() ), xpp, ioe );
843            }
844        }
845    };
846
847    /**
848     * GrammarAction that adds a Referral to a LDAP Result
849     */
850    private final GrammarAction ldapResultAddReferral = new GrammarAction( "Add Referral to LDAP Result" )
851    {
852        /**
853         * {@inheritDoc}
854         */
855        @Override
856        public void action( Dsmlv2Container container ) throws XmlPullParserException
857        {
858            DsmlDecorator<? extends Response> ldapResponse =
859                container.getBatchResponse().getCurrentResponse();
860
861            LdapResult ldapResult;
862
863            // Search Response is a special case
864            // ResultCode can only occur in a case of Search Result Done in a Search Response
865            if ( ldapResponse.getDecorated() instanceof SearchResponse )
866            {
867                SearchResponse searchResponse = ( SearchResponse ) ldapResponse.getDecorated();
868                ldapResult = searchResponse.getSearchResultDone().getLdapResult();
869            }
870            else
871            {
872                ldapResult = ( ( ResultResponse ) ldapResponse.getDecorated() ).getLdapResult();
873            }
874
875            // Initialization of the Referrals if needed
876            if ( ldapResult.getReferral() == null )
877            {
878                ldapResult.setReferral( new ReferralImpl() );
879            }
880
881            XmlPullParser xpp = container.getParser();
882
883            try
884            {
885                String nextText = xpp.nextText();
886
887                if ( !Strings.isEmpty( nextText ) )
888                {
889                    try
890                    {
891                        String urlStr = nextText.trim();
892                        LdapUrl ldapUrl = new LdapUrl( urlStr );
893                        ldapResult.getReferral().addLdapUrl( ldapUrl.toString() );
894                    }
895                    catch ( LdapURLEncodingException luee )
896                    {
897                        throw new XmlPullParserException( luee.getMessage(), xpp, luee );
898                    }
899                }
900            }
901            catch ( IOException ioe )
902            {
903                throw new XmlPullParserException( I18n.err( I18n.ERR_03008_UNEXPECTED_ERROR, ioe.getMessage() ), xpp, ioe );
904            }
905        }
906    };
907
908    /**
909     * GrammarAction that creates the Search Response
910     */
911    private final GrammarAction searchResponseCreation = new GrammarAction( "Create Search Response" )
912    {
913        /**
914         * {@inheritDoc}
915         */
916        @Override
917        public void action( Dsmlv2Container container ) throws XmlPullParserException
918        {
919            XmlPullParser xpp = container.getParser();
920            SearchResponse searchResponse;
921
922            // Checking and adding the batchRequest's attributes
923            String attributeValue = xpp.getAttributeValue( "", "requestID" );
924
925            if ( attributeValue != null )
926            {
927                searchResponse = new SearchResponse(
928                    ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
929            }
930            else
931            {
932                searchResponse = new SearchResponse();
933            }
934
935            container.getBatchResponse().addResponse( new SearchResponseDsml(
936                container.getLdapCodecService(), searchResponse ) );
937        }
938    };
939
940    /**
941     * GrammarAction that creates a Search Result Entry
942     */
943    private final GrammarAction searchResultEntryCreation = new GrammarAction(
944        "Add Search Result Entry to Search Response" )
945    {
946        /**
947         * {@inheritDoc}
948         */
949        @Override
950        public void action( Dsmlv2Container container ) throws XmlPullParserException
951        {
952            SearchResultEntryDsml searchResultEntry =
953                new SearchResultEntryDsml( container.getLdapCodecService(),
954                    new SearchResultEntryImpl() );
955            SearchResponseDsml searchResponse = ( SearchResponseDsml )
956                container.getBatchResponse().getCurrentResponse();
957            searchResponse.addResponse( searchResultEntry );
958
959            XmlPullParser xpp = container.getParser();
960
961            // Checking and adding the request's attributes
962            String attributeValue;
963            // requestID
964            attributeValue = xpp.getAttributeValue( "", "requestID" );
965
966            if ( attributeValue != null )
967            {
968                searchResultEntry.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
969            }
970
971            // dn
972            attributeValue = xpp.getAttributeValue( "", "dn" );
973
974            if ( attributeValue != null )
975            {
976                try
977                {
978                    searchResultEntry.setObjectName( new Dn( attributeValue ) );
979                }
980                catch ( LdapInvalidDnException lide )
981                {
982                    throw new XmlPullParserException( lide.getMessage(), xpp, lide );
983                }
984            }
985            else
986            {
987                throw new XmlPullParserException( "dn attribute is required", xpp, null );
988            }
989        }
990    };
991
992    /**
993     * GrammarAction that creates a Search Result Reference
994     */
995    private final GrammarAction searchResultReferenceCreation = new GrammarAction(
996        "Add Search Result Reference to Search Response" )
997    {
998        /**
999         * {@inheritDoc}
1000         */
1001        @Override
1002        public void action( Dsmlv2Container container ) throws XmlPullParserException
1003        {
1004            SearchResultReferenceDsml searchResultReference =
1005                new SearchResultReferenceDsml(
1006                    container.getLdapCodecService(),
1007                    new SearchResultReferenceImpl() );
1008
1009            SearchResponseDsml searchResponseDsml = ( SearchResponseDsml )
1010                container.getBatchResponse().getCurrentResponse();
1011
1012            searchResponseDsml.addResponse( searchResultReference );
1013
1014            XmlPullParser xpp = container.getParser();
1015
1016            // Checking and adding the request's attributes
1017            String attributeValue;
1018            // requestID
1019            attributeValue = xpp.getAttributeValue( "", "requestID" );
1020
1021            if ( attributeValue != null )
1022            {
1023                searchResultReference.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
1024            }
1025        }
1026    };
1027
1028    /**
1029     * GrammarAction that creates a Search Result Done
1030     */
1031    private final GrammarAction searchResultDoneCreation = new GrammarAction(
1032        "Add Search Result Done to Search Response" )
1033    {
1034        /**
1035         * {@inheritDoc}
1036         */
1037        @Override
1038        public void action( Dsmlv2Container container ) throws XmlPullParserException
1039        {
1040            SearchResultDoneDsml searchResultDone =
1041                new SearchResultDoneDsml( container.getLdapCodecService(),
1042                    new SearchResultDoneImpl() );
1043
1044            SearchResponseDsml searchResponseDsml = ( SearchResponseDsml )
1045                container.getBatchResponse().getCurrentResponse();
1046            searchResponseDsml.addResponse( searchResultDone );
1047
1048            XmlPullParser xpp = container.getParser();
1049
1050            // Checking and adding the batchRequest's attributes
1051            String attributeValue;
1052            // requestID
1053            attributeValue = xpp.getAttributeValue( "", "requestID" );
1054
1055            if ( attributeValue != null )
1056            {
1057                searchResultDone.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
1058            }
1059
1060            // MatchedDN
1061            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
1062
1063            if ( attributeValue != null )
1064            {
1065                try
1066                {
1067                    searchResultDone.getLdapResult().setMatchedDn( new Dn( attributeValue ) );
1068                }
1069                catch ( LdapInvalidDnException lide )
1070                {
1071                    throw new XmlPullParserException( lide.getMessage(), xpp, lide );
1072                }
1073            }
1074        }
1075    };
1076
1077    /**
1078     * GrammarAction that adds an Attr to a Search Result Entry
1079     */
1080    private final GrammarAction searchResultEntryAddAttr = new GrammarAction( "Add Attr to Search Result Entry" )
1081    {
1082        /**
1083         * {@inheritDoc}
1084         */
1085        @Override
1086        public void action( Dsmlv2Container container ) throws XmlPullParserException
1087        {
1088            SearchResponse searchResponse = ( SearchResponse )
1089                container.getBatchResponse().getCurrentResponse().getDecorated();
1090
1091            SearchResultEntryDsml searchResultEntry = searchResponse.getCurrentSearchResultEntry();
1092
1093            XmlPullParser xpp = container.getParser();
1094
1095            // Checking and adding the request's attributes
1096            String attributeValue;
1097            // name
1098            attributeValue = xpp.getAttributeValue( "", "name" );
1099
1100            if ( attributeValue != null )
1101            {
1102                try
1103                {
1104                    searchResultEntry.addAttribute( attributeValue );
1105                }
1106                catch ( LdapException le )
1107                {
1108                    throw new XmlPullParserException( I18n.err( I18n.ERR_03002_NAME_ATTRIBUTE_REQUIRED ), xpp, le );
1109                }
1110            }
1111            else
1112            {
1113                throw new XmlPullParserException( I18n.err( I18n.ERR_03002_NAME_ATTRIBUTE_REQUIRED ), xpp, null );
1114            }
1115        }
1116    };
1117
1118    /**
1119     * GrammarAction that adds a Value to an Attr of a Search Result Entry
1120     */
1121    private final GrammarAction searchResultEntryAddValue = new GrammarAction(
1122        "Add a Value to an Attr of a Search Result Entry" )
1123    {
1124        /**
1125         * {@inheritDoc}
1126         */
1127        @Override
1128        public void action( Dsmlv2Container container ) throws XmlPullParserException
1129        {
1130            SearchResponse searchResponse = ( SearchResponse )
1131                container.getBatchResponse().getCurrentResponse().getDecorated();
1132            SearchResultEntryDsml searchResultEntry = searchResponse.getCurrentSearchResultEntry();
1133
1134            XmlPullParser xpp = container.getParser();
1135
1136            try
1137            {
1138                // We have to catch the type Attribute Value before going to the next Text node
1139                String typeValue = ParserUtils.getXsiTypeAttributeValue( xpp );
1140
1141                // Getting the value
1142                String nextText = xpp.nextText();
1143
1144                try
1145                {
1146                    if ( ParserUtils.isBase64BinaryValue( xpp, typeValue ) )
1147                    {
1148                        searchResultEntry.addAttributeValue( Base64.decode( nextText.toCharArray() ) );
1149                    }
1150                    else
1151                    {
1152                        searchResultEntry.addAttributeValue( nextText );
1153                    }
1154                }
1155                catch ( LdapException le )
1156                {
1157                    throw new XmlPullParserException( le.getMessage(), xpp, le );
1158                }
1159            }
1160            catch ( IOException ioe )
1161            {
1162                throw new XmlPullParserException( I18n.err( I18n.ERR_03008_UNEXPECTED_ERROR, ioe.getMessage() ), xpp, ioe );
1163            }
1164        }
1165    };
1166
1167    /**
1168     * GrammarAction that adds a Ref to a Search Result Reference
1169     */
1170    private final GrammarAction searchResultReferenceAddRef = new GrammarAction(
1171        "Add a Ref to a Search Result Reference" )
1172    {
1173        /**
1174         * {@inheritDoc}
1175         */
1176        @Override
1177        public void action( Dsmlv2Container container ) throws XmlPullParserException
1178        {
1179            SearchResponse searchResponse = ( SearchResponse )
1180                container.getBatchResponse().getCurrentResponse().getDecorated();
1181            SearchResultReference searchResultReference = searchResponse.getCurrentSearchResultReference();
1182
1183            XmlPullParser xpp = container.getParser();
1184
1185            try
1186            {
1187                String nextText = xpp.nextText();
1188
1189                if ( !Strings.isEmpty( nextText ) )
1190                {
1191                    LdapUrl ldapUrl = new LdapUrl( nextText );
1192
1193                    searchResultReference.getReferral().addLdapUrl( ldapUrl.toString() );
1194                }
1195            }
1196            catch ( IOException ioe )
1197            {
1198                throw new XmlPullParserException( I18n.err( I18n.ERR_03008_UNEXPECTED_ERROR, ioe.getMessage() ), xpp, ioe );
1199            }
1200            catch ( LdapURLEncodingException luee )
1201            {
1202                throw new XmlPullParserException( luee.getMessage(), xpp, luee );
1203            }
1204        }
1205    };
1206
1207    /**
1208     * GrammarAction that adds Result Code to an Extended Response
1209     */
1210    private final GrammarAction extendedResponseAddResultCode = ldapResultAddResultCode;
1211
1212    /**
1213     * GrammarAction that creates the Search Response
1214     */
1215    private final GrammarAction extendedResponseAddErrorMessage = ldapResultAddErrorMessage;
1216
1217    /**
1218     * GrammarAction that adds a Referral to an Extended Response
1219     */
1220    private final GrammarAction extendedResponseAddReferral = ldapResultAddReferral;
1221
1222    /**
1223     * GrammarAction that adds a Response Name to an Extended Response
1224     */
1225    private final GrammarAction extendedResponseAddResponseName = new GrammarAction(
1226        "Add Response Name to Extended Response" )
1227    {
1228        /**
1229         * {@inheritDoc}
1230         */
1231        @Override
1232        public void action( Dsmlv2Container container ) throws XmlPullParserException
1233        {
1234            ExtendedResponse extendedResponse = ( ExtendedResponse ) container.getBatchResponse().getCurrentResponse();
1235
1236            XmlPullParser xpp = container.getParser();
1237
1238            try
1239            {
1240                String nextText = xpp.nextText();
1241
1242                if ( !Strings.isEmpty( nextText ) )
1243                {
1244                    extendedResponse.setResponseName( Oid.fromString( nextText.trim() ).toString() );
1245                }
1246
1247            }
1248            catch ( IOException ioe )
1249            {
1250                throw new XmlPullParserException( I18n.err( I18n.ERR_03008_UNEXPECTED_ERROR, ioe.getMessage() ), xpp, ioe );
1251            }
1252            catch ( DecoderException de )
1253            {
1254                throw new XmlPullParserException( de.getMessage(), xpp, de );
1255            }
1256        }
1257    };
1258
1259    /**
1260     * GrammarAction that adds a Response to an Extended Response
1261     */
1262    private final GrammarAction extendedResponseAddResponse = new GrammarAction( "Add Response to Extended Response" )
1263    {
1264        /**
1265         * {@inheritDoc}
1266         */
1267        @Override
1268        public void action( Dsmlv2Container container ) throws XmlPullParserException
1269        {
1270            ExtendedResponseDsml extendedResponse = ( ExtendedResponseDsml ) container.getBatchResponse()
1271                .getCurrentResponse();
1272
1273            XmlPullParser xpp = container.getParser();
1274
1275            try
1276            {
1277                // We have to catch the type Attribute Value before going to the next Text node
1278                String typeValue = ParserUtils.getXsiTypeAttributeValue( xpp );
1279
1280                // Getting the value
1281                String nextText = xpp.nextText();
1282
1283                if ( ParserUtils.isBase64BinaryValue( xpp, typeValue ) )
1284                {
1285                    extendedResponse.setResponseValue( Base64.decode( nextText.trim().toCharArray() ) );
1286                }
1287                else
1288                {
1289                    extendedResponse.setResponseValue( Strings.getBytesUtf8( nextText.trim() ) );
1290                }
1291            }
1292            catch ( IOException ioe )
1293            {
1294                throw new XmlPullParserException( I18n.err( I18n.ERR_03008_UNEXPECTED_ERROR, ioe.getMessage() ), xpp, ioe );
1295            }
1296        }
1297    };
1298
1299
1300    @SuppressWarnings("unchecked")
1301    private Dsmlv2ResponseGrammar()
1302    {
1303        name = Dsmlv2ResponseGrammar.class.getName();
1304
1305        // Create the transitions table
1306        super.transitions = ( HashMap<Tag, GrammarTransition>[] ) Array.newInstance( HashMap.class, 300 );
1307
1308        //====================================================
1309        //  Transitions concerning : BATCH RESPONSE
1310        //====================================================
1311        super.transitions[Dsmlv2StatesEnum.INIT_GRAMMAR_STATE.ordinal()] = new HashMap<Tag, GrammarTransition>();
1312
1313        // ** OPEN BATCH Reponse **
1314        // State: [INIT_GRAMMAR_STATE] - Tag: <batchResponse>
1315        super.transitions[Dsmlv2StatesEnum.INIT_GRAMMAR_STATE.ordinal()].put( new Tag( "batchResponse", Tag.START ),
1316            new GrammarTransition( Dsmlv2StatesEnum.INIT_GRAMMAR_STATE, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1317                batchResponseCreation ) );
1318
1319        //====================================================
1320        //  Transitions concerning : BATCH RESPONSE LOOP
1321        //====================================================
1322        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()] = new HashMap<Tag, GrammarTransition>();
1323
1324        // State: [BATCH_RESPONSE_LOOP] - Tag: <addResponse>
1325        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "addResponse", Tag.START ),
1326            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
1327                addResponseCreation ) );
1328
1329        // State: [BATCH_RESPONSE_LOOP] - Tag: <authResponse>
1330        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "authResponse", Tag.START ),
1331            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
1332                authResponseCreation ) );
1333
1334        // State: [BATCH_RESPONSE_LOOP] - Tag: <compareResponse>
1335        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "compareResponse", Tag.START ),
1336            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
1337                compareResponseCreation ) );
1338
1339        // State: [BATCH_RESPONSE_LOOP] - Tag: <delResponse>
1340        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "delResponse", Tag.START ),
1341            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
1342                delResponseCreation ) );
1343
1344        // State: [BATCH_RESPONSE_LOOP] - Tag: <modifyResponse>
1345        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "modifyResponse", Tag.START ),
1346            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
1347                modifyResponseCreation ) );
1348
1349        // State: [BATCH_RESPONSE_LOOP] - Tag: <modDNResponse>
1350        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "modDNResponse", Tag.START ),
1351            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
1352                modDNResponseCreation ) );
1353
1354        // State: [BATCH_RESPONSE_LOOP] - Tag: <extendedResponse>
1355        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put(
1356            new Tag( "extendedResponse", Tag.START ),
1357            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.EXTENDED_RESPONSE,
1358                extendedResponseCreation ) );
1359
1360        // State: [BATCH_RESPONSE_LOOP] - Tag: <errorResponse>
1361        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "errorResponse", Tag.START ),
1362            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.ERROR_RESPONSE,
1363                errorResponseCreation ) );
1364
1365        // State: [BATCH_RESPONSE_LOOP] - Tag: <searchReponse>
1366        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "searchResponse", Tag.START ),
1367            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.SEARCH_RESPONSE,
1368                searchResponseCreation ) );
1369
1370        // State: [BATCH_RESPONSE_LOOP] - Tag: </batchResponse>
1371        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "batchResponse", Tag.END ),
1372            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.GRAMMAR_END, null ) );
1373
1374        //====================================================
1375        //  Transitions concerning : ERROR RESPONSE
1376        //====================================================
1377        super.transitions[Dsmlv2StatesEnum.ERROR_RESPONSE.ordinal()] = new HashMap<Tag, GrammarTransition>();
1378        super.transitions[Dsmlv2StatesEnum.MESSAGE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1379        super.transitions[Dsmlv2StatesEnum.DETAIL_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
1380        super.transitions[Dsmlv2StatesEnum.DETAIL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1381
1382        // State: [ERROR_RESPONSE] - Tag: <message>
1383        super.transitions[Dsmlv2StatesEnum.ERROR_RESPONSE.ordinal()].put( new Tag( "message", Tag.START ),
1384            new GrammarTransition(
1385                Dsmlv2StatesEnum.ERROR_RESPONSE, Dsmlv2StatesEnum.MESSAGE_END, errorResponseAddMessage ) );
1386
1387        // State: [ERROR_RESPONSE] - Tag: <detail>
1388        super.transitions[Dsmlv2StatesEnum.ERROR_RESPONSE.ordinal()].put( new Tag( "detail", Tag.START ),
1389            new GrammarTransition(
1390                Dsmlv2StatesEnum.ERROR_RESPONSE, Dsmlv2StatesEnum.DETAIL_START, ERROR_RESPONSE_ADD_DETAIL ) );
1391
1392        // State: [MESSAGE_END] - Tag: </errorResponse>
1393        super.transitions[Dsmlv2StatesEnum.MESSAGE_END.ordinal()].put( new Tag( "errorResponse", Tag.END ),
1394            new GrammarTransition( Dsmlv2StatesEnum.MESSAGE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1395
1396        // State: [MESSAGE_END] - Tag: <detail>
1397        super.transitions[Dsmlv2StatesEnum.MESSAGE_END.ordinal()].put( new Tag( "detail", Tag.START ),
1398            new GrammarTransition(
1399                Dsmlv2StatesEnum.MESSAGE_END, Dsmlv2StatesEnum.DETAIL_START, ERROR_RESPONSE_ADD_DETAIL ) );
1400
1401        // State: [DETAIL_START] - Tag: </detail>
1402        super.transitions[Dsmlv2StatesEnum.DETAIL_START.ordinal()].put( new Tag( "detail", Tag.END ),
1403            new GrammarTransition(
1404                Dsmlv2StatesEnum.DETAIL_START, Dsmlv2StatesEnum.DETAIL_END, null ) );
1405
1406        // State: [DETAIL_END] - Tag: <detail>
1407        super.transitions[Dsmlv2StatesEnum.DETAIL_END.ordinal()].put( new Tag( "detail", Tag.END ),
1408            new GrammarTransition(
1409                Dsmlv2StatesEnum.DETAIL_END, Dsmlv2StatesEnum.DETAIL_END, ERROR_RESPONSE_ADD_DETAIL ) );
1410
1411        // State: [ERROR_RESPONSE] - Tag: </errorResponse>
1412        super.transitions[Dsmlv2StatesEnum.ERROR_RESPONSE.ordinal()].put( new Tag( "errorResponse", Tag.END ),
1413            new GrammarTransition( Dsmlv2StatesEnum.ERROR_RESPONSE, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1414
1415        //====================================================
1416        //  Transitions concerning : EXTENDED RESPONSE
1417        //====================================================
1418        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE.ordinal()] = new HashMap<Tag, GrammarTransition>();
1419        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
1420        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1421        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_VALUE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1422        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
1423        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1424        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1425        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1426        super.transitions[Dsmlv2StatesEnum.RESPONSE_NAME_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1427        super.transitions[Dsmlv2StatesEnum.RESPONSE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1428
1429        // State: [EXTENDED_RESPONSE] - Tag: <control>
1430        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE.ordinal()].put( new Tag( "control", Tag.START ),
1431            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE,
1432                Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START, ldapResultControlCreation ) );
1433
1434        // State: [EXTENDED_RESPONSE_CONTROL_START] - Tag: <controlValue>
1435        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START.ordinal()].put( new Tag( "controlValue",
1436            Tag.START ),
1437            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START,
1438                Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_VALUE_END, ldapResultControlValueCreation ) );
1439
1440        // State: [EXTENDED_RESPONSE_CONTROL_VALUE_END] - Tag: </control>
1441        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_VALUE_END.ordinal()].put( new Tag( "control",
1442            Tag.END ),
1443            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_VALUE_END,
1444                Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END, null ) );
1445
1446        // State: [EXTENDED_RESPONSE_CONTROL_START] - Tag: </control>
1447        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START.ordinal()].put(
1448            new Tag( "control", Tag.END ),
1449            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START,
1450                Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END, null ) );
1451
1452        // State: [EXTENDED_RESPONSE_CONTROL_END] - Tag: <control>
1453        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END.ordinal()].put(
1454            new Tag( "control", Tag.START ),
1455            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END,
1456                Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START, ldapResultControlCreation ) );
1457
1458        // State: [EXTENDED_RESPONSE_CONTROL_END] - Tag: <resultCode>
1459        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END.ordinal()].put( new Tag( "resultCode",
1460            Tag.START ),
1461            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END,
1462                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_START, extendedResponseAddResultCode ) );
1463
1464        // State: [EXTENDED_RESPONSE] - Tag: <resultCode>
1465        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE.ordinal()].put( new Tag( "resultCode", Tag.START ),
1466            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE,
1467                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_START, extendedResponseAddResultCode ) );
1468
1469        // State: [EXTENDED_RESPONSE_RESULT_CODE_START] - Tag: </resultCode>
1470        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_START.ordinal()].put( new Tag( "resultCode",
1471            Tag.END ),
1472            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_START,
1473                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END, null ) );
1474
1475        // State: [EXTENDED_RESPONSE_RESULT_CODE_END] - Tag: <errorMessage>
1476        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()].put(
1477            new Tag( "errorMessage", Tag.START ), new GrammarTransition(
1478                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END,
1479                Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END, extendedResponseAddErrorMessage ) );
1480
1481        // State: [EXTENDED_RESPONSE_RESULT_CODE_END] - Tag: <referral>
1482        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()].put( new Tag( "referral",
1483            Tag.START ),
1484            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END,
1485                Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END, extendedResponseAddReferral ) );
1486
1487        // State: [EXTENDED_RESPONSE_RESULT_CODE_END] - Tag: <responseName>
1488        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()].put(
1489            new Tag( "responseName", Tag.START ), new GrammarTransition(
1490                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END, Dsmlv2StatesEnum.RESPONSE_NAME_END,
1491                extendedResponseAddResponseName ) );
1492
1493        // State: [EXTENDED_RESPONSE_RESULT_CODE_END] - Tag: <response>
1494        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()].put( new Tag( "response",
1495            Tag.START ),
1496            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END, Dsmlv2StatesEnum.RESPONSE_END,
1497                extendedResponseAddResponse ) );
1498
1499        // State: [EXTENDED_RESPONSE_RESULT_CODE_END] - Tag: </extendedResponse>
1500        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()].put(
1501            new Tag( "extendedResponse", Tag.END ), new GrammarTransition(
1502                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1503
1504        // State: [EXTENDED_RESPONSE_ERROR_MESSAGE_END] - Tag: <referral>
1505        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END.ordinal()].put( new Tag( "referral",
1506            Tag.START ),
1507            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END,
1508                Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END, extendedResponseAddReferral ) );
1509
1510        // State: [EXTENDED_RESPONSE_ERROR_MESSAGE_END] - Tag: <responseName>
1511        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END.ordinal()].put(
1512            new Tag( "responseName", Tag.START ), new GrammarTransition(
1513                Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END, Dsmlv2StatesEnum.RESPONSE_NAME_END,
1514                extendedResponseAddResponseName ) );
1515
1516        // State: [EXTENDED_RESPONSE_ERROR_MESSAGE_END] - Tag: <response>
1517        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END.ordinal()].put( new Tag( "response",
1518            Tag.START ),
1519            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END, Dsmlv2StatesEnum.RESPONSE_END,
1520                extendedResponseAddResponse ) );
1521
1522        // State: [EXTENDED_RESPONSE_ERROR_MESSAGE_END] - Tag: </extendedResponse>
1523        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END.ordinal()].put( new Tag(
1524            "extendedResponse",
1525            Tag.END ), new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END,
1526            Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1527
1528        // State: [EXTENDED_RESPONSE_REFERRAL_END] - Tag: <referral>
1529        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END.ordinal()].put( new Tag( "referral",
1530            Tag.START ),
1531            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END,
1532                Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END, extendedResponseAddReferral ) );
1533
1534        // State: [EXTENDED_RESPONSE_REFERRAL_END] - Tag: <responseName>
1535        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END.ordinal()].put( new Tag( "responseName",
1536            Tag.START ),
1537            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END, Dsmlv2StatesEnum.RESPONSE_NAME_END,
1538                extendedResponseAddResponseName ) );
1539
1540        // State: [EXTENDED_RESPONSE_REFERRAL_END] - Tag: <reponse>
1541        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END.ordinal()].put(
1542            new Tag( "reponse", Tag.START ),
1543            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END, Dsmlv2StatesEnum.RESPONSE_END,
1544                extendedResponseAddResponse ) );
1545
1546        // State: [EXTENDED_RESPONSE_REFERRAL_END] - Tag: </extendedResponse>
1547        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END.ordinal()].put( new Tag( "extendedResponse",
1548            Tag.END ),
1549            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END,
1550                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1551
1552        // State: [RESPONSE_NAME_END] - Tag: <response>
1553        super.transitions[Dsmlv2StatesEnum.RESPONSE_NAME_END.ordinal()].put( new Tag( "response", Tag.START ),
1554            new GrammarTransition( Dsmlv2StatesEnum.RESPONSE_NAME_END, Dsmlv2StatesEnum.RESPONSE_END,
1555                extendedResponseAddResponse ) );
1556
1557        // State: [RESPONSE_NAME_END] - Tag: </extendedResponse>
1558        super.transitions[Dsmlv2StatesEnum.RESPONSE_NAME_END.ordinal()].put( new Tag( "extendedResponse", Tag.END ),
1559            new GrammarTransition( Dsmlv2StatesEnum.RESPONSE_NAME_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1560
1561        // State: [RESPONSE_END] - Tag: </extendedResponse>
1562        super.transitions[Dsmlv2StatesEnum.RESPONSE_END.ordinal()].put( new Tag( "extendedResponse", Tag.END ),
1563            new GrammarTransition( Dsmlv2StatesEnum.RESPONSE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1564
1565        //====================================================
1566        //  Transitions concerning : LDAP RESULT
1567        //====================================================
1568        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT.ordinal()] = new HashMap<Tag, GrammarTransition>();
1569        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
1570        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1571        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_VALUE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1572        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
1573        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1574        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1575        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1576        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1577
1578        // State: [LDAP_RESULT] - Tag: <control>
1579        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT.ordinal()].put( new Tag( "control", Tag.START ),
1580            new GrammarTransition(
1581                Dsmlv2StatesEnum.LDAP_RESULT, Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START, ldapResultControlCreation ) );
1582
1583        // State: [LDAP_RESULT] - Tag: <resultCode>
1584        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT.ordinal()]
1585            .put( new Tag( "resultCode", Tag.START ), new GrammarTransition(
1586                Dsmlv2StatesEnum.LDAP_RESULT, Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_START, ldapResultAddResultCode ) );
1587
1588        // State: [LDAP_RESULT_CONTROL_START] - Tag: <controlValue>
1589        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START.ordinal()].put(
1590            new Tag( "controlValue", Tag.START ),
1591            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START,
1592                Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_VALUE_END, ldapResultControlValueCreation ) );
1593
1594        // State: [LDAP_RESULT_CONTROL_VALUE_END] - Tag: </control>
1595        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_VALUE_END.ordinal()].put( new Tag( "control", Tag.END ),
1596            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_VALUE_END,
1597                Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END, null ) );
1598
1599        // State: [LDAP_RESULT_CONTROL_START] - Tag: </control>
1600        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START.ordinal()].put( new Tag( "control", Tag.END ),
1601            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START,
1602                Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END, null ) );
1603
1604        // State: [LDAP_RESULT_CONTROL_END] - Tag: <control>
1605        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END.ordinal()].put( new Tag( "control", Tag.START ),
1606            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END,
1607                Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START, ldapResultControlCreation ) );
1608
1609        // State: [LDAP_RESULT_CONTROL_END] - Tag: <resultCode>
1610        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END.ordinal()].put( new Tag( "resultCode", Tag.START ),
1611            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END,
1612                Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_START, ldapResultAddResultCode ) );
1613
1614        // State: [LDAP_RESULT_RESULT_CODE_START] - Tag: </resultCode>
1615        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_START.ordinal()].put(
1616            new Tag( "resultCode", Tag.END ),
1617            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_START,
1618                Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, null ) );
1619
1620        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: <errorMessage>
1621        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put( new Tag( "errorMessage",
1622            Tag.START ),
1623            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END,
1624                Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END, ldapResultAddErrorMessage ) );
1625
1626        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: <referral>
1627        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put(
1628            new Tag( "referral", Tag.START ),
1629            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END,
1630                Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, ldapResultAddReferral ) );
1631
1632        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </addResponse>
1633        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put(
1634            new Tag( "addResponse", Tag.END ),
1635            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1636                null ) );
1637
1638        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </authResponse>
1639        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put(
1640            new Tag( "authResponse", Tag.END ),
1641            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1642                null ) );
1643
1644        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </compareResponse>
1645        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put( new Tag( "compareResponse",
1646            Tag.END ),
1647            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1648                null ) );
1649
1650        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </delResponse>
1651        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put(
1652            new Tag( "delResponse", Tag.END ),
1653            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1654                null ) );
1655
1656        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </modifyResponse>
1657        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put( new Tag( "modifyResponse",
1658            Tag.END ),
1659            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1660                null ) );
1661
1662        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </modDNResponse>
1663        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put( new Tag( "modDNResponse",
1664            Tag.END ),
1665            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1666                null ) );
1667
1668        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </searchResultDone>
1669        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put( new Tag( "searchResultDone",
1670            Tag.END ),
1671            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END,
1672                Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END, null ) );
1673
1674        // State: [SEARCH_RESULT_DONE_END] - Tag: </searchResponse>
1675        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END.ordinal()]
1676            .put( new Tag( "searchResponse", Tag.END ), new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END,
1677                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1678
1679        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: <referral>
1680        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put(
1681            new Tag( "referral", Tag.START ),
1682            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
1683                Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, ldapResultAddReferral ) );
1684
1685        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </addResponse>
1686        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "addResponse",
1687            Tag.END ),
1688            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
1689                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1690
1691        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </authResponse>
1692        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "authResponse",
1693            Tag.END ),
1694            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
1695                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1696
1697        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </compareResponse>
1698        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "compareResponse",
1699            Tag.END ),
1700            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
1701                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1702
1703        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </delResponse>
1704        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "delResponse",
1705            Tag.END ),
1706            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
1707                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1708
1709        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </modifyResponse>
1710        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "modifyResponse",
1711            Tag.END ),
1712            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
1713                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1714
1715        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </modDNResponse>
1716        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "modDNResponse",
1717            Tag.END ),
1718            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
1719                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
1720
1721        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </searchResultDone>
1722        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "searchResultDone",
1723            Tag.END ),
1724            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
1725                Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END, null ) );
1726
1727        // State: [LDAP_RESULT_REFERRAL_END] - Tag: <referral>
1728        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put( new Tag( "referral", Tag.START ),
1729            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END,
1730                Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, ldapResultAddReferral ) );
1731
1732        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </addResponse>
1733        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put( new Tag( "addResponse", Tag.END ),
1734            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1735                null ) );
1736
1737        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </authResponse>
1738        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put( new Tag( "authResponse", Tag.END ),
1739            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1740                null ) );
1741
1742        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </compareResponse>
1743        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put(
1744            new Tag( "compareResponse", Tag.END ),
1745            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1746                null ) );
1747
1748        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </delResponse>
1749        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put( new Tag( "delResponse", Tag.END ),
1750            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1751                null ) );
1752
1753        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </modifyResponse>
1754        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put(
1755            new Tag( "modifyResponse", Tag.END ),
1756            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1757                null ) );
1758
1759        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </modDNResponse>
1760        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put(
1761            new Tag( "modDNResponse", Tag.END ),
1762            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
1763                null ) );
1764
1765        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </searchResultDone>
1766        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put( new Tag( "searchResultDone",
1767            Tag.END ),
1768            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END,
1769                null ) );
1770
1771        //====================================================
1772        //  Transitions concerning : SEARCH RESPONSE
1773        //====================================================
1774        super.transitions[Dsmlv2StatesEnum.SEARCH_RESPONSE.ordinal()] = new HashMap<Tag, GrammarTransition>();
1775
1776        // State: [SEARCH_REPONSE] - Tag: <searchResultEntry>
1777        super.transitions[Dsmlv2StatesEnum.SEARCH_RESPONSE.ordinal()].put( new Tag( "searchResultEntry", Tag.START ),
1778            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESPONSE, Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY,
1779                searchResultEntryCreation ) );
1780
1781        // State: [SEARCH_REPONSE] - Tag: <searchResultReference>
1782        super.transitions[Dsmlv2StatesEnum.SEARCH_RESPONSE.ordinal()].put(
1783            new Tag( "searchResultReference", Tag.START ),
1784            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESPONSE, Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE,
1785                searchResultReferenceCreation ) );
1786
1787        // State: [SEARCH_REPONSE] - Tag: <searchResultDone>
1788        super.transitions[Dsmlv2StatesEnum.SEARCH_RESPONSE.ordinal()].put( new Tag( "searchResultDone", Tag.START ),
1789            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESPONSE, Dsmlv2StatesEnum.LDAP_RESULT,
1790                searchResultDoneCreation ) );
1791
1792        //====================================================
1793        //  Transitions concerning : SEARCH RESULT ENTRY
1794        //====================================================
1795        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY.ordinal()] = new HashMap<Tag, GrammarTransition>();
1796        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
1797        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1798        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_VALUE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1799        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
1800        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1801        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1802
1803        // State: [SEARCH_RESULT_ENTRY] - Tag: <control>
1804        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY.ordinal()].put( new Tag( "control", Tag.START ),
1805            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY,
1806                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START, searchResultEntryControlCreation ) );
1807
1808        // State: [SEARCH_RESULT_ENTRY] - Tag: <attr>
1809        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY.ordinal()].put( new Tag( "attr", Tag.START ),
1810            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY,
1811                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START, searchResultEntryAddAttr ) );
1812
1813        // State: [SEARCH_RESULT_ENTRY] - Tag: </searchResultEntry>
1814        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY.ordinal()].put( new Tag( "searchResultEntry", Tag.END ),
1815            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY, Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP,
1816                null ) );
1817
1818        // State: [SEARCH_RESULT_ENTRY_CONTROL_START] - Tag: <controlValue>
1819        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START.ordinal()].put(
1820            new Tag( "controlValue", Tag.START ), new GrammarTransition(
1821                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START,
1822                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_VALUE_END, searchResultEntryControlValueCreation ) );
1823
1824        // State: [SEARCH_RESULT_ENTRY_CONTROL_VALUE_END] - Tag: </control>
1825        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_VALUE_END.ordinal()].put( new Tag( "control",
1826            Tag.END ),
1827            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_VALUE_END,
1828                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END, null ) );
1829
1830        // State: [SEARCH_RESULT_ENTRY_CONTROL_START] - Tag: </control>
1831        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START.ordinal()].put( new Tag( "control",
1832            Tag.END ),
1833            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START,
1834                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END, null ) );
1835
1836        // State: [SEARCH_RESULT_ENTRY_CONTROL_END] - Tag: <control>
1837        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END.ordinal()].put( new Tag( "control",
1838            Tag.START ),
1839            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END,
1840                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START, searchResultEntryControlCreation ) );
1841
1842        // State: [SEARCH_RESULT_ENTRY_CONTROL_END] - Tag: </searchResultEntry>
1843        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END.ordinal()].put(
1844            new Tag( "searchResultEntry", Tag.END ), new GrammarTransition(
1845                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END, Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP, null ) );
1846
1847        // State: [SEARCH_RESULT_ENTRY_CONTROL_END] - Tag: <attr>
1848        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END.ordinal()].put(
1849            new Tag( "attr", Tag.START ),
1850            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END,
1851                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START, null ) );
1852
1853        // State: [SEARCH_RESULT_ENTRY_ATTR_START] - Tag: </attr>
1854        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START.ordinal()].put( new Tag( "attr", Tag.END ),
1855            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START,
1856                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END, null ) );
1857
1858        // State: [SEARCH_RESULT_ENTRY_ATTR_START] - Tag: <value>
1859        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START.ordinal()].put(
1860            new Tag( "value", Tag.START ),
1861            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START,
1862                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END, searchResultEntryAddValue ) );
1863
1864        // State: [SEARCH_RESULT_ENTRY_ATTR_END] - Tag: <attr>
1865        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END.ordinal()].put( new Tag( "attr", Tag.START ),
1866            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END,
1867                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START, searchResultEntryAddAttr ) );
1868
1869        // State: [SEARCH_RESULT_ENTRY_ATTR_END] - Tag: </searchResultEntry>
1870        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END.ordinal()].put( new Tag( "searchResultEntry",
1871            Tag.END ),
1872            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END,
1873                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP, null ) );
1874
1875        // State: [SEARCH_RESULT_ENTRY_VALUE_END] - Tag: <value>
1876        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END.ordinal()].put( new Tag( "value", Tag.START ),
1877            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END,
1878                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END, searchResultEntryAddValue ) );
1879
1880        // State: [SEARCH_RESULT_ENTRY_VALUE_END] - Tag: </attr>
1881        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END.ordinal()].put( new Tag( "attr", Tag.END ),
1882            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END,
1883                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END, null ) );
1884
1885        //====================================================
1886        //  Transitions concerning : SEARCH RESULT ENTRY LOOP
1887        //====================================================
1888        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP.ordinal()] = new HashMap<Tag, GrammarTransition>();
1889
1890        // State: [SEARCH_RESULT_ENTRY_LOOP] - Tag: <searchResultEntry>
1891        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP.ordinal()].put( new Tag( "searchResultEntry",
1892            Tag.START ),
1893            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP, Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY,
1894                searchResultEntryCreation ) );
1895
1896        // State: [SEARCH_RESULT_ENTRY_LOOP] - Tag: <searchResultReference>
1897        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP.ordinal()].put(
1898            new Tag( "searchResultReference", Tag.START ), new GrammarTransition(
1899                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP, Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE,
1900                searchResultReferenceCreation ) );
1901
1902        // State: [SEARCH_RESULT_ENTRY_LOOP] - Tag: <searchResultDone>
1903        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP.ordinal()].put( new Tag( "searchResultDone",
1904            Tag.START ),
1905            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
1906                searchResultDoneCreation ) );
1907
1908        //====================================================
1909        //  Transitions concerning : SEARCH RESULT REFERENCE
1910        //====================================================
1911        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE.ordinal()] = new HashMap<Tag, GrammarTransition>();
1912        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
1913        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1914        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_VALUE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1915        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1916
1917        // State: [SEARCH_RESULT_REFERENCE] - Tag: <control>
1918        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE.ordinal()].put( new Tag( "control", Tag.START ),
1919            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE,
1920                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START, searchResultReferenceControlCreation ) );
1921
1922        // State: [SEARCH_RESULT_REFERENCE] - Tag: <ref>
1923        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE.ordinal()].put( new Tag( "ref", Tag.START ),
1924            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE,
1925                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END, searchResultReferenceAddRef ) );
1926
1927        // State: [SEARCH_RESULT_REFERENCE_CONTROL_START] - Tag: <controlValue>
1928        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START.ordinal()].put( new Tag(
1929            "controlValue",
1930            Tag.START ), new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START,
1931            Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_VALUE_END, searchResultReferenceControlValueCreation ) );
1932
1933        // State: [sEARCH_RESULT_REFERENCE_CONTROL_VALUE_END] - Tag: </control>
1934        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_VALUE_END.ordinal()].put(
1935            new Tag( "control", Tag.END ), new GrammarTransition(
1936                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_VALUE_END,
1937                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END, null ) );
1938
1939        // State: [SEARCH_RESULT_REFERENCE_CONTROL_START] - Tag: </control>
1940        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START.ordinal()].put( new Tag( "control",
1941            Tag.END ),
1942            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START,
1943                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END, null ) );
1944
1945        // State: [SEARCH_RESULT_REFERENCE_CONTROL_END] - Tag: <control>
1946        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END.ordinal()].put( new Tag( "control",
1947            Tag.START ),
1948            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END,
1949                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START, searchResultReferenceControlCreation ) );
1950
1951        // State: [SEARCH_RESULT_REFERENCE_CONTROL_END] - Tag: <ref>
1952        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END.ordinal()].put( new Tag( "ref",
1953            Tag.START ),
1954            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END,
1955                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END, searchResultReferenceAddRef ) );
1956
1957        // State: [SEARCH_RESULT_REFERENCE_REF_END] - Tag: <ref>
1958        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END.ordinal()].put( new Tag( "ref", Tag.START ),
1959            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END,
1960                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END, searchResultReferenceAddRef ) );
1961
1962        // State: [SEARCH_RESULT_REFERENCE_REF_END] - Tag: </searchResultReference>
1963        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END.ordinal()].put( new Tag(
1964            "searchResultReference",
1965            Tag.END ), new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END,
1966            Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP, null ) );
1967
1968        //==========================================================
1969        //  Transitions concerning : SEARCH RESULT REFERENCE LOOP
1970        //==========================================================
1971        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP.ordinal()] = new HashMap<Tag, GrammarTransition>();
1972
1973        // State: [SEARCH_RESULT_REFERENCE_LOOP] - Tag: <searchResultReference>
1974        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP.ordinal()].put( new Tag(
1975            "searchResultReference",
1976            Tag.START ), new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP,
1977            Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE, searchResultReferenceCreation ) );
1978
1979        // State: [SEARCH_RESULT_REFERENCE_LOOP] - Tag: <searchResultDone>
1980        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP.ordinal()].put( new Tag( "searchResultDone",
1981            Tag.START ),
1982            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
1983                searchResultDoneCreation ) );
1984
1985        //------------------------------------------ handle SOAP envelopes --------------------------
1986        super.transitions[Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG.ordinal()] = new HashMap<Tag, GrammarTransition>();
1987        super.transitions[Dsmlv2StatesEnum.SOAP_HEADER_START_TAG.ordinal()] = new HashMap<Tag, GrammarTransition>();
1988        super.transitions[Dsmlv2StatesEnum.SOAP_HEADER_END_TAG.ordinal()] = new HashMap<Tag, GrammarTransition>();
1989        super.transitions[Dsmlv2StatesEnum.SOAP_BODY_START_TAG.ordinal()] = new HashMap<Tag, GrammarTransition>();
1990        super.transitions[Dsmlv2StatesEnum.SOAP_BODY_END_TAG.ordinal()] = new HashMap<Tag, GrammarTransition>();
1991
1992        super.transitions[Dsmlv2StatesEnum.GRAMMAR_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
1993
1994        // State: [INIT_GRAMMAR_STATE] - Tag: <envelope>
1995        super.transitions[Dsmlv2StatesEnum.INIT_GRAMMAR_STATE.ordinal()].put( new Tag( "envelope", Tag.START ),
1996            new GrammarTransition( Dsmlv2StatesEnum.INIT_GRAMMAR_STATE, Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG,
1997                null ) );
1998
1999        // state: [SOAP_ENVELOPE_START_TAG] -> Tag: <header>
2000        super.transitions[Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG.ordinal()].put( new Tag( "header", Tag.START ),
2001            new GrammarTransition( Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG, Dsmlv2StatesEnum.SOAP_HEADER_START_TAG,
2002                ParserUtils.READ_SOAP_HEADER ) );
2003
2004        // state: [SOAP_HEADER_START_TAG] -> Tag: </header>
2005        super.transitions[Dsmlv2StatesEnum.SOAP_HEADER_START_TAG.ordinal()]
2006            .put( new Tag( "header", Tag.END ),
2007                new GrammarTransition( Dsmlv2StatesEnum.SOAP_HEADER_START_TAG, Dsmlv2StatesEnum.SOAP_HEADER_END_TAG,
2008                    null ) );
2009
2010        // state: [SOAP_HEADER_END_TAG] -> Tag: <body>
2011        super.transitions[Dsmlv2StatesEnum.SOAP_HEADER_END_TAG.ordinal()].put( new Tag( "body", Tag.START ),
2012            new GrammarTransition( Dsmlv2StatesEnum.SOAP_HEADER_END_TAG, Dsmlv2StatesEnum.SOAP_BODY_START_TAG, null ) );
2013
2014        // state: [SOAP_BODY_START_TAG] -> Tag: <batchResponse>
2015        super.transitions[Dsmlv2StatesEnum.SOAP_BODY_START_TAG.ordinal()].put( new Tag( "batchResponse", Tag.START ),
2016            new GrammarTransition( Dsmlv2StatesEnum.SOAP_BODY_START_TAG, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
2017                batchResponseCreation ) );
2018
2019        // the optional transition if no soap header is present
2020        // state: [SOAP_ENVELOPE_START_TAG] -> Tag: <body>
2021        super.transitions[Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG.ordinal()]
2022            .put( new Tag( "body", Tag.START ),
2023                new GrammarTransition( Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG, Dsmlv2StatesEnum.SOAP_BODY_START_TAG,
2024                    null ) );
2025
2026        // the below two transitions are a bit unconventional, technically the container's state is set to GRAMMAR_END
2027        // when the </batchRequest> tag is encountered by the parser and the corresponding action gets executed but in
2028        // a SOAP envelop we still have two more end tags(</body> and </envelope>) are left so we set those corresponding
2029        // current and next transition states always to GRAMMAR_END
2030        super.transitions[Dsmlv2StatesEnum.GRAMMAR_END.ordinal()].put( new Tag( "body", Tag.END ),
2031            new GrammarTransition( Dsmlv2StatesEnum.GRAMMAR_END, Dsmlv2StatesEnum.GRAMMAR_END, null ) );
2032
2033        super.transitions[Dsmlv2StatesEnum.GRAMMAR_END.ordinal()].put( new Tag( "envelope", Tag.END ),
2034            new GrammarTransition( Dsmlv2StatesEnum.GRAMMAR_END, Dsmlv2StatesEnum.GRAMMAR_END, null ) );
2035
2036        //------------------------------------------
2037    }
2038
2039
2040    /**
2041     * Get the instance of this grammar
2042     *
2043     * @return
2044     *      an instance on this grammar
2045     */
2046    public static Dsmlv2ResponseGrammar getInstance()
2047    {
2048        return instance;
2049    }
2050
2051
2052    /**
2053     * Creates a Control Value parsing the current node and adds it to the given parent
2054     * @param container the DSMLv2Container
2055     * @param parent the parent
2056     * @throws XmlPullParserException When the parsing fails
2057     */
2058    private void createAndAddControlValue( Dsmlv2Container container,
2059        AbstractDsmlMessageDecorator<? extends Message> parent )
2060        throws XmlPullParserException
2061    {
2062        DsmlControl<? extends Control> control = parent.getCurrentControl();
2063
2064        XmlPullParser xpp = container.getParser();
2065        try
2066        {
2067            // We have to catch the type Attribute Value before going to the next Text node
2068            String typeValue = ParserUtils.getXsiTypeAttributeValue( xpp );
2069
2070            // Getting the value
2071            String nextText = xpp.nextText();
2072
2073            if ( !Strings.isEmpty( nextText ) )
2074            {
2075                if ( ParserUtils.isBase64BinaryValue( xpp, typeValue ) )
2076                {
2077                    control.setValue( Base64.decode( nextText.trim().toCharArray() ) );
2078                }
2079                else
2080                {
2081                    control.setValue( Strings.getBytesUtf8( nextText.trim() ) );
2082                }
2083            }
2084        }
2085        catch ( IOException ioe )
2086        {
2087            throw new XmlPullParserException( I18n.err( I18n.ERR_03008_UNEXPECTED_ERROR, ioe.getMessage() ), xpp, ioe );
2088        }
2089    }
2090
2091
2092    /**
2093     * Creates a Control parsing the current node and adds it to the given parent
2094     * @param container the DSMLv2Container
2095     * @param parent the parent
2096     * @throws XmlPullParserException When the parsing fails
2097     */
2098    private void createAndAddControl( Dsmlv2Container container,
2099        AbstractDsmlMessageDecorator<? extends Message> parent ) throws XmlPullParserException
2100    {
2101        Control control;
2102
2103        XmlPullParser xpp = container.getParser();
2104
2105        // Checking and adding the Control's attributes
2106        String attributeValue;
2107        // TYPE
2108        attributeValue = xpp.getAttributeValue( "", "type" );
2109
2110        if ( attributeValue != null )
2111        {
2112            if ( !Oid.isOid( attributeValue ) )
2113            {
2114                throw new XmlPullParserException( I18n.err( I18n.ERR_03006_INCORRECT_TYPE_ATTRIBUTE_VALUE ), xpp, null );
2115            }
2116
2117            ControlFactory<? extends Control> factory = container.getLdapCodecService().
2118                getRequestControlFactories().get( attributeValue );
2119            
2120            if ( factory == null )
2121            {
2122                control = new OpaqueControl( attributeValue );
2123            }
2124            else
2125            {
2126                control = factory.newControl();
2127            }
2128            
2129            parent.addControl( control );
2130        }
2131        else
2132        {
2133            throw new XmlPullParserException( I18n.err( I18n.ERR_03005_REQUIRE_ATTRIBUTE_TYPE ), xpp, null );
2134        }
2135
2136        // CRITICALITY
2137        attributeValue = xpp.getAttributeValue( "", "criticality" );
2138
2139        if ( attributeValue != null )
2140        {
2141            if ( "true".equals( attributeValue ) )
2142            {
2143                control.setCritical( true );
2144            }
2145            else if ( "false".equals( attributeValue ) )
2146            {
2147                control.setCritical( false );
2148            }
2149            else
2150            {
2151                throw new XmlPullParserException( I18n.err( I18n.ERR_03007_INCORRECT_CRITICALITY_VALUE ), xpp, null );
2152            }
2153        }
2154    }
2155}