blob: e3ebdecafe62a278dc57f3b733abf5bb0930960a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.stem.model.ui.editor;
import java.util.Iterator;
import java.util.List;
import org.eclipse.stem.model.common.MetamodelUtils;
import org.eclipse.stem.model.metamodel.Compartment;
import org.eclipse.stem.model.metamodel.Model;
import org.eclipse.stem.model.metamodel.Package;
import org.eclipse.stem.model.metamodel.Transition;
import org.eclipse.stem.model.ui.editor.vismodel.CanvasPackage;
import org.eclipse.stem.model.ui.editor.vismodel.CompartmentElement;
import org.eclipse.stem.model.ui.editor.vismodel.ModelElement;
import org.eclipse.stem.model.ui.editor.vismodel.TransitionElement;
import org.eclipse.stem.model.ui.editor.vismodel.VisualMetamodelFactory;
public class VisualModelReconciler
{
final static VisualMetamodelFactory FACTORY = VisualMetamodelFactory.eINSTANCE;
public static int DEFAULT_X_MARGIN = 5;
public static int DEFAULT_Y_MARGIN = 5;
public static int DEFAULT_WIDTH = 75;
public static int DEFAULT_HEIGHT = 75;
public static int DEFAULT_X_SPACING = DEFAULT_WIDTH + 30;
public static int DEFAULT_Y_SPACING = 0;
private Package metamodel;
private CanvasPackage vismodel;
private boolean vismodelChanged = false;
public VisualModelReconciler(Package metamodel, CanvasPackage vismodel)
{
this.metamodel = metamodel;
this.vismodel = vismodel;
}
private void flagVismodelChange() {
vismodelChanged = true;
}
public boolean isVismodelChanged() {
return vismodelChanged;
}
public void reconcile() {
reconcileMetamodel();
reconcileVismodel();
}
private ModelElement findElementForModel(Model m) {
for (ModelElement me : vismodel.getModelElements()) {
if (me.getModel() == m) {
return me;
}
}
return null;
}
private CompartmentElement findElementForCompartment(ModelElement me, Compartment c) {
for (CompartmentElement ce : me.getCompartmentElements()) {
if (ce.getCompartment() == c) {
return ce;
}
}
return null;
}
private TransitionElement findElementForTransition(ModelElement me, Transition t) {
for (TransitionElement te : me.getTransitionElements()) {
if (te.getTransition() == t) {
return te;
}
}
return null;
}
private void reconcileVismodel() {
Iterator<ModelElement> iter = vismodel.getModelElements().iterator();
while (iter.hasNext()) {
ModelElement me = iter.next();
if (me.getModel() != null) {
reconcileModelElement(me);
} else {
iter.remove();
flagVismodelChange();
}
}
}
private void reconcileModelElement(ModelElement me) {
reconcileCompartmentElements(me);
reconcileTransitionElements(me);
}
private void reconcileCompartmentElements(ModelElement me) {
Iterator<CompartmentElement> iter = me.getCompartmentElements().iterator();
while (iter.hasNext()) {
CompartmentElement ce = iter.next();
if (ce.getCompartment() == null ||
ce.getCompartment().eIsProxy()) {
iter.remove();
flagVismodelChange();
}
}
}
private void reconcileTransitionElements(ModelElement me) {
Iterator<TransitionElement> iter = me.getTransitionElements().iterator();
while (iter.hasNext()) {
TransitionElement te = iter.next();
if (te.getTransition() == null) {
iter.remove();
flagVismodelChange();
}
}
}
private void reconcileMetamodel() {
for (Model m : metamodel.getModels()) {
reconcileModel(m);
}
}
private void reconcileModel(Model m) {
ModelElement me = findElementForModel(m);
if (me == null) {
me = initializeModelElement(m);
vismodel.getModelElements().add(me);
flagVismodelChange();
}
reconcileCompartments(me,m);
reconcileTransitions(me,m);
}
private void reconcileCompartments(ModelElement me, Model m) {
int x = DEFAULT_X_MARGIN;
int y = DEFAULT_Y_MARGIN;
List<Compartment> compartments = MetamodelUtils.getAllCompartmentsForModel(m);
for (final Compartment compartment : compartments) {
CompartmentElement ce = findElementForCompartment(me, compartment);
if (ce == null) {
ce = createCompartmentElement(me, compartment, x, y);
me.getCompartmentElements().add(ce);
flagVismodelChange();
x += DEFAULT_X_SPACING;
y += DEFAULT_Y_SPACING;
//me.eResource().getContents().add(ce);
}
}
}
private void reconcileTransitions(ModelElement me, Model m) {
for (final Transition transition : m.getTransitions()) {
TransitionElement te = findElementForTransition(me, transition);
if (te == null) {
te = createTransitionElement(me, transition);
me.getTransitionElements().add(te);
flagVismodelChange();
//me.eResource().getContents().add(te);
}
}
}
public static CanvasPackage initializeForMetamodel(Package metamodel)
{
CanvasPackage canvasPackage = FACTORY.createCanvasPackage();
canvasPackage.setMetamodel(metamodel);
// create models
for (Model model : metamodel.getModels()) {
canvasPackage.getModelElements().add(initializeModelElement(model));
}
return canvasPackage;
}
public static ModelElement initializeModelElement(Model model) {
ModelElement me = FACTORY.createModelElement();
me.setModel(model);
initializeCompartments(me);
initializeTransitions(me);
return me;
}
private static void initializeCompartments(ModelElement me) {
int x = DEFAULT_X_MARGIN;
int y = DEFAULT_Y_MARGIN;
List<Compartment> compartments = MetamodelUtils.getAllCompartmentsForModel(me.getModel());
for (Compartment compartment : compartments) {
CompartmentElement ce = createCompartmentElement(me, compartment, x, y);
me.getCompartmentElements().add(ce);
x += DEFAULT_X_SPACING;
y += DEFAULT_Y_SPACING;
}
}
private static void initializeTransitions(ModelElement me) {
List<Transition> transitions = me.getModel().getTransitions();
for (Transition transition : transitions) {
me.getTransitionElements().add(createTransitionElement(me, transition));
}
}
private static CompartmentElement createCompartmentElement(ModelElement me, Compartment compartment, int x, int y) {
CompartmentElement ce = FACTORY.createCompartmentElement();
ce.setCompartment(compartment);
ce.setWidth(DEFAULT_WIDTH);
ce.setHeight(DEFAULT_HEIGHT);
ce.setX(x);
ce.setY(y);
return ce;
}
private static TransitionElement createTransitionElement(ModelElement me, Transition transition) {
TransitionElement te = FACTORY.createTransitionElement();
te.setTransition(transition);
te.setSource(VisualModelUtils.findCompartmentElementForCompartment(transition.getSource(), me));
te.setTarget(VisualModelUtils.findCompartmentElementForCompartment(transition.getTarget(), me));
if (te.getSource() == null || te.getTarget() == null) {
System.err.println("Could not find compartment element for source or target in transition "+ me.getModel().getName() +"/"+ transition.getName());
return null;
}
return te;
}
// private Model findModelForElement(ModelElement me) {
// for (Model model : metamodel.getModels()) {
// if (model == me.getModel()) {
// return model;
// }
// }
// return null;
//}
//
//private Compartment findCompartmentForElement(CompartmentElement ce) {
// Model model = ce.getModelElement().getModel();
// for (Compartment compartment : MetamodelUtils.getAllCompartmentsForModel(model)) {
// if (ce.getCompartment() == compartment) {
// return compartment;
// }
// }
//
// return null;
//}
//
//private Transition findTransitionForElement(TransitionElement te) {
// Model model = te.getModelElement().getModel();
// for (Transition transition : model.getTransitions()) {
// if (te.getTransition() == transition) {
// return transition;
// }
// }
//
// return null;
//}
}