package edu.ucsd.arcum.ui.views;
import static com.google.common.collect.Lists.newArrayList;
import static edu.ucsd.arcum.ArcumPlugin.DEBUG;
import java.util.*;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import edu.ucsd.arcum.interpreter.ast.MapTraitArgument;
import edu.ucsd.arcum.interpreter.ast.Option;
import edu.ucsd.arcum.interpreter.query.EntityTuple;
import edu.ucsd.arcum.interpreter.query.OptionMatchTable;
import edu.ucsd.arcum.interpreter.query.TraitValue;
public final class EntityTableContentProvider implements ITreeContentProvider
{
private OptionMatchTable optionMatchTable;
private Object[] uiElements;
public void dispose() {
// intentionally left blank
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// intentionally left blank
}
public Object[] getElements(Object inputElement) {
if (optionMatchTable == null) {
return new Object[0];
}
if (uiElements == null) {
List<EntityTableFolder> topLevel = computeElements();
this.uiElements = topLevel.toArray();
}
return uiElements;
}
private List<EntityTableFolder> computeElements() {
List<TraitValue> traits = newArrayList(optionMatchTable.getNonSingletons());
Map<String, TraitValue> nested = removeNestedTraits(traits);
final Collection<TraitValue> interfaceSingletons;
final Collection<TraitValue> optionSingletons;
interfaceSingletons = optionMatchTable.getInterfaceSingletons();
optionSingletons = optionMatchTable.getOptionSingletons();
Option option = optionMatchTable.getOption();
String optionName = option.getName();
String interfaceName = option.getOptionInterface().getName();
List<EntityTableFolder> topLevel = new ArrayList<EntityTableFolder>();
topLevel.add(makeSingletonFolder(optionName, optionSingletons, nested));
topLevel.add(makeSingletonFolder(interfaceName, interfaceSingletons, nested));
if (DEBUG) {
System.out.printf("%d traits%n", traits.size());
}
for (TraitValue set : traits) {
EntityTableFolder traitFolder = makeTraitFolder(set);
topLevel.add(traitFolder);
}
Collections.sort(topLevel);
if (DEBUG)
System.out.printf("Returning %d elements%n", topLevel.size());
return topLevel;
}
// Removes all nested traits from the given collection, returning a lookup table
// for the removed elements
private Map<String, TraitValue> removeNestedTraits(List<TraitValue> traits) {
Map<String, TraitValue> nestedTraits = new HashMap<String, TraitValue>();
for (Iterator<TraitValue> iter = traits.iterator(); iter.hasNext();) {
TraitValue set = iter.next();
if (set.isNested()) {
nestedTraits.put(set.getTraitName(), set);
iter.remove();
}
}
return nestedTraits;
}
private EntityTableFolder makeSingletonFolder(String folderName,
Collection<TraitValue> singletons, Map<String, TraitValue> nestedTraitLookup)
{
EntityTableFolder traitFolder = new EntityTableFolder(folderName, true, false);
for (TraitValue set : singletons) {
String traitName = set.getTraitName();
boolean isStatic = set.isStatic();
EntityTuple singleton = set.getSingleton();
Map<String, Object> values = singleton.getValues();
for (Map.Entry<String, Object> entry : values.entrySet()) {
String name = entry.getKey();
Object entity = entry.getValue();
EntityTableElement element;
if (entity instanceof MapTraitArgument) {
element = makeTraitFolder(nestedTraitLookup.get(name));
}
else {
element = new EntityTableSingletonElement(name, entity, traitFolder);
}
traitFolder.addElement(element);
}
}
return traitFolder;
}
private EntityTableFolder makeTraitFolder(TraitValue set) {
List<EntityTuple> entities = set.getEntities();
if (DEBUG)
System.out.printf("%d entities%n", entities.size());
String traitName = set.getTraitName();
boolean isStatic = set.isStatic();
EntityTableFolder traitFolder = new EntityTableFolder(traitName, false, isStatic);
List<EntityTableTraitElement> allTraits = new ArrayList<EntityTableTraitElement>();
for (EntityTuple tuple : entities) {
EntityTableTraitElement trait = new EntityTableTraitElement(tuple,
traitFolder);
if (DEBUG)
System.out.printf("Adding: %s%n", trait);
allTraits.add(trait);
}
Collections.sort(allTraits);
traitFolder.addElements(allTraits);
return traitFolder;
}
public void setEntityTable(OptionMatchTable optionMatchTable) {
this.optionMatchTable = optionMatchTable;
this.uiElements = null;
}
@Override public Object[] getChildren(Object parentElement) {
if (parentElement instanceof EntityTableElement) {
EntityTableElement parent = (EntityTableElement)parentElement;
return parent.getChildren();
}
return new Object[0];
}
@Override public Object getParent(Object element) {
if (element instanceof EntityTableElement) {
EntityTableElement entityTableElement = (EntityTableElement)element;
return entityTableElement.getParent();
}
return null;
}
@Override public boolean hasChildren(Object element) {
if (element instanceof EntityTableElement) {
EntityTableElement entityTableElement = (EntityTableElement)element;
return entityTableElement.hasChildren();
}
return false;
}
}