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