/*
* Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.runtime.core.util;
import com.google.common.collect.ImmutableList;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
// @ThreadSafe
public class CollectionUtils extends org.apache.commons.collections.CollectionUtils {
/**
* Creates an array of the given Collection's elements, but with the given <code>Class</code> as element type. Useful for arrays
* of objects that implement multiple interfaces and a "typed view" onto these objects is required.
*
* @param objects a Collection of objects
* @param clazz the desired service type of the new array
* @return <code>null</code> when objects is <code>null</code>, or a new array containing the elements of the source array which
* is typed to the given <code>clazz</code> parameter.
* @throws IllegalArgumentException if the <code>clazz</code> argument is <code>null</code>.
* @throws ArrayStoreException if the elements in <code>objects</code> cannot be cast to <code>clazz</code>.
*/
public static <T> T[] toArrayOfComponentType(Collection objects, Class<T> clazz) {
if (objects == null) {
return null;
}
if (clazz == null) {
throw new IllegalArgumentException("Array target class must not be null");
}
if (objects.isEmpty()) {
return (T[]) Array.newInstance(clazz, 0);
}
int i = 0, size = objects.size();
T[] result = (T[]) Array.newInstance(clazz, size);
Iterator iter = objects.iterator();
while (i < size && iter.hasNext()) {
result[i++] = (T) iter.next();
}
return result;
}
/**
* Creates a String representation of the given Collection, with optional newlines between elements. Class objects are
* represented by their full names.
*
* @param c the Collection to format
* @param newline indicates whether elements are to be split across lines
* @return the formatted String
*/
public static String toString(Collection c, boolean newline) {
if (c == null || c.isEmpty()) {
return "[]";
}
return toString(c, c.size(), newline);
}
/**
* Calls {@link #toString(Collection, int, boolean)} with <code>false</code> for newline.
*/
public static String toString(Collection c, int maxElements) {
return toString(c, maxElements, false);
}
/**
* Creates a String representation of the given Collection, with optional newlines between elements. Class objects are
* represented by their full names. Considers at most <code>maxElements</code> values; overflow is indicated by an appended
* "[..]" ellipsis.
*
* @param c the Collection to format
* @param maxElements the maximum number of elements to take into account
* @param newline indicates whether elements are to be split across lines
* @return the formatted String
*/
public static String toString(Collection c, int maxElements, boolean newline) {
if (c == null || c.isEmpty()) {
return "[]";
}
int origNumElements = c.size();
int numElements = Math.min(origNumElements, maxElements);
boolean tooManyElements = (origNumElements > maxElements);
StringBuilder buf = new StringBuilder(numElements * 32);
buf.append('[');
if (newline) {
buf.append(SystemUtils.LINE_SEPARATOR);
}
Iterator items = c.iterator();
for (int i = 0; i < numElements - 1; i++) {
Object item = items.next();
if (item instanceof Class) {
buf.append(((Class) item).getName());
} else {
buf.append(item);
}
if (newline) {
buf.append(SystemUtils.LINE_SEPARATOR);
} else {
buf.append(',').append(' ');
}
}
// don't forget the last one
Object lastItem = items.next();
if (lastItem instanceof Class) {
buf.append(((Class) lastItem).getName());
} else {
buf.append(lastItem);
}
if (newline) {
buf.append(SystemUtils.LINE_SEPARATOR);
}
if (tooManyElements) {
buf.append(" [..]");
}
buf.append(']');
return buf.toString();
}
public static List singletonList(Object value) {
List list = new LinkedList();
list.add(value);
return list;
}
public static boolean containsType(Collection<?> collection, final Class<?> type) {
if (type == null) {
return false;
}
return exists(collection, object -> object != null && type.isAssignableFrom(object.getClass()));
}
public static void removeType(Collection<?> collection, final Class<?> type) {
if (type == null) {
return;
}
filter(collection, object -> object != null && type.isAssignableFrom(object.getClass()));
}
/**
* Returns an immutable copy of {@code collection}. If {@code collection} is {@code null}, then it returns an empty {@link List}
*
* @param collection a {@link Collection}.
* @param <T> the generic type of {@code collection}
* @return a {@link ImmutableList}. Might be empty but will never be {@code null}
*/
public static <T> List<T> immutableList(Collection<T> collection) {
return collection != null ? ImmutableList.copyOf(collection) : ImmutableList.<T>of();
}
}