package gov.nasa.jpl.mbee.mdk.util;
import java.util.ArrayList;
import java.util.Collection;
/**
* Manages additions to nested collections based on policy of several
* attributes.
*/
public class CollectionAdder {
public boolean mustFlatten = false;
public boolean mayFlatten = false;
public boolean flattenIfSizeOne = false;
public boolean flattenToNullIfEmpty = false;
public int defaultFlattenDepth = 1;
public boolean nullOk = true;
public boolean onlyAddOne = false;
public Class<?> unflattenedCollectionType = ArrayList.class;
/**
* @param mustFlatten
* @param mayFlatten
* @param flattenIfSizeOne
* @param flattenToNullIfEmpty
* @param defaultFlattenDepth
* @param nullOk
*/
public CollectionAdder(boolean mustFlatten, boolean mayFlatten, boolean flattenIfSizeOne,
boolean flattenToNullIfEmpty, int defaultFlattenDepth, boolean nullOk, boolean onlyAddOne,
Class<?> unflattenedCollectionType) {
this.mustFlatten = mustFlatten;
this.mayFlatten = mayFlatten;
this.flattenIfSizeOne = flattenIfSizeOne;
this.flattenToNullIfEmpty = flattenToNullIfEmpty;
this.defaultFlattenDepth = defaultFlattenDepth;
this.nullOk = nullOk;
this.onlyAddOne = onlyAddOne;
this.unflattenedCollectionType = unflattenedCollectionType;
}
public CollectionAdder() {
}
public boolean add(Object o, Collection<Object> list) {
return add(o, list, defaultFlattenDepth);
}
/**
* Fix an existing Collection according to the ListBuilder's properties.
*
* @param coll the input Collection
* @return the original collection or a new instance of
* unflattenedCollectionType
*/
public Object fix(Collection<?> coll) {
return fix(coll, defaultFlattenDepth);
}
/**
* Fix an existing collection according to the ListBuilder's properties.
*
* @param coll
* @param flattenDepth
* @return the original collection or a new unflattenedCollectionType
* collection
*/
@SuppressWarnings("unchecked")
public Object fix(Collection<?> coll, int flattenDepth) {
if (!mustFlatten && (!mayFlatten || flattenDepth <= 0)) {
return coll;
}
Object result = coll;
if (coll.isEmpty()) {
if (mustFlatten || flattenToNullIfEmpty) {
result = null;
}
}
else if (coll.size() == 1 && flattenIfSizeOne) {
result = coll.iterator().next();
}
else {
// flatten!
// Collection< Object > newList;
ArrayList<Object> newList = new ArrayList<Object>();
// try {
// newList = (Collection< Object
// >)unflattenedCollectionType.newInstance();
// } catch ( InstantiationException e ) {
// newList = new ArrayList<Object>();
// } catch ( IllegalAccessException e ) {
// newList = new ArrayList<Object>();
// }
result = newList;
// ListBuilder adder = new ListBuilder( mustFlatten, mayFlatten,
// flattenIfSizeOne, flattenToNullIfEmpty, flattenDepth-1, nullOk,
// onlyAddOne, unflattenedCollectionType );
for (Object child : coll) {
boolean added = true;
if (child instanceof Collection) {
added = add(child, newList, flattenDepth - 1);
}
else {
newList.add(child);
}
if (onlyAddOne && added) {
break;
}
}
}
// fixType
if (result instanceof Collection) {
if (unflattenedCollectionType != null && !unflattenedCollectionType.isInstance(result)) {
Collection<Object> newColl = null;
try {
Object o = unflattenedCollectionType.newInstance();
if (o instanceof Collection) {
newColl = (Collection<Object>) o;
}
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
}
if (newColl != null) {
newColl.addAll((Collection<? extends Object>) result);
result = newColl;
}
}
}
return result;
}
public boolean add(Object o, Collection<Object> list, int flattenDepth) {
if (o == null) {
if (nullOk) {
list.add(null);
}
return nullOk;
}
if ((o instanceof Collection) && (mustFlatten || (mayFlatten && flattenDepth > 0))) {
Collection<?> coll = (Collection<?>) o;
if (coll.isEmpty()) {
if (mustFlatten || flattenToNullIfEmpty) {
add(null, list, flattenDepth - 1);
return true;
}
return false;
}
if (coll.size() != 1 || !flattenIfSizeOne) {
boolean didAdd = false;
for (Object child : coll) {
boolean added = add(child, list, flattenDepth - 1);
if (added) {
if (onlyAddOne) {
return true;
}
didAdd = true;
}
}
return didAdd;
} // else add unflattened below
// if ( unflattenedCollectionType != null &&
// !unflattenedCollectionType.isInstance( coll ) ) {
// Collection< ? > newColl =
// unflattenedCollectionType.newInstance();
// newColl.addAll( (Collection< ? >)coll );
// return didAdd;
// }
// }
}
list.add(o);
return true;
}
}