/*******************************************************************************
* Copyright (c) 2010-2012, Istvan Rath, Zoltan Ujhelyi and Daniel Varro
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Istvan Rath, Zoltan Ujhelyi - initial API and implementation
*******************************************************************************/
package org.eclipse.incquery.tooling.ui.retevis.views;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Vector;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.text.FlowPage;
import org.eclipse.draw2d.text.TextFlow;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.gef4.zest.core.viewers.IEntityStyleProvider;
import org.eclipse.incquery.patternlanguage.patternLanguage.Pattern;
import org.eclipse.incquery.patternlanguage.patternLanguage.Variable;
import org.eclipse.incquery.runtime.rete.boundary.ReteBoundary;
import org.eclipse.incquery.runtime.rete.construction.Stub;
import org.eclipse.incquery.runtime.rete.construction.psystem.PConstraint;
import org.eclipse.incquery.runtime.rete.construction.psystem.PVariable;
import org.eclipse.incquery.runtime.rete.index.Indexer;
import org.eclipse.incquery.runtime.rete.index.IndexerWithMemory;
import org.eclipse.incquery.runtime.rete.matcher.RetePatternMatcher;
import org.eclipse.incquery.runtime.rete.misc.ConstantNode;
import org.eclipse.incquery.runtime.rete.network.Node;
import org.eclipse.incquery.runtime.rete.network.Production;
import org.eclipse.incquery.runtime.rete.remote.Address;
import org.eclipse.incquery.runtime.rete.single.UniquenessEnforcerNode;
import org.eclipse.incquery.runtime.rete.tuple.Tuple;
import org.eclipse.incquery.tooling.ui.retevis.theme.ColorTheme;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Color;
public class ZestReteLabelProvider extends LabelProvider implements IEntityStyleProvider {
private final int INDEXER_ID = 0;
private final int RETEMATCHER_ID = 1;
private final int INPUT_ID = 2;
private ReteBoundary rb;
private ColorTheme theme;
/**
* Sets the colors of the indexer and rete matcher nodes
*
* @param indexerColor
* @param reteMatcherColor
*/
public void setColors(ColorTheme theme) {
this.theme = theme;
}
public ReteBoundary getRb() {
return rb;
}
public void setRb(ReteBoundary rb) {
this.rb = rb;
// initialize reverse traceability information
resetReverseMap();
for (Object _o : rb.getAllProductionNodes()) {
Node productionNode = rb.getHeadContainer().resolveLocal((Address<?>) _o);
if (productionNode != null && productionNode instanceof Production) {
initalizeReverseMap((Production) productionNode);
}
}
}
@Override
public String getText(Object element) {
if (element instanceof Node) {
Node n = (Node) element;
Class<?> namedClass = n.getClass();
String simpleName;
do {
simpleName = namedClass.getSimpleName();
namedClass = namedClass.getSuperclass();
} while (simpleName == null || simpleName.isEmpty());
String s = "" + simpleName;
if (n instanceof UniquenessEnforcerNode) {
// print tuplememory statistics
UniquenessEnforcerNode un = (UniquenessEnforcerNode) n;
if (un.getParents().isEmpty() && un.getTag() instanceof ENamedElement) {
s += " : " + ((ENamedElement) un.getTag()).getName() + " : ";
}
s += " [" + (un).getMemory().size() + "]";
}
if (n instanceof IndexerWithMemory) {
s += "[" + ((IndexerWithMemory) n).getMemory().getSize() + "]";
}
if (!(n instanceof UniquenessEnforcerNode || n instanceof ConstantNode)) {
StringBuilder sb = new StringBuilder();
sb.append("\n");
for (Stub st : getStubsForNode(n)) {
sb.append("<");
Tuple variablesTuple = st.getVariablesTuple();
for (Object obj : variablesTuple.getElements()) {
if (obj instanceof PVariable) {
Object nameObj = ((PVariable) obj).getName();
if (nameObj instanceof Variable) {
sb.append(((Variable) nameObj).getName());
}
}
sb.append("; ");
}
sb.append("> ");
s += sb.toString();
}
}
return s;
}
return "!";
// return s+super.getText(element);
}
@Override
public IFigure getTooltip(Object entity) {
if (entity instanceof Node) {
Node n = (Node) entity;
String s = "";
for (Stub st : getStubsForNode(n)) {
s += getEnforcedConstraints(st);
}
FlowPage fp = new FlowPage();
TextFlow nameTf = new TextFlow();
// nameTf.setFont(fontRegistry.get("default"));
TextFlow infoTf = new TextFlow();
// infoTf.setFont(fontRegistry.get("code"));
nameTf.setText(n.toString());
String info = "";// "\n";
info += "Stubs:\n" + s;// +"\n";
infoTf.setText(info);
if (entity instanceof RetePatternMatcher) {
if (((Node) entity).getTag() instanceof Pattern) {
Pattern pattern = (Pattern) ((Node) entity).getTag();
nameTf.setText(pattern.getName());
fp.add(nameTf);
}
} else if (entity instanceof ConstantNode) {
ConstantNode node = (ConstantNode) entity;
ArrayList<Tuple> arrayList = new ArrayList<Tuple>();
node.pullInto(arrayList);
StringBuilder sb = new StringBuilder();
for (Tuple tuple : arrayList) {
sb.append(tuple.toString() + "\n");
}
nameTf.setText(sb.toString());
fp.add(nameTf);
}
fp.add(infoTf);
return fp;
}
return null;
}
// useful only for production nodes
private static String getEnforcedConstraints(Stub st) {
String s = "";
for (Object _pc : st.getAllEnforcedConstraints()) {
PConstraint pc = (PConstraint) _pc;
s += "\t[" + pc.getClass().getSimpleName() + "]:";
for (Object _v : pc.getAffectedVariables()) {
PVariable v = (PVariable) _v;
s += "{" + v.getName() + "}";
}
s += "\n";
}
return s;
}
private Collection<Stub<Address<?>>> getStubsForNode(Node n) {
Collection<Stub<Address<?>>> r = reverseMap.get(n);
if (r != null)
return r;
else
return Collections.EMPTY_SET;
}
Map<Node, Collection<Stub<Address<?>>>> reverseMap;// = new HashMap<Node, Collection<Stub<Address<?>>>>();
private void resetReverseMap() {
reverseMap = new HashMap<Node, Collection<Stub<Address<?>>>>();
}
private void initalizeReverseMap(Production prod) {
for (Object _stubOfProd : rb.getParentStubsOfReceiver(new Address<Node>(prod))) {
Stub stubOfProd = (Stub) _stubOfProd;
for (Stub<Address<?>> s : getAllParentStubs(stubOfProd)) {
Address<Node> address = (Address<Node>) s.getHandle();
Node n = rb.getHeadContainer().resolveLocal(address);
Collection<Stub<Address<?>>> t = reverseMap.get(n);
if (t == null) {
t = new HashSet<Stub<Address<?>>>();
}
t.add(s);
reverseMap.put(n, t);
}
}
}
private static Collection<Stub<Address<?>>> getAllParentStubs(Stub<Address<?>> st) {
if (st != null) {
Vector<Stub<Address<?>>> v = new Vector<Stub<Address<?>>>();
v.add(st);
v.addAll(getAllParentStubs(st.getPrimaryParentStub()));
v.addAll(getAllParentStubs(st.getSecondaryParentStub()));
return v;
} else
return Collections.EMPTY_LIST;
}
@Override
public Color getNodeHighlightColor(Object entity) {
// TODO Auto-generated method stub
return null;
}
@Override
public Color getBorderColor(Object entity) {
// TODO Auto-generated method stub
return null;
}
@Override
public Color getBorderHighlightColor(Object entity) {
// TODO Auto-generated method stub
return null;
}
@Override
public int getBorderWidth(Object entity) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Color getBackgroundColour(Object entity) {
if (entity instanceof Indexer) {
return theme.getNodeColor(INDEXER_ID);
} else if (entity instanceof RetePatternMatcher) {
return theme.getNodeColor(RETEMATCHER_ID);
} else if (entity instanceof UniquenessEnforcerNode) {
UniquenessEnforcerNode inputNode = (UniquenessEnforcerNode) entity;
if (inputNode.getParents().isEmpty()) {
return theme.getNodeColor(INPUT_ID);
}
}
return null;
}
@Override
public Color getForegroundColour(Object entity) {
if (entity instanceof Indexer) {
return theme.getTextColor(INDEXER_ID);
} else if (entity instanceof RetePatternMatcher) {
return theme.getTextColor(RETEMATCHER_ID);
} else if (entity instanceof UniquenessEnforcerNode) {
UniquenessEnforcerNode inputNode = (UniquenessEnforcerNode) entity;
if (inputNode.getParents().isEmpty()) {
return theme.getTextColor(INPUT_ID);
}
}
return null;
}
@Override
public boolean fisheyeNode(Object entity) {
// TODO Auto-generated method stub
return true;
}
}