package bndtools.model.resolution;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.framework.namespace.PackageNamespace;
public class CapReqMapContentProvider implements ITreeContentProvider {
private static final Object[] EMPTY = new Object[0];
private static final String[] NAMESPACE_ORDER = new String[] {
BundleNamespace.BUNDLE_NAMESPACE, IdentityNamespace.IDENTITY_NAMESPACE, HostNamespace.HOST_NAMESPACE, PackageNamespace.PACKAGE_NAMESPACE
};
private static final Set<String> NAMESPACES;
private final Comparator<Object> comparator = new CapReqComparator();
static {
NAMESPACES = new HashSet<>();
for (String s : NAMESPACE_ORDER)
NAMESPACES.add(s);
}
@Override
public void dispose() {}
@Override
public void inputChanged(Viewer viewer, Object oldValue, Object newValue) {}
@Override
public Object[] getElements(Object input) {
List<Object[]> arrays = new LinkedList<>();
@SuppressWarnings("unchecked")
Map<String,List<Object>> map = (Map<String,List<Object>>) input;
// Add entries for our preferred ordering of namespaces
for (String namespace : NAMESPACE_ORDER) {
List<Object> listForNs = map.get(namespace);
if (listForNs != null) {
Object[] array = listForNs.toArray();
Arrays.sort(array, comparator);
arrays.add(array);
}
}
// Now the rest in any order
for (Entry<String,List<Object>> entry : map.entrySet()) {
// Skip if namespace is a member of the namespaces we have already added.
if (NAMESPACES.contains(entry.getKey()))
continue;
List<Object> listForNs = entry.getValue();
Object[] array = listForNs.toArray();
Arrays.sort(array, comparator);
arrays.add(array);
}
return flatten(arrays);
}
private Object[] flatten(List<Object[]> arrays) {
// Iterate over once to count the lengths
int length = 0;
for (Object[] array : arrays) {
length += array.length;
}
Object[] result = new Object[length];
// Iterate again to flatten out the arrays
int position = 0;
for (Object[] array : arrays) {
System.arraycopy(array, 0, result, position, array.length);
position += array.length;
}
return result;
}
@Override
public Object getParent(Object object) {
return null;
}
@Override
public boolean hasChildren(Object object) {
boolean children = false;
if (object instanceof RequirementWrapper) {
RequirementWrapper rw = (RequirementWrapper) object;
children = rw.requirers != null && !rw.requirers.isEmpty();
}
return children;
}
@Override
public Object[] getChildren(Object parent) {
Object[] result = EMPTY;
if (parent instanceof RequirementWrapper) {
Collection< ? extends Object> requirers = ((RequirementWrapper) parent).requirers;
if (requirers != null)
result = requirers.toArray();
}
return result;
}
}