/******************************************************************************* * 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.tggeditor.actions.imports; import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Vector; import org.eclipse.emf.common.ui.dialogs.ResourceDialog; 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.impl.DynamicEObjectImpl; import org.eclipse.emf.ecore.resource.impl.ResourceImpl; import org.eclipse.emf.ecore.xmi.XMLResource; 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.Module; import org.eclipse.emf.henshin.model.NamedElement; import org.eclipse.gef.EditPart; 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.tgg.ImportedPackage; import de.tub.tfs.henshin.tgg.TGG; import de.tub.tfs.henshin.tgg.TNode; import de.tub.tfs.henshin.tgg.TggFactory; import de.tub.tfs.henshin.tgg.TripleGraph; import de.tub.tfs.henshin.tggeditor.editparts.tree.TransformationSystemTreeEditPart; import de.tub.tfs.henshin.tggeditor.editparts.tree.graphical.GraphFolderTreeEditPart; import de.tub.tfs.henshin.tggeditor.editparts.tree.graphical.GraphTreeEditPart; import de.tub.tfs.henshin.tggeditor.util.GraphicalNodeUtil; public class ImportTargetInstanceModelAction extends SelectionAction { /** The Constant ID. */ public static final String ID = "henshineditor.actions.ImportTargetInstanceModelAction"; /** the shell of the dialog */ protected Shell shell; /** the transformation system, in which the instance shall be included */ protected Module module; /** the URIs for the files to import */ protected List<URI> urIs; /** the mapping between henshinGraph and instanceGraph */ protected HashMap<EObject,TNode> instanceGraphToHenshinGraphMapping = new HashMap<EObject, TNode>();; /** the current object of the instance graph */ protected EObject eObj; /** the current node of the henshin graph */ protected TNode node; /** the graph to be created in henshin*/ protected TripleGraph tripleGraph; public ImportTargetInstanceModelAction(IWorkbenchPart part) { super(part); setId(ID); setText("Import a target instance model."); // setImageDescriptor(IconUtil.getDescriptor("attr16.png")); setToolTipText("Import a target instance model."); } @Override protected boolean calculateEnabled() { List<?> selectedObjects = getSelectedObjects(); if (selectedObjects.size() != 1) { return false; } Object selectedObject = selectedObjects.get(0); if ((selectedObject instanceof EditPart)) { EditPart editpart = (EditPart) selectedObject; if (editpart instanceof GraphTreeEditPart) { tripleGraph = (TripleGraph) editpart.getModel(); if (editpart.getParent() instanceof GraphFolderTreeEditPart){ GraphFolderTreeEditPart gftep = (GraphFolderTreeEditPart) editpart.getParent(); TransformationSystemTreeEditPart host = (TransformationSystemTreeEditPart) gftep.getParent(); module = (Module) host.getModel(); return true; }else{ return false; } } // if (editpart instanceof GraphElementsTreeEditPart) { // graph = ((GraphElementsContainterEObject) editpart.getModel()).getModel(); // return true; // } } return false; } @SuppressWarnings("unchecked") @Override public void run() { instanceGraphToHenshinGraphMapping = new HashMap<EObject, TNode>(); boolean dialogSuccess = openImportDialog(); if (!dialogSuccess) return; long startTime = System.currentTimeMillis(); System.out.println("DEBUG: start instance import "); for (URI uri : urIs){ ResourceImpl r = (ResourceImpl) module.eResource() .getResourceSet().createResource(uri); r.unload(); try { r.load(null); } catch (IOException e) { //e.printStackTrace(); try { r.unload(); } catch (Exception ex){ } HashMap<String,Object> options = new HashMap<String,Object>(); options.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE); options.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE); options.put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); options.put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE); options.put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE); options.put(XMLResource.OPTION_USE_LEXICAL_HANDLER, Boolean.TRUE); try { r.load(options); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } createAndAddGraph(r,uri); System.out .println("DEBUG: graph added " + ((System.currentTimeMillis() - startTime) / 1000d) + " s"); } shell.dispose(); super.run(); } public void createAndAddGraph(ResourceImpl r,URI uri) { { List<?> selectedObjs = getSelectedObjects(); if (selectedObjs.size() != 1) { System.out.println("more than one object selected"); return; } if (r.getContents().isEmpty()) return; Iterator<EObject> itr = r.getAllContents(); //tripleGraph.setName(uri.segment(uri.segmentCount() - 1)); HashSet<EObject> allNodes = new HashSet<EObject>(); // import all nodes without features first (otherwise, references // could be dangling) HashSet<EObject> missingNodes = new HashSet<EObject>(); long amountNodes = 0; while (itr.hasNext()) { eObj = itr.next(); createNode(); amountNodes++; allNodes.add(eObj); if (eObj instanceof DynamicEObjectImpl){ for (EReference ref : eObj.eClass().getEAllContainments()) { if (ref.isMany()){ missingNodes.addAll((Collection<? extends EObject>) eObj.eGet(ref)); } else { missingNodes.add((EObject) eObj.eGet(ref)); } } } } Iterator<EObject> iterator = missingNodes.iterator(); while (iterator.hasNext()) { eObj = iterator.next(); iterator.remove(); if (eObj == null) continue; // If this node was already created, then don't create duplicative nodes. // This case occurs for input files in xmi format. if (allNodes.contains(eObj)) continue; createNode(); amountNodes++; allNodes.add(eObj); if (eObj instanceof DynamicEObjectImpl){ for (EReference ref : eObj.eClass().getEAllContainments()) { if (ref.isMany()){ missingNodes.addAll((Collection<? extends EObject>) eObj.eGet(ref)); iterator = missingNodes.iterator(); } else { missingNodes.add((EObject) eObj.eGet(ref)); iterator = missingNodes.iterator(); } } } } TGG tgg = GraphicalNodeUtil.getLayoutSystem(module); Iterator<ImportedPackage> importedPkgsItr = tgg.getImportedPkgs().iterator(); ImportedPackage impPkg; List<EObject> typesWithLoadDefaultValues = new Vector<EObject>(); while(importedPkgsItr.hasNext()){ impPkg = importedPkgsItr.next(); if(impPkg.isLoadWithDefaultValues()) typesWithLoadDefaultValues.addAll(impPkg.getPackage().eContents()); } itr = allNodes.iterator(); boolean loadAttributesWithDefaultValues; while (itr.hasNext()) { eObj = itr.next(); // get node that was created in the loop before node = instanceGraphToHenshinGraphMapping.get(eObj); loadAttributesWithDefaultValues = typesWithLoadDefaultValues.contains(node.getType()); // iterate over all features of that node for (EStructuralFeature feat : eObj.eClass() .getEAllStructuralFeatures()) { // import references if (feat instanceof EReference) { createEdge((EReference) feat); } // import attribute values else if (feat instanceof EAttribute) { createAttribute((EAttribute) feat, loadAttributesWithDefaultValues); } } } //module.getInstances().add(tripleGraph); } } /** * @return */ protected boolean openImportDialog() { shell = new Shell(); ResourceDialog dialog = new ResourceDialog(shell, "Please select the instance model you want to load.", SWT.OPEN + SWT.MULTI); int p = dialog.open(); if (p == 1 || p == SWT.CANCEL){ 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 false; } urIs = dialog.getURIs(); 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 false; } return true; } /** * @param feat */ protected void createAttribute(EAttribute feat, boolean loadAttributesWithDefaultValues) { Attribute attr; if (feat.getEType().getName().equals("EFeatureMapEntry")) // do nothing, because this map summarizes all features return; if (!eObj.eIsSet(feat) && (!loadAttributesWithDefaultValues || feat.getDefaultValue() == null)) // no value available, thus do not create an attribute return; // value is available // process attribute attr = TggFactory.eINSTANCE.createTAttribute(); attr.setNode(node); attr.setType((EAttribute) feat); if (attr.getType().getName().contains("name") && !(eObj instanceof NamedElement)) { node.setName(attr.getValue()); } if (feat.isMany()) { if (eObj.eIsSet(feat)) { // value of feature is set String valueString = eObj.eGet(feat).toString(); // remove the square brackets of the array // TODO: remove only if the list contains one element if (valueString.length() > 1) { valueString = valueString.substring(1, valueString.length() - 1); } attr.setValue(valueString); } else { if (feat.getDefaultValue() != null) { attr.setValue(feat.getDefaultValue().toString()); } } } else { // feature is single valued if (eObj.eIsSet(feat)) { attr.setValue(eObj.eGet(feat).toString()); } else { if (feat.getDefaultValue() != null) { attr.setValue(feat.getDefaultValue().toString()); } } } } /** * @param feat */ protected void createEdge(EReference feat) { if (eObj.eIsSet(feat)) { if (feat.isMany()) { List<EObject> list = (List<EObject>) eObj.eGet(feat); for (EObject ref : list) { Edge edge = TggFactory.eINSTANCE.createTEdge(); edge.setSource(node); if (instanceGraphToHenshinGraphMapping.containsKey(ref)) { edge.setTarget(instanceGraphToHenshinGraphMapping .get(ref)); } else { edge.setTarget(createTargetNode(ref, tripleGraph)); } edge.setType((EReference) feat); tripleGraph.getEdges().add(edge); } } else { EObject ref = (EObject) eObj.eGet(feat); Edge edge = TggFactory.eINSTANCE.createTEdge(); edge.setSource(node); if (instanceGraphToHenshinGraphMapping.containsKey(ref)) { edge.setTarget(instanceGraphToHenshinGraphMapping.get(ref)); } else { edge.setTarget(createTargetNode(ref, tripleGraph)); } edge.setType((EReference) feat); tripleGraph.getEdges().add(edge); } } } /** */ protected void createNode() { //henshinGraph.addEObject(eObj); TNode node = TggFactory.eINSTANCE.createTNode(); node.setType(eObj.eClass()); int tmp_x = tripleGraph.getDividerCT_X(); node.setX(tmp_x+500); node.setY(0); /*if (eObj instanceof NamedElement){ node.setName(((NamedElement)eObj).getName()); } else { node.setName("_DEBUG:_" + eObj.toString() + "_"); }*/ node.setName(""); instanceGraphToHenshinGraphMapping.put(eObj, node); tripleGraph.getNodes().add(node); } protected HashMap<Graph, HashMap<EObject,TNode>> graphToNodeMap = new HashMap<Graph, HashMap<EObject,TNode>>(); protected TNode createTargetNode(EObject ref,Graph graph) { HashMap<EObject, TNode> map = graphToNodeMap.get(graph); if (map == null) graphToNodeMap.put(graph, map = new HashMap<EObject, TNode>()); TNode node = map.get(ref); if (node == null){ node = TggFactory.eINSTANCE.createTNode(); node.setType(ref.eClass()); node.setName(ref.toString()); graph.getNodes().add(node); map.put(ref, node); } return node; } public void setModule(Module transSys) { this.module = transSys; } }