/**
* Copyright (c) 2012-2016 Marsha Chechik, Alessio Di Sandro, Michalis Famelis,
* Rick Salay, Naama Ben-David.
* 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:
* Naama Ben-David - Implementation.
* Alessio Di Sandro - Generalization to all metamodels.
*/
package edu.toronto.cs.se.modelepedia.z3.mavo;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jdt.annotation.NonNull;
import edu.toronto.cs.se.mavo.LogicElement;
import edu.toronto.cs.se.mavo.MAVOCollection;
import edu.toronto.cs.se.mavo.MAVODecision;
import edu.toronto.cs.se.mavo.MAVOElement;
import edu.toronto.cs.se.mavo.MayDecision;
import edu.toronto.cs.se.mavo.MayDecisionLogic;
import edu.toronto.cs.se.mavo.SetDecision;
import edu.toronto.cs.se.mavo.VarDecision;
import edu.toronto.cs.se.mmint.MMINTException;
import edu.toronto.cs.se.mmint.mavo.library.MAVOGMFDiagramUtils;
import edu.toronto.cs.se.mmint.mid.editor.Diagram;
import edu.toronto.cs.se.mmint.mid.ui.GMFUtils;
import edu.toronto.cs.se.mmint.mid.utils.FileUtils;
public class MAVOConcretizationHighlighter {
private static final int HIGHLIGHT_COLOR = 0x1ACA1A;
private static final int FONT_HIGHLIGHT_COLOR = 0x005600;
private static final int GREYOUT_COLOR = 0xF4F4F4;
private static final int FONT_GREYOUT_COLOR = 0xD0D0D0;
private static final int[] DIFFERENT_COLORS = {
0xFF0000,
0x00FF00,
0x0000FF,
0xFFFF00,
0xFF00FF,
0x00FFFF
};
private static final int[] FONT_DIFFERENT_COLORS = {
0xD00000,
0x00D000,
0x0000D0,
0xD0D000,
0xD000D0,
0x00D0D0
};
private static final String EXAMPLE_MODEL_SUFFIX = "_example";
private Set<String> separateExampleElements(@NonNull Map<String, Set<String>> z3ModelObjs, @NonNull Map<String, View> diagramViews) {
Set<String> notInExampleFormulaVars = new HashSet<String>(diagramViews.keySet());
z3ModelObjs.values().forEach(formulaVars -> notInExampleFormulaVars.removeAll(formulaVars));
return notInExampleFormulaVars;
}
public void highlightMAVOCounterExample(@NonNull Diagram modelDiagram, @NonNull Map<String, Set<String>> z3ModelObjs) throws Exception {
// get view elements from diagram
org.eclipse.gmf.runtime.notation.Diagram exampleDiagram = (org.eclipse.gmf.runtime.notation.Diagram) FileUtils.readModelFile(modelDiagram.getUri(), true);
Map<String, View> diagramViews = MAVOGMFDiagramUtils.getDiagramViews(exampleDiagram);
// grey out model objects that are not in the example
Set<String> notInExampleFormulaVars = separateExampleElements(z3ModelObjs, diagramViews);
for (String notInExampleFormulaVar : notInExampleFormulaVars) {
highlightMAVOElement(diagramViews, notInExampleFormulaVar, GREYOUT_COLOR, FONT_GREYOUT_COLOR);
}
// write diagram to file
String exampleDiagramUri = FileUtils.addFileNameSuffixInUri(modelDiagram.getUri(), EXAMPLE_MODEL_SUFFIX);
FileUtils.writeModelFile(exampleDiagram, exampleDiagramUri, true);
FileUtils.openEclipseEditor(exampleDiagramUri, modelDiagram.getId(), true);
}
private void highlightMAVODecision(@NonNull Map<String, View> diagramViews, @NonNull MAVODecision mavoDecision) {
// highlight collections within the decision with different colors
List<MAVOCollection> mavoCollections = new ArrayList<MAVOCollection>();
if (mavoDecision instanceof MayDecision) {
mavoCollections.addAll(((MayDecision) mavoDecision).getAlternatives());
}
else if (mavoDecision instanceof VarDecision) {
mavoCollections.add(((VarDecision) mavoDecision).getDomain());
}
else if (mavoDecision instanceof SetDecision) {
mavoCollections.add(((SetDecision) mavoDecision).getEntity());
}
for (int i = 0; i < mavoCollections.size(); i++) {
MAVOCollection mavoCollection = mavoCollections.get(i);
for (MAVOElement mavoModelObj : mavoCollection.getMavoElements()) {
highlightMAVOElement(diagramViews, mavoModelObj, DIFFERENT_COLORS[i], FONT_DIFFERENT_COLORS[i]);
}
}
}
private void highlightMAVOCollection(@NonNull Map<String, View> diagramViews, @NonNull MAVOCollection mavoCollection) {
// (May) grey out may model objects in other alternatives for the same decision, highlight may model objects in the alternative
// (Var) highlight var model objects in the domain
MAVODecision mavoDecision = (MAVODecision) mavoCollection.eContainer();
if (mavoDecision instanceof MayDecision && ((MayDecision) mavoDecision).getLogic() == MayDecisionLogic.XOR) {
for (MAVOCollection otherMayAlternative : ((MayDecision) mavoDecision).getAlternatives()) {
if (otherMayAlternative == mavoCollection) {
continue;
}
for (MAVOElement otherMayModelObj : otherMayAlternative.getMavoElements()) {
highlightMAVOElement(diagramViews, otherMayModelObj, GREYOUT_COLOR, FONT_GREYOUT_COLOR);
}
}
}
for (MAVOElement mavoModelObj : mavoCollection.getMavoElements()) {
highlightMAVOElement(diagramViews, mavoModelObj, HIGHLIGHT_COLOR, FONT_HIGHLIGHT_COLOR);
}
}
private void highlightMAVOElement(@NonNull Map<String, View> diagramViews, @NonNull MAVOElement mavoModelObj, int color, int fontColor) {
// highlight model object and contained children
highlightMAVOElement(diagramViews, mavoModelObj.getFormulaVariable(), color, fontColor);
mavoModelObj.eContents().stream()
.filter(containedModelObj -> containedModelObj instanceof MAVOElement)
.forEach(mavoContainedModelObj -> highlightMAVOElement(diagramViews, (MAVOElement) mavoContainedModelObj, color, fontColor));
}
private void highlightMAVOElement(@NonNull Map<String, View> diagramViews, @NonNull String mavoModelObjFormulaVar, int color, int fontColor) {
// highlight model object
try {
View diagramView = diagramViews.get(mavoModelObjFormulaVar);
if (diagramView == null) {
throw new MMINTException("Can't find " + mavoModelObjFormulaVar + " in diagram");
}
GMFUtils.colorDiagramElement(diagramView, color, fontColor);
}
catch (MMINTException e) {
MMINTException.print(IStatus.WARNING, "Can't color diagram element, skipping it", e);
}
}
public void highlight(@NonNull Diagram modelDiagram, @NonNull LogicElement mavoElemToHighlight) throws Exception {
// get view elements from diagram
org.eclipse.gmf.runtime.notation.Diagram exampleDiagram = (org.eclipse.gmf.runtime.notation.Diagram) FileUtils.readModelFile(modelDiagram.getUri(), true);
Map<String, View> diagramViews = MAVOGMFDiagramUtils.getDiagramViews(exampleDiagram);
// highlight
if (mavoElemToHighlight instanceof MAVODecision) {
highlightMAVODecision(diagramViews, (MAVODecision) mavoElemToHighlight);
}
else if (mavoElemToHighlight instanceof MAVOCollection) {
highlightMAVOCollection(diagramViews, (MAVOCollection) mavoElemToHighlight);
}
else if (mavoElemToHighlight instanceof MAVOElement) {
highlightMAVOElement(diagramViews, (MAVOElement) mavoElemToHighlight, HIGHLIGHT_COLOR, FONT_HIGHLIGHT_COLOR);
}
// write diagram to file
String exampleDiagramUri = FileUtils.addFileNameSuffixInUri(modelDiagram.getUri(), EXAMPLE_MODEL_SUFFIX);
FileUtils.writeModelFile(exampleDiagram, exampleDiagramUri, true);
FileUtils.openEclipseEditor(exampleDiagramUri, modelDiagram.getId(), true);
}
}