/******************************************************************************* * Copyright (c) 2010-2015 Henshin developers. 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: * TU Berlin, University of Luxembourg, SES S.A. *******************************************************************************/ package de.tub.tfs.henshin.tgg.interpreter.impl; import java.util.List; import java.util.Map.Entry; import java.util.Set; import javax.script.ScriptContext; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.EcoreUtil.Copier; import org.eclipse.emf.henshin.interpreter.EGraph; import org.eclipse.emf.henshin.interpreter.Engine; import org.eclipse.emf.henshin.interpreter.Match; import org.eclipse.emf.henshin.interpreter.impl.EngineImpl; import org.eclipse.emf.henshin.model.Node; import de.tub.tfs.henshin.tgg.TripleComponent; import de.tub.tfs.henshin.tgg.interpreter.TggTransformation; public class ObjectCopier { private EGraph graph; private Engine engine; private TggTransformation trafo=null; private boolean handleMarkers=false; public ObjectCopier(EGraph graph,TggTransformation trafo, Engine e) //Engine e,HashMap<Node, Boolean> isTranslatedMap, HashMap<Attribute, Boolean> isTranslatedAttributeMap, HashMap<Edge, Boolean> isTranslatedEdgeMap) { assert(trafo != null):"Object copier is called with transformation, but it is not set."; this.graph = graph; this.trafo = trafo; this.engine = e; handleMarkers=true; } public ObjectCopier(EGraph graph, Engine e) { this.graph = graph; this.engine = (EngineImpl) e; } public void postProcess(Match m){ int i = 0; EObject source = null; EObject targetEObject = null; Set<Entry<String, Object>> entrySet = engine.getScriptEngine().getContext().getBindings(ScriptContext.ENGINE_SCOPE).entrySet(); for (Entry<String, Object> entry : entrySet) { if (!(entry.getValue() instanceof EObject)) continue; source = (EObject) entry.getValue(); if (m != null && source != null){ for (Node rhsNode : m.getRule().getRhs().getNodes()) { if (rhsNode.getName() != null && rhsNode.getName().equals("copy(" + entry.getKey() + ")")){ targetEObject = m.getNodeTarget(rhsNode); if (targetEObject != null){ //assert (graph instanceof TggHenshinEGraph): "Graph should be a triple graph"; //TggHenshinEGraph tggGraph = (TggHenshinEGraph) graph; //Map<EObject,Node> objToNodeMap = null; // if (graph instanceof TggHenshinEGraph){ // objToNodeMap = tggGraph.getObject2NodeMap(); // } // if (graph instanceof HenshinEGraph){ // objToNodeMap = ((HenshinEGraph) graph).getObject2NodeMap(); // } //TNode targetNode = (TNode) objToNodeMap.get(targetEObject); TripleComponent targetComponent = TripleComponent.TARGET; //assert (tggGraph.getHenshinGraph() instanceof TripleGraph):"Graph should be a triple graph"; //int targetXCoordinate = ((TripleGraph)tggGraph.getHenshinGraph()).getDividerCT_X(); Copier copier = new Copier(); EObject newTarget = copier.copy(source); copier.copyReferences(); graph.addTree(newTarget); // set component and X-value of new target node //TNode newTargetNode = (TNode) objToNodeMap.get(newTarget); //assert (newTargetNode!=null) : "Object copier tries to access the created node, but is is not contained in the graph"; //targetNode.setX(targetXCoordinate); // set component of new node TripleComponent componentOfNewNodes = trafo.getTripleComponentNodeMap().get(targetEObject); trafo.getTripleComponentNodeMap().put(newTarget,componentOfNewNodes); if(handleMarkers) setMarkers(source); for (EStructuralFeature feat : newTarget.eClass().getEAllStructuralFeatures()) { newTarget.eSet(feat, newTarget.eGet(feat)); //?? FIXME: this seems to have no effect } TreeIterator<EObject> iterator = source.eAllContents(); while (iterator.hasNext()){ EObject srcNext = iterator.next(); EObject tgtNext = copier.get(srcNext); if (tgtNext == null) continue; //assert (objToNodeMap != null) : "Object to node map of Henshin graph is missing."; //TNode targetNextNode = (TNode) objToNodeMap.get(tgtNext); //targetNextNode.setX(targetXCoordinate); // set component of new node trafo.getTripleComponentNodeMap().put(tgtNext,componentOfNewNodes); if(handleMarkers) setMarkers(srcNext); for (EStructuralFeature feat : tgtNext.eClass().getEAllStructuralFeatures()) { tgtNext.eSet(feat, tgtNext.eGet(feat)); //?? FIXME: this seems to have no effect } } EObject container = targetEObject.eContainer(); if (container != null){ if (targetEObject.eContainingFeature().isMany()) { List<EObject> list = (List<EObject>) container .eGet(targetEObject .eContainingFeature()); int indexOf = list.indexOf(targetEObject); list.add(indexOf, newTarget); list.remove(targetEObject); // container.eSet(target.eContainingFeature(), // newTarget); } else { container.eSet( targetEObject.eContainingFeature(), newTarget); } } graph.remove(targetEObject); trafo.getTripleComponentNodeMap().remove(targetEObject); //engine.getScriptEngine().put("source"+i, null); i++; } } } } } } private void setMarkers(EObject o) { assert (trafo!=null):"TggTransformation is missing."; trafo.fillTranslatedMaps(o,true); } }