KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opensubsystems > patterns > ordereddata > util > OrderedDataUtils


1 /*
2  * Copyright (c) 2006 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: OrderedDataUtils.java,v 1.6 2007/01/07 06:14:32 bastafidli Exp $
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21
22 package org.opensubsystems.patterns.ordereddata.util;
23
24 import java.util.Collection JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28
29 import javax.servlet.http.HttpServletRequest JavaDoc;
30
31 import org.opensubsystems.core.data.DataObject;
32 import org.opensubsystems.core.util.DataObjectOrderingComparator;
33 import org.opensubsystems.core.util.DataObjectUtils;
34 import org.opensubsystems.core.www.WebCommonConstants;
35 import org.opensubsystems.patterns.ordereddata.data.OrderedData;
36
37 /**
38  * Utility methods for data object order manipulation.
39  *
40  * @version $Id: OrderedDataUtils.java,v 1.6 2007/01/07 06:14:32 bastafidli Exp $
41  * @author Julian Legeny
42  * @code.reviewer Miro Halas
43  * @code.reviewed 1.3 2006/04/28 01:48:15 jlegeny
44  */

45 public final class OrderedDataUtils
46 {
47    // Constants ////////////////////////////////////////////////////////////////
48

49    /**
50     * Postfix for name of the hidden variable for particular dataobject. This
51     * hidden parameter will store ordered items with belonging order number.
52     * Format will be following:
53     * ID1:ORDER_NUMBER1;...;IDn:ORDER_NUMBERn
54     */

55    public static final String JavaDoc ORDERED_ITEMS_POSTFIX = "_ORDERED_ITEMS";
56
57    // Constructor //////////////////////////////////////////////////////////////
58

59    /**
60     * Private constructor since this class cannot be instantiated
61     */

62    private OrderedDataUtils(
63    )
64    {
65       // Do nothing
66
}
67
68    // Public methods ///////////////////////////////////////////////////////////
69

70    /**
71     * Parse order numbers and set it up into collection of dataobject.
72     *
73     * @param hsrqRequest - HTTP request containing request parameter defining
74     * order of data objects. The value format is documented
75     * in ORDERED_ITEMS_POSTFIX.
76     * @param colDataObjects - collection of data objects whose order number
77     * needs to be updated from the values passed in the
78     * request. The collection will be also sorted by the
79     * order number
80     * @param strParamPrefix - prefix for hidden variable storing changed IDs. The
81     * prefix has to be followed by ORDERED_ITEMS_POSTFIX
82     * so that the whole request parameter name is prefix
83     * + postfix.
84     * @return Collection - the same collection of items that is passed in with
85     * each data object updated with order number value from
86     * the request and sorted by te order number
87     */

88    public static Collection JavaDoc updateOrder(
89       HttpServletRequest JavaDoc hsrqRequest,
90       Collection JavaDoc colDataObjects,
91       String JavaDoc strParamPrefix
92    )
93    {
94       // Get hidden variable storing orders for all items. Parse orders
95
// and change order number for each dataobject within the list.
96

97       StringBuffer JavaDoc sbParamName = new StringBuffer JavaDoc();
98       // construct name of hidden variable that stores orders
99
sbParamName.append(strParamPrefix);
100       sbParamName.append(ORDERED_ITEMS_POSTFIX);
101       
102       String JavaDoc strOrderedItems = hsrqRequest.getParameter(sbParamName.toString());
103       
104       if ((colDataObjects != null) && (!colDataObjects.isEmpty())
105           && (strOrderedItems != null) && (strOrderedItems.length() > 0))
106       {
107          // get orderable dataobject, parse particular order for it and set up
108
// order number value within this dataobject
109
Iterator JavaDoc itHelp;
110          OrderedData data = null;
111          for (itHelp = colDataObjects.iterator(); itHelp.hasNext();)
112          {
113             data = (OrderedData)itHelp.next();
114             // TODO: Performance: By calling this method in the loop we end up
115
// searching the strinf over and over. We may want to consider parsing
116
// the string only once to a map and then use direct lookup in the map.
117
data.setOrderNumber(getOrder(strOrderedItems,
118                                 ((DataObject)data).getId()));
119          }
120       }
121       // sort data by object number
122
Collections.sort((List JavaDoc)colDataObjects, OrderedDataComparator.getInstance());
123
124       // return the same collection of items updated with order number value
125
return colDataObjects;
126    }
127    
128    /**
129     * Get order number for specified id encoded in the specified string
130     *
131     * @param strOrderedItems - string specifying order of data objects identifiable
132     * by their ids. Format of the string is
133     * ID1:ORDER_NUMBER1;...;IDn:ORDER_NUMBERn
134     * @param iItemId - id of item for which we need to get order
135     * @return int - parsed order number for specified ID
136     */

137    public static int getOrder(
138       String JavaDoc strOrderedItems,
139       int iItemId
140    )
141    {
142       int iOrderReturn = 0;
143       
144       int iIndexStart = -1;
145       int iIndexEnd = -1;
146       
147       StringBuffer JavaDoc sbOrderedItems = new StringBuffer JavaDoc();
148       StringBuffer JavaDoc sbId = new StringBuffer JavaDoc();
149       sbOrderedItems.append(WebCommonConstants.OBJECT_SEPARATOR);
150       sbOrderedItems.append(strOrderedItems);
151       sbOrderedItems.append(WebCommonConstants.OBJECT_SEPARATOR);
152       
153       sbId.append(WebCommonConstants.OBJECT_SEPARATOR);
154       sbId.append(iItemId);
155       sbId.append(WebCommonConstants.ITEM_SEPARATOR);
156       
157       // find out ID of the item within the string
158
iIndexStart = sbOrderedItems.indexOf(sbId.toString()) + sbId.length();
159       iIndexEnd = sbOrderedItems.indexOf(WebCommonConstants.OBJECT_SEPARATOR, iIndexStart);
160       
161       iOrderReturn = Integer.parseInt(sbOrderedItems.substring(iIndexStart, iIndexEnd));
162
163       return iOrderReturn;
164    }
165    
166    /**
167     * Construct string representation of all ordered items contained within the
168     * specified collection. The format of the order string is:
169     * ID1:ORDER_NUMBER1;...;IDn:ORDER_NUMBERn
170     *
171     * @param colDataObjects - collection of ordered data objects for which the
172     * order string will be constructed for
173     * @return String - string representation of all ordered data objects within
174     * the collection
175     */

176    public static String JavaDoc getEncodedOrder(
177       Collection JavaDoc colDataObjects
178    )
179    {
180       StringBuffer JavaDoc sbOrderedItems = new StringBuffer JavaDoc();
181       Iterator JavaDoc itHelp;
182       OrderedData data = null;
183
184       // sort data by order number
185
// TODO: Performance: Do we need to sort the data objects?
186
Collections.sort((List JavaDoc)colDataObjects, OrderedDataComparator.getInstance());
187
188       for (itHelp = colDataObjects.iterator(); itHelp.hasNext();)
189       {
190          data = (OrderedData)itHelp.next();
191          
192          if (sbOrderedItems.length() > 0)
193          {
194             sbOrderedItems.append(WebCommonConstants.OBJECT_SEPARATOR);
195          }
196          sbOrderedItems.append(((DataObject)data).getId());
197          sbOrderedItems.append(WebCommonConstants.ITEM_SEPARATOR);
198          sbOrderedItems.append(data.getOrderNumber());
199       }
200
201       return sbOrderedItems.toString();
202    }
203
204    /**
205     * Compare lists of objects to find out if their order or attributes were
206     * changed or if some objects were added or deleted. Objects in list have
207     * to be instances of DataObject and OrderedData.
208     *
209     * @param lstList1 - first list to compare
210     * @param lstList2 - second list to compare
211     * @return byte - result byte with bit flags of changes:
212     * [COMPARE_ORDER_CHANGE]-th bit = if order has been changed
213     * [COMPARE_ATTRIBUTES_CHANGE]-th bit - if attributes has been changed
214     * - Objects are not isSame()
215     * [COMPARE_CHANGED]-th bit = if list is changed (added or removed some
216     * objects)
217     * in this case order flag is false
218     * to check use CODE-th byte : (X & CODE) != 0
219     */

220    public static byte compare(
221       List JavaDoc lstList1,
222       List JavaDoc lstList2
223    )
224    {
225       // we will initialize result as no changes
226
byte bReturn = 0;
227       
228       Iterator JavaDoc itHelp1;
229       Iterator JavaDoc itHelp2;
230       Object JavaDoc oHelp1;
231       Object JavaDoc oHelp2;
232       
233       // check if any of lists is null or empty
234
if ((lstList1 != null && lstList1.size() > 0)
235          && (lstList2 != null && lstList2.size() > 0))
236       {
237          // check if size of lists are different
238
if (lstList1.size() == lstList2.size())
239          {
240             // we will check order first by iterating lists sequentially
241
itHelp1 = lstList1.iterator();
242             itHelp2 = lstList2.iterator();
243             while (((bReturn & DataObjectUtils.COMPARE_ORDER_CHANGED) == 0)
244                   && (itHelp1.hasNext()) && (itHelp2.hasNext()))
245             {
246                oHelp1 = itHelp1.next();
247                oHelp2 = itHelp2.next();
248                // objects in list has to be instances of OrderedData to be able to
249
// compare them
250
// if order identifiert is not same
251
// we will set COMPARE_ORDER_CHANGE to true and stop iterating
252
if (((OrderedData) oHelp1).getOrderNumber()
253                   != ((OrderedData) oHelp2).getOrderNumber())
254                {
255                   bReturn += DataObjectUtils.COMPARE_ORDER_CHANGED;
256                }
257                // otherwise we will check parameters changes
258
else if (!((DataObject) oHelp1).isSame(oHelp2))
259                {
260                   bReturn = DataObjectUtils.COMPARE_ATTRIBUTES_CHANGED;
261                }
262             }
263    
264             // in case of order changed we have to check also attributes change or lists changed
265
if (((bReturn & DataObjectUtils.COMPARE_ORDER_CHANGED) != 0))
266             {
267                // we will sort the lists
268
Collections.sort(lstList1, OrderedDataComparator.getInstance());
269                Collections.sort(lstList2, OrderedDataComparator.getInstance());
270    
271                // we will iterate synchronly through sorted lists
272
itHelp1 = lstList1.iterator();
273                itHelp2 = lstList2.iterator();
274                while (((bReturn & DataObjectUtils.COMPARE_CHANGED) == 0)
275                      && (itHelp1.hasNext()) && (itHelp2.hasNext()))
276                {
277                   oHelp1 = itHelp1.next();
278                   oHelp2 = itHelp2.next();
279    
280                   // objects in list have to be instances of OrderedData and DataObject
281
// to be able to compare them and check if are same
282
// if order identifiers are not same
283
// we will set COMPARE_NOT_EQUALS to true and stop iterating
284
if (((OrderedData) oHelp1).getOrderNumber()
285                      != ((OrderedData) oHelp2).getOrderNumber())
286                   {
287                      bReturn = DataObjectUtils.COMPARE_CHANGED;
288                   }
289                   else
290                   {
291                      // we have to check if objects are the same
292
if (!((DataObject) oHelp1).isSame(oHelp2)
293                         && ((bReturn & DataObjectUtils.COMPARE_ATTRIBUTES_CHANGED) == 0))
294                      {
295                         bReturn += DataObjectUtils.COMPARE_ATTRIBUTES_CHANGED;
296                      }
297                   }
298                }
299             }
300          }
301          else
302          {
303             // in case that lists sizes are not the same the result is COMPARE_CHANGED
304
bReturn = DataObjectUtils.COMPARE_CHANGED;
305          }
306       }
307       else
308       {
309          // in case that one list is null or empty but not the other one
310
// the result is COMPARE_CHANGED
311
if (((lstList1 != null) && (lstList1.size() > 0))
312             || ((lstList2 != null) && (lstList2.size() > 0)))
313          {
314             bReturn = DataObjectUtils.COMPARE_CHANGED;
315          }
316       }
317       return bReturn;
318    }
319
320    /**
321     * Compare array of ids and list of objects to find out if the order of the
322     * object as changed or if some objects were newly added or removed. Objects
323     * in list have to be instances of DataObject and OrderedData
324     *
325     * @param arrIdentifiers - array of ints - ids of the data object
326     * @param lstList - list of data object to compare with the ist of ids
327     * @return byte - result byte with bit flags of changes:
328     * [COMPARE_ORDER_CHANGE]-th bit = if order has been changed
329     * [COMPARE_CHANGED]-th bit = if list is changed (added or removed some
330     * objects)
331     * in this case order flag is false
332     * to check use CODE-th byte : (X & CODE) != 0
333     */

334    public static byte compare(
335       int[] arrIdentifiers,
336       List JavaDoc lstList
337    )
338    {
339       // we will initialize result as no changes
340
byte bReturn = 0;
341       
342       Iterator JavaDoc itHelp;
343       Object JavaDoc oHelp;
344       int iCounter;
345       
346       // check if any of array and list is null or empty
347
if ((arrIdentifiers != null && arrIdentifiers.length > 0)
348          && (lstList != null && lstList.size() > 0))
349       {
350          // check if size of lists are different
351
if (arrIdentifiers.length == lstList.size())
352          {
353             // we will check order first by iterating array and list synchronly
354
itHelp = lstList.iterator();
355             iCounter = 0;
356             while (((bReturn & DataObjectUtils.COMPARE_ORDER_CHANGED) == 0)
357                   && (itHelp.hasNext()))
358             {
359                oHelp = itHelp.next();
360                // object in list has to be instance of OrderedData to be able to
361
// compare it
362
// if order identifiert is not same
363
// we will set COMPARE_ORDER_CHANGE to true and stop iterating
364
if (arrIdentifiers[iCounter] != ((OrderedData) oHelp).getOrderNumber())
365                {
366                   bReturn = DataObjectUtils.COMPARE_ORDER_CHANGED;
367                }
368                iCounter++;
369             }
370    
371             // in case of order changed we have to check also if list changed
372
if (((bReturn & DataObjectUtils.COMPARE_ORDER_CHANGED) != 0))
373             {
374                // we will sort the lists by array identifiers
375
Collections.sort(lstList, new DataObjectOrderingComparator(arrIdentifiers));
376    
377                // we will iterate synchronly through sorted list
378
itHelp = lstList.iterator();
379                iCounter = 0;
380                while (((bReturn & DataObjectUtils.COMPARE_CHANGED) == 0)
381                      && (itHelp.hasNext()))
382                {
383                   oHelp = itHelp.next();
384    
385                   // objects in list has to be instances of OrderedData
386
// to be able to compare them
387
// if order identifiers are not same
388
// we will set COMPARE_NOT_EQUALS to true and stop iterating
389
if (arrIdentifiers[iCounter]
390                      != ((OrderedData) oHelp).getOrderNumber())
391                   {
392                      bReturn = DataObjectUtils.COMPARE_CHANGED;
393                   }
394                   iCounter++;
395                }
396             }
397          }
398          else
399          {
400             // in case that lists sizes are not the same the result is COMPARE_NOT_EQUALS
401
bReturn = DataObjectUtils.COMPARE_CHANGED;
402          }
403       }
404       else
405       {
406          // in case that array or list is null or empty but not the other one
407
// the result is COMPARE_NOT_EQUALS
408
if ((arrIdentifiers != null && arrIdentifiers.length > 0)
409             || (lstList != null && lstList.size() > 0))
410          {
411             bReturn = DataObjectUtils.COMPARE_CHANGED;
412          }
413       }
414       return bReturn;
415    }
416 }
417
Popular Tags