/******************************************************************************* * 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.editor.actions.transSys; import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import org.eclipse.draw2d.geometry.Point; import org.eclipse.emf.common.ui.dialogs.ResourceDialog; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.resource.impl.ResourceImpl; import org.eclipse.emf.henshin.model.Attribute; import org.eclipse.emf.henshin.model.Edge; import org.eclipse.emf.henshin.model.Graph; import org.eclipse.emf.henshin.model.HenshinFactory; import org.eclipse.emf.henshin.model.HenshinPackage; import org.eclipse.emf.henshin.model.Module; import org.eclipse.emf.henshin.model.NamedElement; import org.eclipse.emf.henshin.model.Node; import org.eclipse.gef.EditPart; import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.gef.ui.actions.SelectionAction; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PlatformUI; import de.tub.tfs.henshin.editor.commands.SimpleAddEObjectCommand; import de.tub.tfs.henshin.editor.util.HenshinLayoutUtil; import de.tub.tfs.henshin.editor.util.IconUtil; import de.tub.tfs.henshin.editor.util.NodeUtil; import de.tub.tfs.henshin.model.layout.EContainerDescriptor; import de.tub.tfs.henshin.model.layout.HenshinLayoutFactory; import de.tub.tfs.henshin.model.layout.HenshinLayoutPackage; import de.tub.tfs.henshin.model.layout.Layout; import de.tub.tfs.henshin.model.layout.LayoutSystem; import de.tub.tfs.henshin.model.layout.NodeLayout; public class ImportInstanceModelAction extends SelectionAction { /** The Constant ID. */ public static final String ID = "henshineditor.actions.ImportInstanceModelAction"; private Module transformationSystem; public ImportInstanceModelAction(IWorkbenchPart part) { super(part); setId(ID); setText("Import EMF Instance Model..."); setImageDescriptor(IconUtil.getDescriptor("attr16.png")); setToolTipText("Imports an instance model."); } @Override protected boolean calculateEnabled() { List<?> selectedObjects = getSelectedObjects(); transformationSystem = null; if (selectedObjects.size() == 1) { Object selectedObject = selectedObjects.get(0); if ((selectedObject instanceof EditPart)) { EditPart editpart = (EditPart) selectedObject; Object model = editpart.getModel(); if (model instanceof Module) { transformationSystem = (Module) model; } else if (model instanceof EContainerDescriptor && editpart.getAdapter(Graph.class) != null) { transformationSystem = (Module) ((EContainerDescriptor) model) .getContainer(); } } } return transformationSystem != null; } @SuppressWarnings("unchecked") @Override public void run() { Shell shell = new Shell(); ResourceDialog dialog = new ResourceDialog(shell, "Please select the instance model you want to load.", SWT.OPEN + SWT.MULTI); HashMap<EObject, Node> instanceGraphToHenshinGraphMapping = new HashMap<EObject, Node>(); int p = dialog.open(); if (p == 1) { return; } List<URI> urIs = dialog.getURIs(); shell.dispose(); if (urIs.isEmpty()) { MessageDialog .open(SWT.ERROR, PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage() .getActivePart().getSite().getShell(), "No File selected.", "Please select a valid emf file to load an instance model.", SWT.SHEET); return; } for (URI uri : urIs) { ResourceImpl r = (ResourceImpl) transformationSystem.eResource() .getResourceSet().getResource(uri, true); r.unload(); try { r.load(null); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Graph graph = HenshinFactory.eINSTANCE.createGraph(); if (r.getContents().isEmpty()) continue; TreeIterator<EObject> itr = r.getAllContents(); graph.setName(uri.segment(uri.segmentCount() - 1)); while (itr.hasNext()) { EObject eObj = itr.next(); Node node = HenshinFactory.eINSTANCE.createNode(); node.setType(eObj.eClass()); node.setName(""); instanceGraphToHenshinGraphMapping.put(eObj, node); graph.getNodes().add(node); } itr = r.getAllContents(); while (itr.hasNext()) { EObject eObj = itr.next(); Node node = instanceGraphToHenshinGraphMapping.get(eObj); for (EStructuralFeature feat : eObj.eClass() .getEAllStructuralFeatures()) { if (eObj.eIsSet(feat)) { if (feat instanceof EReference) { if (feat.isMany()) { List<EObject> list = (List<EObject>) eObj .eGet(feat); for (EObject ref : list) { Edge edge = HenshinFactory.eINSTANCE .createEdge(); edge.setSource(node); if (instanceGraphToHenshinGraphMapping .containsKey(ref)) { edge.setTarget(instanceGraphToHenshinGraphMapping .get(ref)); } else { edge.setTarget(createTargetNode(ref, graph)); } edge.setType((EReference) feat); graph.getEdges().add(edge); } } else { EObject ref = (EObject) eObj.eGet(feat); Edge edge = HenshinFactory.eINSTANCE .createEdge(); edge.setSource(node); if (instanceGraphToHenshinGraphMapping .containsKey(ref)) { edge.setTarget(instanceGraphToHenshinGraphMapping .get(ref)); } else { edge.setTarget(createTargetNode(ref, graph)); } edge.setType((EReference) feat); graph.getEdges().add(edge); } } else if (feat instanceof EAttribute) { if (feat.isMany()) { // cannot handle array attributes right now } else { Attribute attr = HenshinFactory.eINSTANCE .createAttribute(); attr.setNode(node); attr.setType((EAttribute) feat); attr.setValue(eObj.eGet(feat).toString()); if (attr.getType().getName().contains("name") && !(eObj instanceof NamedElement)) { node.setName(attr.getValue()); } } } } } } LinkedList<Layout> layouts = new LinkedList<Layout>(); for (Node n : graph.getNodes()) { NodeLayout l = HenshinLayoutFactory.eINSTANCE .createNodeLayout(); l.setModel(n); Point loc = NodeUtil.calculatePosition( NodeUtil.getPoints2NodeLyouts(n, layouts), l); l.setX(loc.x); l.setY(loc.y); layouts.add(l); } CompoundCommand cmd = new CompoundCommand("Import Instance Graph"); LayoutSystem layoutSystem = HenshinLayoutUtil.INSTANCE .getLayoutSystem(transformationSystem); for (Layout l : layouts) { cmd.add(new SimpleAddEObjectCommand<EObject, EObject>(l, HenshinLayoutPackage.LAYOUT_SYSTEM__LAYOUTS, layoutSystem)); } cmd.add(new SimpleAddEObjectCommand<EObject, EObject>(graph, HenshinPackage.MODULE__INSTANCES, transformationSystem)); execute(cmd); } } private HashMap<Graph, HashMap<EObject, Node>> graphToNodeMap = new HashMap<Graph, HashMap<EObject, Node>>(); private Node createTargetNode(EObject ref, Graph graph) { HashMap<EObject, Node> map = graphToNodeMap.get(graph); if (map == null) graphToNodeMap.put(graph, map = new HashMap<EObject, Node>()); Node node = map.get(ref); if (node == null) { node = HenshinFactory.eINSTANCE.createNode(); node.setType(ref.eClass()); node.setName(ref.toString()); graph.getNodes().add(node); map.put(ref, node); } return node; } }