/*
* Copyright (c) 2006, 2010 Borland Software 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:
* Dmitry Stadnik (Borland) - initial API and implementation
*/
package org.eclipse.gmf.tests.setup.annotated;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.gmf.gmfgraph.Canvas;
import org.eclipse.gmf.gmfgraph.Compartment;
import org.eclipse.gmf.gmfgraph.Connection;
import org.eclipse.gmf.gmfgraph.DiagramLabel;
import org.eclipse.gmf.gmfgraph.Node;
import org.eclipse.gmf.mappings.CanvasMapping;
import org.eclipse.gmf.mappings.ChildReference;
import org.eclipse.gmf.mappings.CompartmentMapping;
import org.eclipse.gmf.mappings.DesignLabelMapping;
import org.eclipse.gmf.mappings.FeatureLabelMapping;
import org.eclipse.gmf.mappings.GMFMapFactory;
import org.eclipse.gmf.mappings.LabelMapping;
import org.eclipse.gmf.mappings.LinkMapping;
import org.eclipse.gmf.mappings.Mapping;
import org.eclipse.gmf.mappings.MappingEntry;
import org.eclipse.gmf.mappings.NodeMapping;
import org.eclipse.gmf.mappings.TopNodeReference;
import org.eclipse.gmf.tests.setup.MapDefSource;
import org.eclipse.gmf.tooldef.CreationTool;
import org.eclipse.gmf.tooldef.ToolRegistry;
/**
* Creates mapping model from annotated domain model.
*
* @author dstadnik
*/
public class MapDefASetup extends AbstractASetup implements MapDefSource {
protected EPackage ePackage;
protected Mapping mapping;
protected ToolRegistry registry;
protected Canvas canvas;
protected Map<EClass, List<ChildReference>> nodeMappings;
protected Map<EClass, List<CompartmentMapping>> compartmentMappings;
protected Map<EClass, List<FeatureLabelMapping>> labelMappings;
public MapDefASetup(EPackage ePackage, ToolRegistry registry, Canvas canvas) {
this.ePackage = ePackage;
this.registry = registry;
this.canvas = canvas;
}
protected Iterator<EObject> getAllDomainModelContents() {
return ePackage.eAllContents();
}
protected void createMapping() {
nodeMappings = new HashMap<EClass, List<ChildReference>>();
compartmentMappings = new HashMap<EClass, List<CompartmentMapping>>();
labelMappings = new HashMap<EClass, List<FeatureLabelMapping>>();
mapping = GMFMapFactory.eINSTANCE.createMapping();
processDomainModel();
// unwind nodes hierarchy
List<ChildReference> refs = nodeMappings.remove(mapping.getDiagram().getDomainMetaElement());
if (refs != null) {
for (ChildReference ref : refs) {
TopNodeReference tref = GMFMapFactory.eINSTANCE.createTopNodeReference();
tref.setContainmentFeature(ref.getContainmentFeature());
tref.setOwnedChild(ref.getOwnedChild());
mapping.getNodes().add(tref);
List<CompartmentMapping> compartments = compartmentMappings.remove(tref.getOwnedChild().getDomainMetaElement());
if (compartments != null) {
tref.getOwnedChild().getCompartments().addAll(compartments);
}
unwindNodeMappings(tref.getOwnedChild());
}
}
assert nodeMappings.isEmpty() : "Inconsistent gmf annotations (nodes)"; //$NON-NLS-1$
// distribute label mappings among node and link mappings
for (Iterator<EObject> it = mapping.eAllContents(); it.hasNext();) {
Object next = it.next();
if (next instanceof MappingEntry) {
MappingEntry entry = (MappingEntry) next;
List<FeatureLabelMapping> list = labelMappings.remove(entry.getDomainMetaElement());
if (list != null) {
for (FeatureLabelMapping lmapping : list) {
entry.getLabelMappings().add(lmapping);
}
}
}
}
assert labelMappings.isEmpty() : "Inconsistent gmf annotations (labels)"; //$NON-NLS-1$
}
protected void unwindNodeMappings(NodeMapping parent) {
List<ChildReference> refs = nodeMappings.remove(parent.getDomainMetaElement());
if (refs != null) {
for (ChildReference ref : refs) {
parent.getChildren().add(ref);
List<CompartmentMapping> compartments = compartmentMappings.remove(ref.getOwnedChild().getDomainMetaElement());
if (compartments != null) {
ref.getOwnedChild().getCompartments().addAll(compartments);
}
unwindNodeMappings(ref.getOwnedChild());
CompartmentMapping cmapping = findCompartment(parent, ref.getOwnedChild());
if (cmapping != null) {
ref.setCompartment(cmapping);
}
}
}
}
protected CompartmentMapping findCompartment(NodeMapping parent, NodeMapping child) {
List<Parameter> params = getParameters(child.getDomainMetaElement());
for (Parameter param : params) {
if ("in".equals(param.name)) { //$NON-NLS-1$
String comparmtentName = param.value;
assert comparmtentName != null;
for (CompartmentMapping cmapping : parent.getCompartments()) {
if (cmapping.getCompartment().getName().equals(comparmtentName)) {
return cmapping;
}
}
}
}
return null;
}
protected void processCanvas(EModelElement element, String name, List<Parameter> params) {
CanvasMapping cmapping = GMFMapFactory.eINSTANCE.createCanvasMapping();
cmapping.setDomainModel(ePackage);
cmapping.setDomainMetaElement((EClass) element);
cmapping.setPalette(registry.getPalette());
cmapping.setDiagramCanvas(canvas);
mapping.setDiagram(cmapping);
}
protected void processNode(EModelElement element, String name, List<Parameter> params) {
name = getName(element, name);
EReference containment = findReferenceByQName(ePackage, params, "containment"); //$NON-NLS-1$
assert ((EClass) containment.getEType()).isSuperTypeOf((EClass) element) : "Containment feature should contain instances of node class"; //$NON-NLS-1$
ChildReference ref = GMFMapFactory.eINSTANCE.createChildReference();
ref.setContainmentFeature(containment);
NodeMapping nmapping = GMFMapFactory.eINSTANCE.createNodeMapping();
nmapping.setDomainMetaElement((EClass) element);
nmapping.setTool(findCreationTool(element, name));
nmapping.setDiagramNode(findNode(element, name));
ref.setOwnedChild(nmapping);
List<ChildReference> refs = nodeMappings.get(containment.getEContainingClass());
if (refs == null) {
refs = new ArrayList<ChildReference>();
nodeMappings.put(containment.getEContainingClass(), refs);
}
refs.add(ref);
}
protected void processCompartment(EModelElement element, String name, List<Parameter> params) {
assert name != null;
CompartmentMapping cmapping = GMFMapFactory.eINSTANCE.createCompartmentMapping();
cmapping.setCompartment(findCompartment(element, name));
assert element instanceof EClass;
List<CompartmentMapping> list = compartmentMappings.get(element);
if (list == null) {
list = new ArrayList<CompartmentMapping>();
compartmentMappings.put((EClass) element, list);
}
list.add(cmapping);
}
protected void processLink(EModelElement element, String name, List<Parameter> params) {
name = getName(element, name);
LinkMapping lmapping = GMFMapFactory.eINSTANCE.createLinkMapping();
if (element instanceof EClass) {
EClass type = (EClass) element;
lmapping.setDomainMetaElement(type);
lmapping.setContainmentFeature(findReferenceByQName(ePackage, params, "containment")); //$NON-NLS-1$
lmapping.setSourceMetaFeature(findReference(type, "source")); //$NON-NLS-1$
lmapping.setLinkMetaFeature(findReference(type, "target")); //$NON-NLS-1$
} else {
lmapping.setLinkMetaFeature((EReference) element);
}
lmapping.setTool(findCreationTool(element, name));
lmapping.setDiagramLink(findConnection(element, name));
mapping.getLinks().add(lmapping);
}
protected void processLabel(EModelElement element, String name, List<Parameter> params) {
name = getName(element, name);
EAttribute attr = (EAttribute) element;
FeatureLabelMapping lmapping = GMFMapFactory.eINSTANCE.createFeatureLabelMapping();
lmapping.getFeatures().add(attr);
lmapping.setDiagramLabel(findLabel(element, name));
List<FeatureLabelMapping> list = labelMappings.get(attr.getEContainingClass());
if (list == null) {
list = new ArrayList<FeatureLabelMapping>();
labelMappings.put(attr.getEContainingClass(), list);
}
list.add(lmapping);
}
protected CreationTool findCreationTool(EModelElement element, String name) {
for (Iterator<EObject> it = registry.eAllContents(); it.hasNext();) {
EObject next = it.next();
if (next instanceof CreationTool) {
CreationTool tool = (CreationTool) next;
if (name.equals(tool.getTitle())) {
return tool;
}
}
}
return null;
}
protected Node findNode(EModelElement element, String name) {
for (Node node : canvas.getNodes()) {
if (name.equals(node.getName())) {
return node;
}
}
return null;
}
protected Compartment findCompartment(EModelElement element, String name) {
for (Compartment compartment : canvas.getCompartments()) {
if (name.equals(compartment.getName())) {
return compartment;
}
}
return null;
}
protected Connection findConnection(EModelElement element, String name) {
for (Connection connection : canvas.getConnections()) {
if (name.equals(connection.getName())) {
return connection;
}
}
return null;
}
protected DiagramLabel findLabel(EModelElement element, String name) {
for (DiagramLabel label : canvas.getLabels()) {
if (name.equals(label.getName())) {
return label;
}
}
return null;
}
// design
/**
* Removes all references to domain model.
*/
public void detachFromDomainModel() {
Mapping mapping = getMapping();
mapping.getDiagram().setDomainModel(null);
mapping.getDiagram().setDomainMetaElement(null);
for (TopNodeReference tref : mapping.getNodes()) {
tref.setContainmentFeature(null);
tref.setChildrenFeature(null);
detachNodeMapping(tref.getOwnedChild());
}
for (LinkMapping linkMapping : mapping.getLinks()) {
linkMapping.setContainmentFeature(null);
linkMapping.setDomainMetaElement(null);
linkMapping.setLinkMetaFeature(null);
linkMapping.setSourceMetaFeature(null);
linkMapping.setDomainInitializer(null);
linkMapping.setDomainSpecialization(null);
linkMapping.setCreationConstraints(null);
detachLabelMappings(linkMapping);
}
// check that mapping model was detached from domain model
for (Iterator<EObject> it = mapping.eAllContents(); it.hasNext();) {
EObject next = it.next();
for (EReference ref : next.eClass().getEAllReferences()) {
Object value = next.eGet(ref);
if (value == null) {
continue;
}
if (value instanceof List<?>) {
for (Object nvalue : (List<?>) value) {
checkNotDomainElement((EObject) nvalue);
}
} else {
checkNotDomainElement(((EObject) value));
}
}
}
}
protected void checkNotDomainElement(EObject obj) {
assert obj.eClass().getEPackage() != ePackage;
}
protected void detachNodeMapping(NodeMapping nodeMapping) {
nodeMapping.setDomainMetaElement(null);
nodeMapping.setDomainInitializer(null);
nodeMapping.setDomainSpecialization(null);
detachLabelMappings(nodeMapping);
for (ChildReference ref : nodeMapping.getChildren()) {
ref.setChildrenFeature(null);
ref.setContainmentFeature(null);
detachNodeMapping(ref.getOwnedChild());
}
}
protected void detachLabelMappings(MappingEntry entry) {
List<LabelMapping> list = entry.getLabelMappings();
for (int i = 0; i < list.size(); i++) {
LabelMapping labelMapping = list.get(i);
if (labelMapping instanceof FeatureLabelMapping) {
DesignLabelMapping newLebdelMapping = GMFMapFactory.eINSTANCE.createDesignLabelMapping();
newLebdelMapping.setDiagramLabel(labelMapping.getDiagramLabel());
newLebdelMapping.setReadOnly(labelMapping.isReadOnly());
list.set(i, newLebdelMapping);
}
}
}
// source
public Mapping getMapping() {
if (mapping == null) {
createMapping();
saveModel(mapping, "gmfmap"); //$NON-NLS-1$
validate(mapping);
}
return mapping;
}
public NodeMapping getNodeA() {
return null;
}
public NodeMapping getNodeB() {
return null;
}
public LinkMapping getClassLink() {
return null;
}
public LinkMapping getReferenceLink() {
return null;
}
}