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