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