package org.smartly.commons.util;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.*;
import java.util.Map.Entry;
public abstract class CollectionUtils {
public static interface IterationCallback {
Object handle(final Object item, final int index, final Object key);
}
//---------------------------------------------------------------------
// forEach utilities
// Use to filter, map reduce or simply loop on items
//---------------------------------------------------------------------
public static Collection<?> forEach(final Collection<?> items, final IterationCallback callback) {
final Collection<Object> result = new LinkedList<Object>();
if (null != callback && null != items) {
int index = 0;
for (final Object item : items) {
final Object response = callback.handle(item, index, null);
if (null != response) {
result.add(response);
}
index++;
}
}
return result;
}
public static Object[] forEach(final Object[] items, final IterationCallback callback) {
final Collection<Object> result = new LinkedList<Object>();
if (null != callback && null != items) {
int index = 0;
for (final Object item : items) {
final Object response = callback.handle(item, index, null);
if (null != response) {
result.add(response);
}
index++;
}
}
return result.toArray(new Object[result.size()]);
}
public static JSONArray forEach(final JSONArray items, final IterationCallback callback) {
final JSONArray result = new JSONArray();
if (null != callback && null != items && items.length() > 0) {
final int len = items.length();
for (int i = 0; i < len; i++) {
final Object response = callback.handle(items.get(i), i, null);
if (null != response) {
result.put(response);
}
}
}
return result;
}
public static Map<?, ?> forEach(final Map<?, ?> map, final IterationCallback callback) {
final Map<Object, Object> result = new HashMap<Object, Object>();
if (null != callback && null != map) {
final Set<?> keys = map.keySet();
int index = 0;
for (final Object key : keys) {
final Object response = callback.handle(map.get(key), index, key);
if (null != response) {
result.put(key, response);
}
index++;
}
}
return result;
}
public static Object find(final Collection<?> items, final IterationCallback callback) {
if (null != callback && null != items) {
int index = 0;
for (final Object item : items) {
final Object response = callback.handle(item, index, null);
if (null!=response) {
return response;
}
index++;
}
}
return null;
}
public static Object find(final Object[] items, final IterationCallback callback) {
if (null != callback && null != items) {
int index = 0;
for (final Object item : items) {
final Object response = callback.handle(item, index, null);
if (null!=response) {
return response;
}
index++;
}
}
return null;
}
public static Object find(final JSONArray items, final IterationCallback callback) {
if (null != callback && null != items && items.length() > 0) {
final int len = items.length();
for (int i = 0; i < len; i++) {
final Object response = callback.handle(items.get(i), i, null);
if (null!=response) {
return response;
}
}
}
return null;
}
public static Object find(final Map<?, ?> map, final IterationCallback callback) {
if (null != callback && null != map) {
final Set<?> keys = map.keySet();
int index = 0;
for (final Object key : keys) {
final Object response = callback.handle(map.get(key), index, key);
if (null!=response) {
return response;
}
index++;
}
}
return null;
}
//---------------------------------------------------------------------
// Convenience methods for working with String arrays
//---------------------------------------------------------------------
public static int[] resizeArray(int[] array, int newsize) {
if (null == array) {
return null;
}
int[] newArr = new int[newsize];
if (newsize > array.length) {
System.arraycopy(array, 0, newArr, 0, array.length);
} else {
System.arraycopy(array, 0, newArr, 0, newsize);
}
return newArr;
}
public static String[] resizeArray(String[] array, int newsize) {
if (null == array) {
return null;
}
String[] newArr = new String[newsize];
if (newsize > array.length) {
System.arraycopy(array, 0, newArr, 0, array.length);
} else {
System.arraycopy(array, 0, newArr, 0, newsize);
}
return newArr;
}
public static Object[] resizeArray(Object[] array, int newsize) {
if (null == array) {
return null;
}
Object[] newArr = new Object[newsize];
if (newsize > array.length) {
System.arraycopy(array, 0, newArr, 0, array.length);
} else {
System.arraycopy(array, 0, newArr, 0, newsize);
}
return newArr;
}
/**
* Append the given String to the given String array, returning a new array
* consisting of the input array contents plus the given String.
*
* @param array the array to append to (can be
* <code>null</code>)
* @param str the String to append
* @return the new array (never
* <code>null</code>)
*/
public static String[] addStringToArray(final String[] array, final String str) {
if (isEmpty(array)) {
return new String[]{str};
}
String[] newArr = new String[array.length + 1];
System.arraycopy(array, 0, newArr, 0, array.length);
newArr[array.length] = str;
return newArr;
}
/**
* Insert the given String to begin of the given String array, returning a
* new array consisting of the input array contents plus the given String.
*
* @param array the array to insert to (can be
* <code>null</code>)
* @param str the String to insert in first position
* @return the new array (never
* <code>null</code>)
*/
public static String[] insertStringToArray(String[] array, String str) {
if (isEmpty(array)) {
return new String[]{str};
}
String[] newArr = new String[array.length + 1];
System.arraycopy(array, 0, newArr, 1, array.length);
newArr[0] = str;
return newArr;
}
public static String[] removeTokenFromArray(String[] array, int index) {
if (null == array || isEmpty(array)) {
return new String[0];
}
String[] newArr = new String[array.length - 1];
int newArrIndex = 0;
for (int i = 0; i < array.length; i++) {
if (index != i) {
newArr[newArrIndex] = array[i];
newArrIndex++;
}
}
return newArr;
}
/**
* Turn given source String array into sorted array.
*
* @param array the source array
* @return the sorted array (never
* <code>null</code>)
*/
public static String[] sortStringArray(String[] array) {
if (isEmpty(array)) {
return new String[0];
}
Arrays.sort(array);
return array;
}
/**
* Remove duplicate Strings from the given array. Also sorts the array, as
* it uses a TreeSet.
*
* @param array the String array
* @return an array without duplicates, in natural sort order
*/
public static String[] removeDuplicateStrings(final String[] array) {
if (isEmpty(array)) {
return array;
}
final Set<String> set = new TreeSet<String>();
Collections.addAll(set, array);
return (String[]) set.toArray(new String[set.size()]);
}
/**
* Take an array Strings and split each element based on the given
* delimiter. A
* <code>Properties</code> instance is then generated, with the left of the
* delimiter providing the key, and the right of the delimiter providing the
* value. <p>Will trim both the key and value before adding them to the
* <code>Properties</code> instance.
*
* @param array the array to process
* @param delimiter to split each element using (typically the equals
* symbol)
* @return a
* <code>Properties</code> instance representing the array contents, or
* <code>null</code> if the array to process was null or empty
*/
public static Properties splitArrayElementsIntoProperties(String[] array, String delimiter) {
return splitArrayElementsIntoProperties(array, delimiter, null);
}
/**
* Take an array Strings and split each element based on the given
* delimiter. A
* <code>Properties</code> instance is then generated, with the left of the
* delimiter providing the key, and the right of the delimiter providing the
* value. <p>Will trim both the key and value before adding them to the
* <code>Properties</code> instance.
*
* @param array the array to process
* @param delimiter to split each element using (typically the equals
* symbol)
* @param charsToDelete one or more characters to remove from each element
* prior to attempting the split operation (typically the quotation mark
* symbol), or
* <code>null</code> if no removal should occur
* @return a
* <code>Properties</code> instance representing the array contents, or
* <code>null</code> if the array to process was null or empty
*/
public static Properties splitArrayElementsIntoProperties(
String[] array, String delimiter, String charsToDelete) {
if (array == null || array.length == 0) {
return null;
}
Properties result = new Properties();
for (final String item : array) {
String element = item;
if (charsToDelete != null) {
element = StringUtils.deleteAny(item, charsToDelete);
}
String[] splittedElement = StringUtils.splitFirst(element, delimiter);
if (splittedElement == null) {
continue;
}
result.setProperty(splittedElement[0].trim(), splittedElement[1].trim());
}
return result;
}
public static Map<String, String> splitArrayElementsIntoMap(
final String[] array, final String delimiter) {
return splitArrayElementsIntoMap(array, delimiter, null);
}
public static Map<String, String> splitArrayElementsIntoMap(
String[] array, String delimiter, String charsToDelete) {
if (array == null || array.length == 0) {
return null;
}
Map<String, String> result = new HashMap<String, String>();
for (final String item : array) {
String element = item;
if (charsToDelete != null) {
element = StringUtils.deleteAny(item, charsToDelete);
}
String[] splittedElement = StringUtils.splitFirst(element, delimiter);
if (splittedElement == null) {
continue;
}
result.put(splittedElement[0].trim(), splittedElement[1].trim());
}
return result;
}
public static String toString(final Collection list) {
final StringBuilder sb = new StringBuilder();
if (null != list) {
for (final Object item : list) {
if (null != item) {
sb.append(item);
}
}
}
return sb.toString();
}
public static String toString(final Object[] list) {
final StringBuilder sb = new StringBuilder();
if (null != list) {
for (final Object item : list) {
if (null != item) {
sb.append(item);
}
}
}
return sb.toString();
}
/**
* Convenience method to convert a CSV string list to a set. Note that this
* will suppress duplicates.
*
* @param str CSV String
* @return a Set of String entries in the list
*/
public static Set<String> commaDelimitedListToSet(final String str) {
final Set<String> set = new TreeSet<String>();
final String[] tokens = StringUtils.split(str, ",");
Collections.addAll(set, tokens);
return set;
}
public static String arrayToString(final Object[] arr) {
if (arr == null) {
return "";
}
final StringBuilder sb = new StringBuilder();
for (final Object item : arr) {
sb.append(item);
}
return sb.toString();
}
/**
* Convenience method to return a String array as a delimited (e.g. CSV)
* String. E.g. useful for toString() implementations.
*
* @param arr array to display. Elements may be of any type (toString will
* be called on each element).
* @param delim delimiter to use (probably a ",")
*/
public static String toDelimitedString(final Object[] arr,
final String delim) {
if (arr == null) {
return "";
}
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (i > 0) {
sb.append(delim);
}
sb.append(arr[i]);
}
return sb.toString();
}
public static String toDelimitedString(final Object[] arr,
final String delim,
int startIndex, int endIndex) {
if (arr == null) {
return "";
}
final StringBuilder sb = new StringBuilder();
endIndex = arr.length - 1 < endIndex ? arr.length - 1 : endIndex;
for (int i = startIndex; i < endIndex + 1; i++) {
if (i > 0) {
sb.append(delim);
}
sb.append(arr[i]);
}
return sb.toString();
}
public static String collectionToString(Collection<?> list) {
if (null == list) {
return null;
}
final StringBuilder sb = new StringBuilder();
for (final Object item : list) {
if (null != item) {
sb.append(item.toString());
}
}
return sb.toString();
}
public static int[] toIntArray(final List<Integer> list) {
int[] array = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
return array;
}
public static long[] toLongArray(final List<Long> list) {
long[] array = new long[list.size()];
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
return array;
}
/**
* Convenience method to return a Collection as a delimited (e.g. CSV)
* String. E.g. useful for toString() implementations.
*
* @param coll Collection to display
* @param delim delimiter to use (probably a ",")
* @param prefix string to start each element with
* @param suffix string to end each element with
*/
public static String tooDelimitedString(final Collection coll,
final String delim,
final String prefix,
final String suffix) {
if (coll == null) {
return "";
}
final StringBuilder sb = new StringBuilder();
Iterator it = coll.iterator();
int i = 0;
while (it.hasNext()) {
if (i > 0) {
sb.append(delim);
}
sb.append(prefix).append(it.next()).append(suffix);
i++;
}
return sb.toString();
}
/**
* Convenience method to return a Collection as a delimited (e.g. CSV)
* String. E.g. useful for toString() implementations.
*
* @param coll Collection to display
* @param delim delimiter to use (probably a ",")
*/
public static String toDelimitedString(final Collection coll,
final String delim) {
return tooDelimitedString(coll, delim, "", "");
}
/**
* Convenience method to return a String array as a CSV String. E.g. useful
* for toString() implementations.
*
* @param arr array to display. Elements may be of any type (toString will
* be called on each element).
*/
public static String toCommaDelimitedString(final Object[] arr) {
return toDelimitedString(arr, ",");
}
/**
* Convenience method to return a Collection as a CSV String. E.g. useful
* for toString() implementations.
*
* @param coll Collection to display
*/
public static String toCommaDelimitedString(final Collection coll) {
return toDelimitedString(coll, ",");
}
public static String mapToString(final Map map) {
if (null == map) {
return "";
}
final String text = map.toString();
return text.substring(1, text.length() - 1);
}
public static <T, E> String mapToString(final Map<T, E> map,
final String separator) {
if (null == map) {
return "";
}
if (null == separator) {
return mapToString(map);
}
final StringBuilder result = new StringBuilder();
final Set<Entry<T, E>> entries = map.entrySet();
for (final Entry entry : entries) {
final String name = StringUtils.toString(entry.getKey(), "");
final String value = StringUtils.toString(entry.getValue(), "");
if (StringUtils.hasText(name)) {
if (result.length() > 0) {
result.append(separator);
}
result.append(name).append("=").append(value);
}
}
return result.toString();
}
public static Map<String, String> stringToMapOfStrings(final String data) {
return stringToMapOfStrings(data, ",");
}
public static Map<String, String> stringToMapOfStrings(final String data, String separator) {
if (StringUtils.hasText(data)) {
if (".".equals(separator) || "|".equals(separator)) {
separator = "\\" + separator;
}
final String[] tokens = data.split(separator);
return toMapOfStrings(tokens);
}
return new HashMap<String, String>();
}
public static Map<String, String> toMapOfStrings(final String[] tokens) {
final Map<String, String> result = new LinkedHashMap<String, String>();
if (null != tokens) {
for (String token : tokens) {
final String[] items = token.split("=");
final String key;
final String value;
if (items.length == 1) {
key = items[0].trim();
value = "";
} else if (items.length == 2) {
key = items[0].trim();
value = items[1].trim();
} else {
continue;
}
result.put(key, value);
}
}
return result;
}
public static Map<String, Object> stringToMap(final String data) {
return stringToMap(data, ",");
}
public static Map<String, Object> stringToMap(final String data, String separator) {
try {
if (StringUtils.hasText(data)) {
if (".".equals(separator) || "|".equals(separator)) {
separator = "\\" + separator;
}
final String[] tokens = data.split(separator);
return toMap(tokens);
}
} catch (Throwable ignored) {
}
return new HashMap<String, Object>();
}
@SuppressWarnings("unchecked")
public static Map<String, Object> toMap(final String[] tokens) {
final Map<String, Object> result = new LinkedHashMap<String, Object>();
if (null != tokens) {
for (String token : tokens) {
final String[] items = token.split("=");
final String key;
final String value;
if (items.length == 1) {
key = items[0].trim();
value = "";
} else if (items.length == 2) {
key = items[0].trim();
value = items[1].trim();
} else {
continue;
}
if (result.containsKey(key)) {
final List<Object> list;
final Object val = result.get(key);
if (val instanceof List) {
list = (List) val;
} else {
list = new LinkedList<Object>();
list.add(val);
result.put(key, list);
}
list.add(value);
} else {
result.put(key, value);
}
}
}
return result;
}
public static Object[] subtract(final Object[] valuestoremove,
final Object[] targetarray) {
final List<Object> result = new LinkedList<Object>();
for (final Object value : targetarray) {
if (!contains(valuestoremove, value)) {
result.add(value);
}
}
return result.toArray(new Object[result.size()]);
}
public static String[] subtract(final String[] valuestoremove,
final String[] targetarray) {
final List<String> result = new LinkedList<String>();
for (final String value : targetarray) {
if (!contains(valuestoremove, value)) {
result.add(value);
}
}
return result.toArray(new String[result.size()]);
}
/**
* Return new array containig all common fields in both arrays
*
* @param targetvalues First Array
* @param checkvalues Second Array
* @return
*/
public static String[] match(final String[] targetvalues,
final String[] checkvalues) {
final List<String> result = new LinkedList<String>();
for (final String value : checkvalues) {
if (contains(targetvalues, value)) {
result.add(value);
}
}
return result.toArray(new String[result.size()]);
}
/**
* Return new array containig all common fields in both arrays
*
* @param targetvalues First list
* @param checkvalues Second list
* @return
*/
public static <T> Collection<T> match(
final Collection<T> targetvalues,
final Collection<T> checkvalues) {
final List<T> result = new LinkedList<T>();
for (final T value : checkvalues) {
if (targetvalues.contains(value)) {
result.add(value);
}
}
return result;
}
public static boolean contains(final Collection list, final String fieldName,
final Object fieldValue) {
return indexOf(list, fieldName, fieldValue) > -1;
}
public static boolean contains(final Object[] list, final String fieldName,
final Object fieldValue) {
return indexOf(list, fieldName, fieldValue) > -1;
}
public static boolean contains(final Collection list, Object value) {
return null != list && list.size() > 0 && list.contains(value);
}
public static boolean contains(Class[] array, Class value) {
return null != array && indexOf(array, value) >= 0;
}
public static boolean contains(char[] array, char value) {
return null != array && indexOf(array, value) >= 0;
}
public static boolean contains(Object[] array, Object value) {
return null != array && indexOf(array, value) >= 0;
}
public static boolean containsLike(Class[] array, Class value) {
return null != array && indexOfLike(array, value) >= 0;
}
/**
* Searches the specified array for the specified object using the binary
* search algorithm. The array is sorted automatically. (If the array
* contains elements that are not mutually comparable (for example, strings
* and integers), it <i>cannot</i> be sorted according to the natural
* ordering of its elements, hence results are undefined.) If the array
* contains multiple elements equal to the specified object, there is no
* guarantee which one will be found.
*
* @param a the array to be searched
* @param key the value to be searched for
* @return index of the search key, if it is contained in the array;
* otherwise, <tt>(- 1)</tt>. The <i>insertion point</i> is defined as the
* point at which the key would be inserted into the array: the index of the
* first element greater than the key, or <tt>a.length</tt> if all elements
* in the array are less than the specified key. Note that this guarantees
* that the return value will be >= 0 if and only if the key is found.
* @throws ClassCastException if the search key is not comparable to the
* elements of the array.
*/
public static int binarySearch(Object[] a, Object key) {
if (null == a || a.length == 0) {
return -1;
}
Arrays.sort(a);
final int index = Arrays.binarySearch(a, key);
return index < 0 ? -1 : index;
}
public static int indexOf(Class[] a, Class key) {
if (null == a || a.length == 0 || null == key) {
return -1;
}
for (int i = 0; i < a.length; i++) {
final Class item = a[i];
if (key.equals(item)) {
return i;
}
}
return -1;
}
public static int indexOf(char[] a, char key) {
if (null == a || a.length == 0) {
return -1;
}
for (int i = 0; i < a.length; i++) {
final char item = a[i];
if (key == item) {
return i;
}
}
return -1;
}
public static int indexOf(Object[] a, Object key) {
if (null == a || a.length == 0 || null == key) {
return -1;
}
for (int i = 0; i < a.length; i++) {
final Object item = a[i];
if (key.equals(item)) {
return i;
}
}
return -1;
}
public static int indexOf(final Object[] list, final String fieldName,
final Object fieldValue) {
if (!isEmpty(list)) {
int counter = 0;
for (final Object item : list) {
final Object value = BeanUtils.getValueIfAny(item, fieldName);
if (CompareUtils.equals(value, fieldValue)) {
return counter;
}
counter++;
}
}
return -1;
}
public static int indexOf(final Collection list, final String fieldName,
final Object fieldValue) {
if (!isEmpty(list)) {
final Iterator iterator = list.iterator();
int counter = 0;
while (iterator.hasNext()) {
final Object item = iterator.next();
final Object value = BeanUtils.getValueIfAny(item, fieldName);
if (CompareUtils.equals(value, fieldValue)) {
return counter;
}
counter++;
}
}
return -1;
}
@SuppressWarnings("unchecked")
public static int indexOfLike(Class[] a, Class key) {
if (null == a || a.length == 0 || null == key) {
return -1;
}
for (int i = 0; i < a.length; i++) {
final Class item = a[i];
// is 'item' equal or super-class of 'key'?
if (key.equals(item) || item.isAssignableFrom(key)) {
return i;
}
}
return -1;
}
public static Map merge(final Map... args) {
Map result = null;
for (final Map map : args) {
if (null != map) {
if (null == result) {
result = map;
} else {
result.putAll(map);
}
}
}
return result;
}
/**
* Combine a variable number of Arrays, returning a single array containing
* all (not null) values of passed arrays.
*
* @param arrays A variable number of arrays
* @return A single array, sum of passed parameters.
*/
public static Class[] merge(Class[]... arrays) {
List<Class> result = new LinkedList<Class>();
if (null != arrays && arrays.length > 0) {
for (Class[] array : arrays) {
if (null != array) {
for (final Class item : array) {
if (null != item) {
result.add(item);
}
}
}
}
}
return result.toArray(new Class[result.size()]);
}
/**
* Combine a variable number of Arrays, returning a single array containing
* all (not null) values of passed arrays.
*
* @param arrays A variable number of arrays
* @return A single array, sum of passed parameters.
*/
public static Object[] merge(Object[]... arrays) {
List<Object> result = new LinkedList<Object>();
if (null != arrays && arrays.length > 0) {
for (Object[] array : arrays) {
if (null != array) {
for (final Object item : array) {
if (null != item) {
result.add(item);
}
}
}
}
}
return result.toArray(new Object[result.size()]);
}
/**
* Combine a variable number of Collections.<br> Duplicates are not added to
* result list, and order is mantained.
*
* @param collections Variable number of collections
* @return LinkedList containig all collections items.
*/
public static Collection<?> mergeNoDuplicates(Collection<?>... collections) {
final Collection<Object> result = new LinkedList<Object>();
if (null != collections && collections.length > 0) {
for (final Collection<?> coll : collections) {
if (!result.contains(coll)) {
result.add(coll);
}
}
}
return result;
}
public static <T> Collection<T> add(final Collection<T> collection,
final T item) {
if (null != item) {
if (null != collection) {
collection.add(item);
}
}
return collection;
}
public static void add(final Collection<String> collection,
final String value,
final int minLength,
final boolean trim,
final boolean allowDuplicates) {
add(collection, value, minLength, trim, allowDuplicates, null);
}
public static void add(final Collection<String> collection,
final String value,
final int minLenght,
final boolean trim,
final boolean allowDuplicates,
final String[] excludes) {
if (null != value) {
if (null != collection) {
if (StringUtils.hasLength(value, minLenght)) {
if (!allowDuplicates) {
if (!collection.contains(value)) {
add(collection, value, trim, excludes);
}
} else {
add(collection, value, trim, excludes);
}
}
}
}
}
public static void add(final Collection<String> collection,
final String value,
final boolean trim,
final String[] excludes) {
if (isEmpty(excludes)) {
collection.add(trim ? value.trim() : value);
} else if (!contains(excludes, value)) {
collection.add(trim ? value.trim() : value);
}
}
/**
* Add item if not null and if does not exists in list
*
* @param <T>
* @param collection
* @param item
* @return
*/
public static <T> Collection<T> addNoDuplicates(final Collection<T> collection,
final T item) {
if (null != item) {
if (null != collection) {
if (!collection.contains(item)) {
collection.add(item);
}
}
}
return collection;
}
/**
* Add items to a collection avoiding dupicates.
*
* @param <T> Type of Objects
* @param collection Collection to add items to.
* @param items Items to add to collection
* @return Collection with all items
*/
public static <T> Collection<T> addAllNoDuplicates(final Collection<T> collection,
final Collection<T> items) {
if (null != items) {
if (null != collection) {
for (T item : items) {
if (!collection.contains(item)) {
collection.add(item);
}
}
}
}
return collection;
}
public static <T> Collection<T> addAllNoDuplicates(final Collection<T> collection,
final T[] items) {
if (null != items) {
if (null != collection) {
for (final T item : items) {
if (!collection.contains(item)) {
collection.add(item);
}
}
}
}
return collection;
}
public static <T> Collection<T> addAll(final Collection<T> collection,
final T[] items) {
if (null != items) {
if (null != collection) {
Collections.addAll(collection, items);
}
}
return collection;
}
public static <T> Set<List<T>> cartesianProduct(
final Collection<Collection<T>> sets) {
if (sets.size() < 2) {
throw new IllegalArgumentException(
"Can't have a product of fewer than two sets (got "
+ sets.size() + ")");
}
return _cartesianProduct(0, sets);
}
public static <T> Set<Map<String, T>> cartesianProduct(
final Map<String, Collection<T>> mapOfColl) {
if (mapOfColl.size() < 2) {
throw new IllegalArgumentException(
"Can't have a product of fewer than two sets (got "
+ mapOfColl.size() + ")");
}
return _cartesianProduct(0, mapOfColl);
}
public static Set<List<Object>> cartesianProduct(Collection<?>... sets) {
if (sets.length < 2) {
throw new IllegalArgumentException(
"Can't have a product of fewer than two sets (got "
+ sets.length + ")");
}
return _cartesianProduct(0, sets);
}
public static Set<List<Object>> cartesianProduct(Object[]... arrays) {
if (arrays.length < 2) {
throw new IllegalArgumentException(
"Can't have a product of fewer than two sets (got "
+ arrays.length + ")");
}
return _cartesianProduct(0, arrays);
}
public static Object[] toArray(final Object item) {
if (null != item) {
if (item.getClass().isArray()) {
return (Object[]) item;
}
final List<?> result = toList(item);
return result.toArray(new Object[result.size()]);
}
return new Object[0];
}
public static String[] toArrayOfString(final Iterator<?> item) {
final List<String> result = new LinkedList<String>();
while (item.hasNext()) {
final Object val = item.next();
if (null != val) {
result.add(val.toString());
}
}
return result.toArray(new String[result.size()]);
}
/**
* Convert Array, JSONObject, Map, into list
*
* @param item
* @return
*/
@SuppressWarnings("unchecked")
public static List toList(final Object item) {
final List result = new LinkedList();
try {
if (null != item) {
if (item.getClass().isArray()) {
CollectionUtils.addAll(result, (Object[]) item);
} else if (item instanceof Collection) {
result.addAll((Collection) item);
} else if (item instanceof Map) {
final Collection values = ((Map) item).values();
result.addAll(values);
} else if (item instanceof JSONObject) {
final Iterator<String> keys = ((JSONObject) item).keys();
while (keys.hasNext()) {
result.add(((JSONObject) item).opt(keys.next()));
}
} else if (item instanceof JSONArray) {
final JSONArray array = (JSONArray) item;
for (int i = 0; i < array.length(); i++) {
result.add(array.get(i));
}
} else if (item instanceof Iterator) {
final Iterator keys = ((Iterator) item);
while (keys.hasNext()) {
result.add(keys.next());
}
} else {
result.add(item);
}
}
} catch (Throwable ignored) {
}
return result;
}
public static <T> List<T> toList(T... args) {
return Arrays.asList(args);
}
public static boolean isEmpty(final Object variant) {
if (null == variant) {
return true;
}
if (variant instanceof Collection) {
return isEmpty((Collection) variant);
} else if (variant instanceof Map) {
return isEmpty((Map) variant);
} else if (variant.getClass().isArray()) {
return isEmpty((Object[]) variant);
}
return false;
}
/**
* Return whether the given array is empty: that is, null or of zero length.
*
* @param array the array to check
*/
public static boolean isEmpty(final Object[] array) {
return CollectionUtils.size(array) == 0;
}
/**
* Return whether the given collection is empty: that is, null or of zero
* length.
*
* @param collection the collection to check
*/
public static boolean isEmpty(final Collection collection) {
return CollectionUtils.size(collection) == 0;
}
/**
* Return whether the given map is empty: that is, null or of zero length.
*
* @param map the map to check
*/
public static boolean isEmpty(final Map map) {
return CollectionUtils.size(map) == 0;
}
/**
* Check if all items of current collection are assignable to passed class
*
* @param list Collection to check
* @param aclass Class
* @return True if all items in collection are assignable to passed class
*/
public static boolean isListOf(final Collection<?> list, final Class aclass) {
if (null == list) {
return false;
}
for (final Object item : list) {
if (null == item || !BeanUtils.isAssignable(item, aclass)) {
return false;
}
}
return true;
}
public static int size(final Object[] array) {
return null != array
? array.length
: 0;
}
public static int size(final Collection collection) {
return null != collection
? collection.size()
: 0;
}
public static int size(final Map map) {
return null != map
? map.size()
: 0;
}
/**
* Return token at index, or null if index is greater than tokens.
*
* @param commaseparated A comma separated string. i.e. "1,2,3,4,5"
* @param index Index of value in string.
* @return Null or token value. i.e. s=getToken("a,b,c,d,e", 1); // s=='b'
*/
public static String getToken(final String commaseparated,
final int index) {
return getToken(commaseparated, ",", index, null);
}
/**
* Return token at index, or null if index is greater than tokens.
*
* @param delimitedString A delimited string. i.e. "a:s:d:f:v"
* @param separator the delimiter. i.e. ":", ",", "|", etc..
* @param index Index of value in string.
* @return Null or token value. i.e. s=getToken("a:b:c:d:e", ":", 1); //
* s=='b'
*/
public static String getToken(final String delimitedString,
final String separator, final int index) {
return getToken(delimitedString, separator, index, null);
}
/**
* Return token at index, or null if index is greater than tokens.
*
* @param delimitedString A delimited string. i.e. "a:s:d:f:v"
* @param separator the delimiter. i.e. ":", ",", "|", etc..
* @param index Index of value in string.
* @param defaultValue Default value if result is null
* @return Null or token value. i.e. s=getToken("a:b:c:d:e", ":", 1); //
* s=='b'
*/
public static String getToken(final String delimitedString,
final String separator,
final int index,
final String defaultValue) {
final String[] array = StringUtils.split(delimitedString,
separator);
final String result = get(array, index);
return null != result ? result : defaultValue;
}
public static <T> T get(T[] array, int index) {
if (array.length < index + 1) {
return null;
}
return array[index];
}
public static <T> T get(final T[] array, final int index,
final T defaultValue) {
if (array.length < index + 1) {
return defaultValue;
}
final T result = array[index];
return null != result ? result : defaultValue; // array[index];
}
public static <T> T get(final Collection<T> collection, final int index) {
if (collection.size() < index + 1) {
return null;
}
int i = 0;
for (T item : collection) {
if (i == index) {
return item;
}
i++;
}
return null;
}
/**
* Return first item of an array. NULL if array is empty or is null.
*/
public static <T> T getFirst(T[] array) {
if (!isEmpty(array)) {
return array[0];
}
return null;
}
/**
* Return first item of a collection. NULL if collection is empty or is
* null.
*/
public static <T> T getFirst(Collection<T> collection) {
if (isEmpty(collection)) {
return null;
} else {
return collection.iterator().next();
}
}
/**
* Return last item of an array. NULL if array is empty or is null.
*/
public static <T> T getLast(final T[] array) {
if (!isEmpty(array)) {
return array[array.length - 1];
}
return null;
}
public static String getLast(final String delimitedText, final String delimiter) {
final String[] tokens = StringUtils.split(delimitedText, delimiter);
if (!isEmpty(tokens)) {
return getLast(tokens);
}
return "";
}
/**
* Return last item of a collection. NULL if collection is empty or has no
* items.<br> To retrieve last item, iterate entire collection.
*/
public static <T> T getLast(Collection<T> collection) {
if (isEmpty(collection)) {
return null;
} else {
T result = null;
Iterator<T> iterator = collection.iterator();
while (iterator.hasNext()) {
result = iterator.next();
}
return result;
}
}
/**
* Retrieve item in list by value of its property.
*
* @param properyName KEY property
* @param propertyValue VALUE of KEY property
* @return NULL or retrieved item.
*/
public static <T> T getByBeanProperty(
final Collection<T> list, final String properyName,
final Object propertyValue) {
if (StringUtils.hasText(properyName)) {
final Iterator<T> iterator = list.iterator();
while (iterator.hasNext()) {
final T item = iterator.next();
final Object itemValue = CollectionUtils._getValue(item, properyName);
if (null != itemValue && itemValue.equals(propertyValue)) {
return item;
}
}
}
return null;
}
// ------------------------------------------------------------------------
// p r i v a t e
// ------------------------------------------------------------------------
private static Object _getValue(final Object item, final String propertyName) {
try {
return BeanUtils.getValue(item, propertyName);
} catch (Exception ignored) {
}
return null;
}
private static <T> Set<List<T>> _cartesianProduct(int index,
final Collection<Collection<T>> sets) {
final Set<List<T>> ret = new LinkedHashSet<List<T>>();
if (index == sets.size()) {
ret.add(new LinkedList<T>());
} else {
for (final T obj : get(sets, index)) {
for (final List<T> set : _cartesianProduct(index + 1, sets)) {
set.add(0, obj);
ret.add(set);
}
}
}
return ret;
}
private static <T> Set<Map<String, T>> _cartesianProduct(int index,
final Map<String, Collection<T>> sets) {
final Set<Map<String, T>> ret = new LinkedHashSet<Map<String, T>>();
if (index == sets.size()) {
ret.add(new LinkedHashMap<String, T>());
} else {
final Collection<T> setOfValues = get(sets.values(), index);
final String keyOfValues = get(sets.keySet(), index);
for (final T obj : setOfValues) {
final Set<Map<String, T>> setOfMaps = _cartesianProduct(index + 1, sets);
for (final Map<String, T> set : setOfMaps) {
set.put(keyOfValues, obj);
ret.add(set);
}
}
}
return ret;
}
private static Set<List<Object>> _cartesianProduct(int index,
Collection<?>... sets) {
final Set<List<Object>> ret = new LinkedHashSet<List<Object>>();
if (index == sets.length) {
ret.add(new LinkedList<Object>());
} else {
for (final Object obj : sets[index]) {
for (final List<Object> set : _cartesianProduct(index + 1, sets)) {
set.add(0, obj);
ret.add(set);
}
}
}
return ret;
}
private static Set<List<Object>> _cartesianProduct(int index,
Object[]... arrays) {
final Set<List<Object>> ret = new LinkedHashSet<List<Object>>();
if (index == arrays.length) {
ret.add(new LinkedList<Object>());
} else {
for (final Object obj : arrays[index]) {
for (final List<Object> set : _cartesianProduct(index + 1, arrays)) {
set.add(0, obj);
ret.add(set);
}
}
}
return ret;
}
}