package org.archstudio.xadl.swt;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import org.archstudio.xadl.XadlUtils;
import org.archstudio.xadl.swt.XadlTreeUtils.Type;
import org.archstudio.xarchadt.IXArchADT;
import org.archstudio.xarchadt.ObjRef;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.ui.IWorkbenchSite;
import com.google.common.collect.Iterables;
public class XadlTreeContentProvider implements ITreeContentProvider {
protected static final Object[] EMPTY_ARRAY = new Object[0];
protected IXArchADT xarch = null;
protected ObjRef rootRef;
protected Set<Type> flags = EnumSet.noneOf(Type.class);
protected List<Filter> filters = Collections.synchronizedList(new ArrayList<Filter>());
public XadlTreeContentProvider(IXArchADT xarch, ObjRef rootRef, Set<Type> flags) {
this.xarch = xarch;
this.rootRef = rootRef;
this.flags = flags;
}
public void addFilter(List<ObjRef> showOnlyTheseElements, Type type) {
Filter f = new Filter(showOnlyTheseElements, type);
filters.add(f);
}
public void clearFilters() {
filters.clear();
}
protected Filter getFilter(Type type) {
for (Filter f : filters) {
if (f.getType().equals(type)) {
return f;
}
}
return null;
}
public boolean shouldShow(Type type) {
return flags.contains(type);
}
@Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
protected boolean isAllowedByFilter(ObjRef ref, Type type) {
Filter f = getFilter(type);
if (f == null) {
return true;
}
for (ObjRef elt : f.getElts()) {
if (ref.equals(elt)) {
return true;
}
}
return false;
}
private void addChildren(List<ObjRef> l, ObjRef ref, String childName, Type childType) {
if (shouldShow(childType)) {
for (ObjRef childRef : Iterables.filter(xarch.getAll(ref, childName), ObjRef.class)) {
if (isAllowedByFilter(childRef, childType)) {
l.add(childRef);
}
}
}
}
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof XadlTreeInput) {
return new Object[] { xarch.get(rootRef, "xADL") };
}
else if (parentElement instanceof IWorkbenchSite) {
return new Object[] { xarch.get(rootRef, "xADL") };
}
else if (parentElement instanceof ObjRef) {
ObjRef ref = (ObjRef) parentElement;
Type type = XadlTreeUtils.getType(xarch, ref);
List<ObjRef> childList = new ArrayList<ObjRef>();
if (type.equals(Type.DOCUMENTROOT)) {
return new Object[] { xarch.get(ref, "xADL") };
}
else if (type.equals(Type.XADLELEMENT)) {
if (shouldShow(Type.STRUCTURE)) {
List<ObjRef> structureRefs = XadlUtils.getAllSubstitutionGroupElementsByTag(xarch, ref,
"topLevelElement", "structure");
for (ObjRef structureRef : structureRefs) {
if (isAllowedByFilter(structureRef, Type.STRUCTURE)) {
childList.add(structureRef);
}
}
}
}
else if (type.equals(Type.STRUCTURE)) {
addChildren(childList, ref, "component", Type.COMPONENT);
addChildren(childList, ref, "connector", Type.CONNECTOR);
}
else if (type.equals(Type.COMPONENT)) {
addChildren(childList, ref, "interface", Type.COMPONENT_INTERFACE);
}
else if (type.equals(Type.CONNECTOR)) {
addChildren(childList, ref, "interface", Type.CONNECTOR_INTERFACE);
}
return childList.toArray();
}
return EMPTY_ARRAY;
}
@Override
public Object getParent(Object element) {
if (element instanceof ObjRef) {
return xarch.getParent((ObjRef) element);
}
return null;
}
@Override
public boolean hasChildren(Object element) {
return getChildren(element).length > 0;
}
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
protected static class Filter {
public List<ObjRef> elts;
public Type type;
public Filter(List<ObjRef> elts, Type type) {
this.elts = Collections.unmodifiableList(new ArrayList<ObjRef>(elts));
this.type = type;
}
public List<ObjRef> getElts() {
return elts;
}
public Type getType() {
return type;
}
}
public static class XadlTreeInput {
}
}