001: // ========================================================================
002: // Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
003: // ------------------------------------------------------------------------
004: // Licensed under the Apache License, Version 2.0 (the "License");
005: // you may not use this file except in compliance with the License.
006: // You may obtain a copy of the License at
007: // http://www.apache.org/licenses/LICENSE-2.0
008: // Unless required by applicable law or agreed to in writing, software
009: // distributed under the License is distributed on an "AS IS" BASIS,
010: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011: // See the License for the specific language governing permissions and
012: // limitations under the License.
013: // ========================================================================
014:
015: package org.mortbay.util;
016:
017: import java.io.Serializable;
018: import java.lang.reflect.Array;
019: import java.util.ArrayList;
020: import java.util.Arrays;
021: import java.util.Collection;
022: import java.util.Collections;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.ListIterator;
026:
027: /* ------------------------------------------------------------ */
028: /** Lazy List creation.
029: * A List helper class that attempts to avoid unneccessary List
030: * creation. If a method needs to create a List to return, but it is
031: * expected that this will either be empty or frequently contain a
032: * single item, then using LazyList will avoid additional object
033: * creations by using Collections.EMPTY_LIST or
034: * Collections.singletonList where possible.
035: *
036: * <p><h4>Usage</h4>
037: * <pre>
038: * Object lazylist =null;
039: * while(loopCondition)
040: * {
041: * Object item = getItem();
042: * if (item.isToBeAdded())
043: * lazylist = LazyList.add(lazylist,item);
044: * }
045: * return LazyList.getList(lazylist);
046: * </pre>
047: *
048: * An ArrayList of default size is used as the initial LazyList.
049: *
050: * @see java.util.List
051: * @author Greg Wilkins (gregw)
052: */
053: public class LazyList implements Cloneable, Serializable {
054: private static final String[] __EMTPY_STRING_ARRAY = new String[0];
055:
056: /* ------------------------------------------------------------ */
057: private LazyList() {
058: }
059:
060: /* ------------------------------------------------------------ */
061: /** Add an item to a LazyList
062: * @param list The list to add to or null if none yet created.
063: * @param item The item to add.
064: * @return The lazylist created or added to.
065: */
066: public static Object add(Object list, Object item) {
067: if (list == null) {
068: if (item instanceof List || item == null) {
069: List l = new ArrayList();
070: l.add(item);
071: return l;
072: }
073:
074: return item;
075: }
076:
077: if (list instanceof List) {
078: ((List) list).add(item);
079: return list;
080: }
081:
082: List l = new ArrayList();
083: l.add(list);
084: l.add(item);
085: return l;
086: }
087:
088: /* ------------------------------------------------------------ */
089: /** Add an item to a LazyList
090: * @param list The list to add to or null if none yet created.
091: * @param index The index to add the item at.
092: * @param item The item to add.
093: * @return The lazylist created or added to.
094: */
095: public static Object add(Object list, int index, Object item) {
096: if (list == null) {
097: if (index > 0 || item instanceof List || item == null) {
098: List l = new ArrayList();
099: l.add(index, item);
100: return l;
101: }
102: return item;
103: }
104:
105: if (list instanceof List) {
106: ((List) list).add(index, item);
107: return list;
108: }
109:
110: List l = new ArrayList();
111: l.add(list);
112: l.add(index, item);
113: return l;
114: }
115:
116: /* ------------------------------------------------------------ */
117: /** Add the contents of a Collection to a LazyList
118: * @param list The list to add to or null if none yet created.
119: * @param collection The Collection whose contents should be added.
120: * @return The lazylist created or added to.
121: */
122: public static Object addCollection(Object list,
123: Collection collection) {
124: Iterator i = collection.iterator();
125: while (i.hasNext())
126: list = LazyList.add(list, i.next());
127: return list;
128: }
129:
130: /* ------------------------------------------------------------ */
131: /** Add the contents of an array to a LazyList
132: * @param list The list to add to or null if none yet created.
133: * @param collection The Collection whose contents should be added.
134: * @return The lazylist created or added to.
135: */
136: public static Object addArray(Object list, Object[] array) {
137: for (int i = 0; array != null && i < array.length; i++)
138: list = LazyList.add(list, array[i]);
139: return list;
140: }
141:
142: /* ------------------------------------------------------------ */
143: /** Ensure the capcity of the underlying list.
144: *
145: */
146: public static Object ensureSize(Object list, int initialSize) {
147: if (list == null)
148: return new ArrayList(initialSize);
149: if (list instanceof ArrayList) {
150: ArrayList ol = (ArrayList) list;
151: if (ol.size() > initialSize)
152: return ol;
153: ArrayList nl = new ArrayList(initialSize);
154: nl.addAll(ol);
155: return nl;
156: }
157: List l = new ArrayList(initialSize);
158: l.add(list);
159: return l;
160: }
161:
162: /* ------------------------------------------------------------ */
163: public static Object remove(Object list, Object o) {
164: if (list == null)
165: return null;
166:
167: if (list instanceof List) {
168: List l = (List) list;
169: l.remove(o);
170: if (l.size() == 0)
171: return null;
172: return list;
173: }
174:
175: if (list.equals(o))
176: return null;
177: return list;
178: }
179:
180: /* ------------------------------------------------------------ */
181: public static Object remove(Object list, int i) {
182: if (list == null)
183: return null;
184:
185: if (list instanceof List) {
186: List l = (List) list;
187: l.remove(i);
188: if (l.size() == 0)
189: return null;
190: return list;
191: }
192:
193: if (i == 0)
194: return null;
195: return list;
196: }
197:
198: /* ------------------------------------------------------------ */
199: /** Get the real List from a LazyList.
200: *
201: * @param list A LazyList returned from LazyList.add(Object)
202: * @return The List of added items, which may be an EMPTY_LIST
203: * or a SingletonList.
204: */
205: public static List getList(Object list) {
206: return getList(list, false);
207: }
208:
209: /* ------------------------------------------------------------ */
210: /** Get the real List from a LazyList.
211: *
212: * @param list A LazyList returned from LazyList.add(Object) or null
213: * @param nullForEmpty If true, null is returned instead of an
214: * empty list.
215: * @return The List of added items, which may be null, an EMPTY_LIST
216: * or a SingletonList.
217: */
218: public static List getList(Object list, boolean nullForEmpty) {
219: if (list == null)
220: return nullForEmpty ? null : Collections.EMPTY_LIST;
221: if (list instanceof List)
222: return (List) list;
223:
224: List l = new ArrayList(1);
225: l.add(list);
226: return l;
227: }
228:
229: /* ------------------------------------------------------------ */
230: public static String[] toStringArray(Object list) {
231: if (list == null)
232: return __EMTPY_STRING_ARRAY;
233:
234: if (list instanceof List) {
235: List l = (List) list;
236: String[] a = new String[l.size()];
237: for (int i = l.size(); i-- > 0;) {
238: Object o = l.get(i);
239: if (o != null)
240: a[i] = o.toString();
241: }
242: return a;
243: }
244:
245: return new String[] { list.toString() };
246: }
247:
248: /* ------------------------------------------------------------ */
249: public static Object toArray(Object list, Class aClass) {
250: if (list == null)
251: return (Object[]) Array.newInstance(aClass, 0);
252:
253: if (list instanceof List) {
254: List l = (List) list;
255: if (aClass.isPrimitive()) {
256: Object a = Array.newInstance(aClass, l.size());
257: for (int i = 0; i < l.size(); i++)
258: Array.set(a, i, l.get(i));
259: return a;
260: }
261: return l.toArray((Object[]) Array.newInstance(aClass, l
262: .size()));
263:
264: }
265:
266: Object a = Array.newInstance(aClass, 1);
267: Array.set(a, 0, list);
268: return a;
269: }
270:
271: /* ------------------------------------------------------------ */
272: /** The size of a lazy List
273: * @param list A LazyList returned from LazyList.add(Object) or null
274: * @return the size of the list.
275: */
276: public static int size(Object list) {
277: if (list == null)
278: return 0;
279: if (list instanceof List)
280: return ((List) list).size();
281: return 1;
282: }
283:
284: /* ------------------------------------------------------------ */
285: /** Get item from the list
286: * @param list A LazyList returned from LazyList.add(Object) or null
287: * @param i int index
288: * @return the item from the list.
289: */
290: public static Object get(Object list, int i) {
291: if (list == null)
292: throw new IndexOutOfBoundsException();
293:
294: if (list instanceof List)
295: return ((List) list).get(i);
296:
297: if (i == 0)
298: return list;
299:
300: throw new IndexOutOfBoundsException();
301: }
302:
303: /* ------------------------------------------------------------ */
304: public static boolean contains(Object list, Object item) {
305: if (list == null)
306: return false;
307:
308: if (list instanceof List)
309: return ((List) list).contains(item);
310:
311: return list.equals(item);
312: }
313:
314: /* ------------------------------------------------------------ */
315: public static Object clone(Object list) {
316: if (list == null)
317: return null;
318: if (list instanceof List)
319: return new ArrayList((List) list);
320: return list;
321: }
322:
323: /* ------------------------------------------------------------ */
324: public static String toString(Object list) {
325: if (list == null)
326: return "[]";
327: if (list instanceof List)
328: return ((List) list).toString();
329: return "[" + list + "]";
330: }
331:
332: /* ------------------------------------------------------------ */
333: public static Iterator iterator(Object list) {
334: if (list == null)
335: return Collections.EMPTY_LIST.iterator();
336: if (list instanceof List)
337: return ((List) list).iterator();
338: return getList(list).iterator();
339: }
340:
341: /* ------------------------------------------------------------ */
342: public static ListIterator listIterator(Object list) {
343: if (list == null)
344: return Collections.EMPTY_LIST.listIterator();
345: if (list instanceof List)
346: return ((List) list).listIterator();
347: return getList(list).listIterator();
348: }
349:
350: /* ------------------------------------------------------------ */
351: /**
352: * @param array Any array of object
353: * @return A new <i>modifiable</i> list initialised with the elements from <code>array</code>.
354: */
355: public static List array2List(Object[] array) {
356: if (array == null || array.length == 0)
357: return new ArrayList();
358: return new ArrayList(Arrays.asList(array));
359: }
360:
361: /* ------------------------------------------------------------ */
362: /** Add element to an array
363: * @param array The array to add to (or null)
364: * @param item The item to add
365: * @param type The type of the array (in case of null array)
366: * @return new array with contents of array plus item
367: */
368: public static Object[] addToArray(Object[] array, Object item,
369: Class type) {
370: if (array == null) {
371: if (type == null && item != null)
372: type = item.getClass();
373: Object[] na = (Object[]) Array.newInstance(type, 1);
374: na[0] = item;
375: return na;
376: } else {
377: Class c = array.getClass().getComponentType();
378: Object[] na = (Object[]) Array.newInstance(c, Array
379: .getLength(array) + 1);
380: System.arraycopy(array, 0, na, 0, array.length);
381: na[array.length] = item;
382: return na;
383: }
384: }
385:
386: /* ------------------------------------------------------------ */
387: public static Object[] removeFromArray(Object[] array, Object item) {
388: if (item == null || array == null)
389: return array;
390: for (int i = array.length; i-- > 0;) {
391: if (item.equals(array[i])) {
392: Class c = array == null ? item.getClass() : array
393: .getClass().getComponentType();
394: Object[] na = (Object[]) Array.newInstance(c, Array
395: .getLength(array) - 1);
396: if (i > 0)
397: System.arraycopy(array, 0, na, 0, i);
398: if (i + 1 < array.length)
399: System.arraycopy(array, i + 1, na, i, array.length
400: - (i + 1));
401: return na;
402: }
403: }
404: return array;
405: }
406:
407: }
|