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