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.request;
021
022
023import java.util.ArrayList;
024import java.util.List;
025
026import org.apache.directory.api.dsmlv2.DsmlDecorator;
027import org.apache.directory.api.dsmlv2.ParserUtils;
028import org.apache.directory.api.ldap.model.message.Request;
029import org.dom4j.Document;
030import org.dom4j.DocumentHelper;
031import org.dom4j.Element;
032
033
034/**
035 * This class represents the Batch Request. It can be used to generate an the XML String of a BatchRequest.
036 *
037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
038 */
039public class BatchRequestDsml
040{
041    /** The Requests list */
042    private List<DsmlDecorator<? extends Request>> requests;
043
044    /** The ID of the request */
045    private int requestID;
046
047    /** The type of processing of the Batch Request */
048    private Processing processing;
049
050    /** The type of on error handling */
051    private OnError onError;
052
053    /** The response order */
054    private ResponseOrder responseOrder;
055
056    /**
057     * This enum represents the different types of processing for a Batch Request 
058     *
059     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
060     */
061    public enum Processing
062    {
063        /** Sequential processing. */
064        SEQUENTIAL,
065        /** Parallel processing. */
066        PARALLEL
067    }
068
069    /**
070     * This enum represents the different types of on error handling for a BatchRequest
071     *
072     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
073         */
074    public enum OnError
075    {
076        /** Resume on error. */
077        RESUME,
078        /** Exit on error. */
079        EXIT
080    }
081
082    /**
083     * This enum represents the different types of response order for a Batch Request
084     *
085     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
086         */
087    public enum ResponseOrder
088    {
089        /** Sequential response order. */
090        SEQUENTIAL,
091        /** Unordered response order. */
092        UNORDERED
093    }
094
095    /**
096     * flag to indicate to store the request objects present in 
097     * this batch request. Default is true
098     */
099    private boolean storeReq = true;
100
101    private DsmlDecorator<? extends Request> currentReq;
102
103
104    /**
105     * Creates a new instance of BatchResponseDsml.
106     */
107    public BatchRequestDsml()
108    {
109        requests = new ArrayList<DsmlDecorator<? extends Request>>();
110        responseOrder = ResponseOrder.SEQUENTIAL;
111        processing = Processing.SEQUENTIAL;
112        onError = OnError.EXIT;
113    }
114
115
116    /**
117     * Gets the current request
118     *
119     * @return
120     *      the current request
121     */
122    public DsmlDecorator<? extends Request> getCurrentRequest()
123    {
124        return currentReq;
125    }
126
127
128    /**
129     * Adds a request to the Batch Request DSML.
130     *
131     * @param request
132     *      the request to add
133     * @return
134     *      true (as per the general contract of the Collection.add method).
135     */
136    public boolean addRequest( DsmlDecorator<? extends Request> request )
137    {
138        currentReq = request;
139
140        if ( storeReq )
141        {
142            return requests.add( request );
143        }
144        else
145        {
146            return true;
147        }
148    }
149
150
151    /**
152     * Removes a request from the Batch Request DSML.
153     *
154     * @param request
155     *      the request to remove
156     * @return
157     *      true if this list contained the specified element.
158     */
159    public boolean removeRequest( DsmlDecorator<? extends Request> request )
160    {
161        return requests.remove( request );
162    }
163
164
165    /**
166     * Gets the ID of the request
167     *
168     * @return
169     *      the ID of the request
170     */
171    public int getRequestID()
172    {
173        return requestID;
174    }
175
176
177    /**
178     * Sets the ID of the request
179     *
180     * @param requestID
181     *      the ID to set
182     */
183    public void setRequestID( int requestID )
184    {
185        this.requestID = requestID;
186    }
187
188
189    /**
190     * Gets the processing type of the request
191     *
192     * @return
193     *      the processing type of the request
194     */
195    public Processing getProcessing()
196    {
197        return processing;
198    }
199
200
201    /**
202     * Sets the processing type of the request
203     *
204     * @param processing
205     *      the processing type to set
206     */
207    public void setProcessing( Processing processing )
208    {
209        this.processing = processing;
210    }
211
212
213    /**
214     * Gets the on error handling type of the request
215     *
216     * @return
217     *      the on error handling type of the request
218     */
219    public OnError getOnError()
220    {
221        return onError;
222    }
223
224
225    /**
226     * Sets the on error handling type of the request
227     *
228     * @param onError
229     *      the on error handling type to set
230     */
231    public void setOnError( OnError onError )
232    {
233        this.onError = onError;
234    }
235
236
237    /**
238     * Gets the response order type of the request
239     *
240     * @return
241     *      the response order type of the request
242     */
243    public ResponseOrder getResponseOrder()
244    {
245        return responseOrder;
246    }
247
248
249    /**
250     * Sets the response order type of the request
251     *
252     * @param responseOrder
253     *      the response order type to set
254     */
255    public void setResponseOrder( ResponseOrder responseOrder )
256    {
257        this.responseOrder = responseOrder;
258    }
259
260
261    /**
262     * Gets the List of all the requests in the Batch Request
263     *
264     * @return the List of all the requests in the Batch Request
265     */
266    public List<DsmlDecorator<? extends Request>> getRequests()
267    {
268        return requests;
269    }
270
271
272    /**
273     * Converts this Batch Request to its XML representation in the DSMLv2 format.
274     * 
275     * @return the XML representation in DSMLv2 format
276     */
277    public String toDsml()
278    {
279        Document document = DocumentHelper.createDocument();
280        Element element = document.addElement( "batchRequest" );
281
282        // RequestID
283        if ( requestID != 0 )
284        {
285            element.addAttribute( "requestID", Integer.toString( requestID ) );
286        }
287
288        // ResponseOrder
289        if ( responseOrder == ResponseOrder.UNORDERED )
290        {
291            element.addAttribute( "responseOrder", "unordered" );
292        }
293
294        // Processing
295        if ( processing == Processing.PARALLEL )
296        {
297            element.addAttribute( "processing", "parallel" );
298        }
299
300        // On Error
301        if ( onError == OnError.RESUME )
302        {
303            element.addAttribute( "onError", "resume" );
304        }
305
306        // Requests
307        for ( DsmlDecorator<? extends Request> request : requests )
308        {
309            request.toDsml( element );
310        }
311
312        return ParserUtils.styleDocument( document ).asXML();
313    }
314
315
316    /**
317     * @return true if the request objects are stored, false otherwise
318     */
319    public boolean isStoringRequests()
320    {
321        return storeReq;
322    }
323
324
325    /**
326     * set the storeReq flag to turn on/off storing of request objects
327     * 
328     * Note: it is better to set this flag to false while processing large DSML 
329     * batch requests
330     *   
331     * @param storeReq Tells if the request objects must be stored or not
332     */
333    public void setStoreReq( boolean storeReq )
334    {
335        this.storeReq = storeReq;
336    }
337
338
339    /**
340     * {@inheritDoc}
341     */
342    @Override
343    public String toString()
344    {
345        StringBuffer sb = new StringBuffer();
346
347        sb.append( "[" );
348        sb.append( "processing: " ).append( processing );
349        sb.append( " - " );
350        sb.append( "onError: " ).append( onError );
351        sb.append( " - " );
352        sb.append( "responseOrder: " ).append( responseOrder );
353        sb.append( "]" );
354
355        return sb.toString();
356    }
357}