Merge "Allow display of plantUML graph and matrix from selecting graphical elements" into develop
diff --git a/org.eclipse.capra.testsuite/src/org/eclipse/capra/testsuite/TestGraphicalVisualization.java b/org.eclipse.capra.testsuite/src/org/eclipse/capra/testsuite/TestGraphicalVisualization.java
new file mode 100644
index 0000000..d08569a
--- /dev/null
+++ b/org.eclipse.capra.testsuite/src/org/eclipse/capra/testsuite/TestGraphicalVisualization.java
@@ -0,0 +1,133 @@
+package org.eclipse.capra.testsuite;
+
+import static org.eclipse.capra.testsuite.TestHelper.clearWorkspace;
+import static org.eclipse.capra.testsuite.TestHelper.createEClassInEPackage;
+import static org.eclipse.capra.testsuite.TestHelper.createEcoreModel;
+import static org.eclipse.capra.testsuite.TestHelper.createSimpleProject;
+import static org.eclipse.capra.testsuite.TestHelper.createTraceForCurrentSelectionOfType;
+import static org.eclipse.capra.testsuite.TestHelper.getProject;
+import static org.eclipse.capra.testsuite.TestHelper.load;
+import static org.eclipse.capra.testsuite.TestHelper.projectExists;
+import static org.eclipse.capra.testsuite.TestHelper.resetSelectionView;
+import static org.eclipse.capra.testsuite.TestHelper.save;
+import static org.eclipse.capra.testsuite.TestHelper.thereIsATraceBetween;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.capra.GenericTraceMetaModel.GenericTraceMetaModelPackage;
+import org.eclipse.capra.core.adapters.TracePersistenceAdapter;
+import org.eclipse.capra.core.helpers.ExtensionPointHelper;
+import org.eclipse.capra.ui.plantuml.DiagramTextProviderHandler;
+import org.eclipse.capra.ui.plantuml.DisplayTracesHandler;
+import org.eclipse.capra.ui.views.SelectionView;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestGraphicalVisualization {
+
+	private final static String EXPECTED_TEXT_FOR_DIRECT_CONNECTIONS = "@startuml\n"
+			+ "object \"A : EClass\" as o0 #pink\n" + "object \"B : EClass\" as o1\n" + "o0--o1:RelatedTo\n"
+			+ "@enduml\n";
+
+	private final static String EXPECTED_TEXT_FOR_TRANSITIVE_CONNECTIONS = "@startuml\n"
+			+ "object \"A : EClass\" as o0 #pink\n" + "object \"B : EClass\" as o1\n" + "object \"C : EClass\" as o2\n"
+			+ "o0--o1:RelatedTo\n" + "o1--o2:RelatedTo\n" + "@enduml\n";
+
+	@Before
+	public void init() throws CoreException {
+		clearWorkspace();
+		resetSelectionView();
+	}
+
+	@Test
+	public void testPlantUMLGraphView() throws CoreException, IOException, InterruptedException {
+
+		// Create a project
+		createSimpleProject("TestProject");
+		assertTrue(projectExists("TestProject"));
+
+		// Create two models each with two classes and persist them
+		IProject testProject = getProject("TestProject");
+		EPackage a = TestHelper.createEcoreModel("modelA");
+		createEClassInEPackage(a, "A");
+		save(testProject, a);
+
+		EPackage b = createEcoreModel("modelB");
+		createEClassInEPackage(b, "B");
+		createEClassInEPackage(b, "C");
+		save(testProject, b);
+
+		// Load them and choose the four classes
+		ResourceSet rs = new ResourceSetImpl();
+
+		EPackage _a = load(testProject, "modelA.ecore", rs);
+		assertEquals(_a.getName(), "modelA");
+		EClass _A = (EClass) _a.getEClassifier("A");
+
+		EPackage _b = load(testProject, "modelB.ecore", rs);
+		assertEquals(_b.getName(), "modelB");
+		EClass _B = (EClass) _b.getEClassifier("B");
+		EClass _C = (EClass) _b.getEClassifier("C");
+
+		// Add A and B to the selection view
+		assertTrue(SelectionView.getOpenedView().getSelection().isEmpty());
+		SelectionView.getOpenedView().dropToSelection(_A);
+		SelectionView.getOpenedView().dropToSelection(_B);
+		assertFalse(SelectionView.getOpenedView().getSelection().isEmpty());
+
+		// Create a trace via the selection view
+		assertFalse(thereIsATraceBetween(_A, _B));
+		createTraceForCurrentSelectionOfType(GenericTraceMetaModelPackage.eINSTANCE.getRelatedTo());
+		assertTrue(thereIsATraceBetween(_A, _B));
+
+		// Clear selection view
+		SelectionView.getOpenedView().clearSelection();
+
+		// Add B and C to selection view
+		SelectionView.getOpenedView().dropToSelection(_B);
+		SelectionView.getOpenedView().dropToSelection(_C);
+
+		// Create a traceLink between B and C
+		assertFalse(thereIsATraceBetween(_B, _C));
+		createTraceForCurrentSelectionOfType(GenericTraceMetaModelPackage.eINSTANCE.getRelatedTo());
+		// Remove trace model from resource set to make sure the trace model is
+		// re-loaded to capture the second trace link
+		removeTraceModel(rs);
+		assertTrue(thereIsATraceBetween(_B, _C));
+
+		// create a selection with class A
+		List<Object> selection = new ArrayList<>();
+		selection.add(_A);
+
+		// Test directly connected Elements
+		DisplayTracesHandler.setTraceViewTransitive(false);
+		DiagramTextProviderHandler provider = new DiagramTextProviderHandler();
+		String DirectlyConnectedElements = provider.getDiagramText(selection);
+		assertTrue(DirectlyConnectedElements.equals(EXPECTED_TEXT_FOR_DIRECT_CONNECTIONS));
+
+		// Test transitively connected Elements
+		DisplayTracesHandler.setTraceViewTransitive(true);
+		String transitivelysConnectedElements = provider.getDiagramText(selection);
+		assertTrue(transitivelysConnectedElements.equals(EXPECTED_TEXT_FOR_TRANSITIVE_CONNECTIONS));
+
+	}
+
+	private void removeTraceModel(ResourceSet rs) {
+		TracePersistenceAdapter persistenceAdapter = ExtensionPointHelper.getTracePersistenceAdapter().get();
+		EObject tm = persistenceAdapter.getTraceModel(rs);
+		rs.getResources().remove(tm.eResource());
+	}
+
+}
diff --git a/org.eclipse.capra.testsuite/src/org/eclipse/capra/testsuite/TestTraceabiltyMatrix.java b/org.eclipse.capra.testsuite/src/org/eclipse/capra/testsuite/TestTraceabiltyMatrix.java
index 3c022db..68fdac8 100644
--- a/org.eclipse.capra.testsuite/src/org/eclipse/capra/testsuite/TestTraceabiltyMatrix.java
+++ b/org.eclipse.capra.testsuite/src/org/eclipse/capra/testsuite/TestTraceabiltyMatrix.java
@@ -23,6 +23,7 @@
 import org.eclipse.capra.core.adapters.TracePersistenceAdapter;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.capra.ui.plantuml.DiagramTextProviderHandler;
+import org.eclipse.capra.ui.plantuml.DisplayTracesHandler;
 import org.eclipse.capra.ui.views.SelectionView;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.CoreException;
@@ -36,9 +37,12 @@
 
 public class TestTraceabiltyMatrix {
 
-	private final static String EXPECTED_TEXT_FOR_SELECTED_PACKAGES = "@startuml\n" + "salt\n" + "{#\n"
+	private final static String EXPECTED_TEXT_FOR_SELECTED_PACKAGES_DIRECT = "@startuml\n" + "salt\n" + "{#\n"
+			+ ".|modelB : EPackage\n" + "modelA : EPackage |X\n" + "}\n" + "\n" + "@enduml\n";
+
+	private final static String EXPECTED_TEXT_FOR_SELECTED_PACKAGES_TRANSITIVE = "@startuml\n" + "salt\n" + "{#\n"
 			+ ".|B : EClass|BB : EClass|modelB : EPackage\n" + "A : EClass |X|.|.\n" + "AA : EClass |.|X|.\n"
-			+ "modelA : EPackage |.|.|.\n" + "}\n" + "\n" + "@enduml\n";
+			+ "modelA : EPackage |.|.|X\n" + "}\n" + "\n" + "@enduml\n";
 
 	private final static String EXPECTED_TEXT_FOR_SELECTED_CLASSES = "@startuml\n" + "salt\n" + "{#\n"
 			+ ".|A : EClass|B : EClass|AA : EClass|BB : EClass\n" + "A : EClass |.|X|.|.\n" + "B : EClass |X|.|.|.\n"
@@ -111,16 +115,42 @@
 		removeTraceModel(rs);
 		assertTrue(thereIsATraceBetween(_AA, _BB));
 
+		// create trace link between package A and B
+		// clear selection
+		SelectionView.getOpenedView().clearSelection();
+		assertTrue(SelectionView.getOpenedView().getSelection().isEmpty());
+
+		// Add Package A and B to selection view
+		SelectionView.getOpenedView().dropToSelection(_a);
+		SelectionView.getOpenedView().dropToSelection(_b);
+		assertFalse(SelectionView.getOpenedView().getSelection().isEmpty());
+
+		// Create a trace between Package A and B
+		assertFalse(thereIsATraceBetween(_a, _b));
+		createTraceForCurrentSelectionOfType(GenericTraceMetaModelPackage.eINSTANCE.getRelatedTo());
+
+		// Remove trace model from resource set to make sure the trace model is
+		// re-loaded to capture the third trace link
+		removeTraceModel(rs);
+		assertTrue(thereIsATraceBetween(_a, _b));
+
 		// create a selection with Package A and B
 		List<Object> selectedPackages = new ArrayList<>();
 		selectedPackages.add(_a);
 		selectedPackages.add(_b);
 
+		// Test directly connected Elements
+		DisplayTracesHandler.setTraceViewTransitive(false);
 		DiagramTextProviderHandler provider = new DiagramTextProviderHandler();
-		String plantUMLTextForSelectedPackages = provider.getDiagramText(selectedPackages);
+		String plantUMLTextForSelectedPackages_Direct = provider.getDiagramText(selectedPackages);
+		assertTrue(plantUMLTextForSelectedPackages_Direct.equals(EXPECTED_TEXT_FOR_SELECTED_PACKAGES_DIRECT));
 
-		assertTrue(plantUMLTextForSelectedPackages.equals(EXPECTED_TEXT_FOR_SELECTED_PACKAGES));
+		// Test transitively connected Elements
+		DisplayTracesHandler.setTraceViewTransitive(true);
+		String plantUMLTextForSelectedPackages_Transitive = provider.getDiagramText(selectedPackages);
+		assertTrue(plantUMLTextForSelectedPackages_Transitive.equals(EXPECTED_TEXT_FOR_SELECTED_PACKAGES_TRANSITIVE));
 
+		// test multiple classes selected
 		List<Object> selectedClasses = new ArrayList<>();
 		selectedClasses.add(_A);
 		selectedClasses.add(_B);
@@ -136,5 +166,4 @@
 		EObject tm = persistenceAdapter.getTraceModel(rs);
 		rs.getResources().remove(tm.eResource());
 	}
-
 }
diff --git a/org.eclipse.capra.ui.plantuml/META-INF/MANIFEST.MF b/org.eclipse.capra.ui.plantuml/META-INF/MANIFEST.MF
index 1e014c3..e1247df 100644
--- a/org.eclipse.capra.ui.plantuml/META-INF/MANIFEST.MF
+++ b/org.eclipse.capra.ui.plantuml/META-INF/MANIFEST.MF
@@ -7,16 +7,14 @@
  org.eclipse.jface,
  org.eclipse.capra.core,
  org.eclipse.emf.ecore.editor,
- com.google.guava,
- org.eclipse.xtext.xbase.lib,
- org.eclipse.xtend.lib,
- org.eclipse.xtend.lib.macro,
  net.sourceforge.plantuml.eclipse,
  org.eclipse.ui,
  org.eclipse.core.resources,
  org.eclipse.core.runtime;bundle-version="3.10.0",
  org.eclipse.capra.ui;bundle-version="0.7.0",
- org.eclipse.capra.generic.tracemodels
+ org.eclipse.capra.generic.tracemodels,
+ org.eclipse.xtext.xbase.lib;bundle-version="2.10.0",
+ org.eclipse.xtend.lib;bundle-version="2.10.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Export-Package: org.eclipse.capra.ui.plantuml
 Bundle-Vendor: Capra Development Team
diff --git a/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/DiagramTextProviderHandler.java b/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/DiagramTextProviderHandler.java
index be4477f..8ef398b 100644
--- a/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/DiagramTextProviderHandler.java
+++ b/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/DiagramTextProviderHandler.java
@@ -11,12 +11,14 @@
 package org.eclipse.capra.ui.plantuml;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.stream.Collectors;
 
 import org.eclipse.capra.core.adapters.Connection;
 import org.eclipse.capra.core.adapters.TraceMetaModelAdapter;
 import org.eclipse.capra.core.adapters.TracePersistenceAdapter;
+import org.eclipse.capra.core.handlers.ArtifactHandler;
 import org.eclipse.capra.core.helpers.EMFHelper;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.capra.ui.helpers.TraceCreationHelper;
@@ -35,60 +37,87 @@
  * @author Anthony Anjorin, Salome Maro
  */
 public class DiagramTextProviderHandler implements DiagramTextProvider {
-	private TraceMetaModelAdapter metamodelAdapter;
-	private List<Connection> traces = new ArrayList<>();
+	private EObject artifactModel = null;
 
 	@Override
 	public String getDiagramText(IEditorPart editor, ISelection input) {
 		List<Object> selectedModels = TraceCreationHelper
 				.extractSelectedElements(editor.getSite().getSelectionProvider().getSelection());
-
 		return getDiagramText(selectedModels);
 	}
 
-	/**
-	 * Creates the {@code String} representation PlantUML uses to render the
-	 * graphics. Based on the selected models, the relevant trace links are
-	 * extracted and a decision is made whether a matrix of a tree view has to
-	 * be displayed.
-	 * 
-	 * @param selectedModels
-	 *            the models whose trace links should be displayed
-	 * @return a string representation of the visualisation that can be rendered
-	 *         by PlantUML
-	 */
 	public String getDiagramText(List<Object> selectedModels) {
 		List<EObject> firstModelElements = null;
 		List<EObject> secondModelElements = null;
+		EObject selectedObject = null;
+		ResourceSet resourceSet = new ResourceSetImpl();
+		EObject traceModel = null;
+		List<Connection> traces = new ArrayList<>();
 
 		TracePersistenceAdapter persistenceAdapter = ExtensionPointHelper.getTracePersistenceAdapter().get();
-		metamodelAdapter = ExtensionPointHelper.getTraceMetamodelAdapter().get();
+		TraceMetaModelAdapter metamodelAdapter = ExtensionPointHelper.getTraceMetamodelAdapter().get();
 
-		ResourceSet resourceSet = new ResourceSetImpl();
-		if (selectedModels.size() > 0 && selectedModels.get(0) instanceof EObject)
-			resourceSet = ((EObject) selectedModels.get(0)).eResource().getResourceSet();
+		artifactModel = persistenceAdapter.getArtifactWrappers(resourceSet);
 
-		EObject traceModel = persistenceAdapter.getTraceModel(resourceSet);
+		Collection<ArtifactHandler> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
+		if (selectedModels.size() > 0) {
+			// check if there is a hander for the selected elements and if yes
+			// get its EObject representation
+			List<ArtifactHandler> availableHandlers = artifactHandlers.stream()
+					.filter(handler -> handler.canHandleSelection(selectedModels.get(0))).collect(Collectors.toList());
+			if (availableHandlers.size() >= 1) {
+				selectedObject = availableHandlers.get(0).getEObjectForSelection(selectedModels.get(0), artifactModel);
 
-		if (selectedModels.size() == 1 && selectedModels.get(0) instanceof EObject) {
-			EObject selectedEObject = (EObject) selectedModels.get(0);
-			if (DisplayTracesHandler.isTraceViewTransitive()) {
-				traces = metamodelAdapter.getTransitivelyConnectedElements(selectedEObject, traceModel);
-			} else {
-				traces = metamodelAdapter.getConnectedElements(selectedEObject, traceModel);
+				if (selectedObject != null) {
+					resourceSet = selectedObject.eResource().getResourceSet();
+					traceModel = persistenceAdapter.getTraceModel(resourceSet);
+
+					if (selectedModels.size() == 1) {
+						if (DisplayTracesHandler.isTraceViewTransitive()) {
+							traces = metamodelAdapter.getTransitivelyConnectedElements(selectedObject, traceModel);
+						} else {
+							traces = metamodelAdapter.getConnectedElements(selectedObject, traceModel);
+						}
+
+						return VisualizationHelper.createNeighboursView(traces, selectedObject);
+					} else if (selectedModels.size() == 2) {
+						if (DisplayTracesHandler.isTraceViewTransitive()) {
+							firstModelElements = EMFHelper.linearize(availableHandlers.get(0)
+									.getEObjectForSelection(selectedModels.get(0), artifactModel));
+							secondModelElements = EMFHelper.linearize(availableHandlers.get(0)
+									.getEObjectForSelection(selectedModels.get(1), artifactModel));
+						} else {
+							List<EObject> firstObject = new ArrayList<>();
+							firstObject.add(availableHandlers.get(0).getEObjectForSelection(selectedModels.get(0),
+									artifactModel));
+							List<EObject> secondObject = new ArrayList<>();
+							secondObject.add(availableHandlers.get(0).getEObjectForSelection(selectedModels.get(1),
+									artifactModel));
+							firstModelElements = firstObject;
+							secondModelElements = secondObject;
+						}
+					} else if (selectedModels.size() > 2) {
+						if (DisplayTracesHandler.isTraceViewTransitive()) {
+							firstModelElements = selectedModels.stream()
+									.flatMap(r -> EMFHelper
+											.linearize(
+													availableHandlers.get(0).getEObjectForSelection(r, artifactModel))
+											.stream())
+									.collect(Collectors.toList());
+							secondModelElements = firstModelElements;
+						} else {
+							List<EObject> Objects = new ArrayList<>();
+							selectedModels.stream().forEach(o -> {
+								Objects.add(availableHandlers.get(0).getEObjectForSelection(o, artifactModel));
+
+							});
+							firstModelElements = Objects;
+							secondModelElements = firstModelElements;
+						}
+					}
+				}
 			}
-
-			return VisualizationHelper.createNeighboursView(traces, selectedEObject);
-		} else if (selectedModels.size() == 2) {
-			firstModelElements = EMFHelper.linearize(selectedModels.get(0));
-			secondModelElements = EMFHelper.linearize(selectedModels.get(1));
-		} else {
-			firstModelElements = selectedModels.stream().flatMap(r -> EMFHelper.linearize(r).stream())
-					.collect(Collectors.toList());
-
-			secondModelElements = firstModelElements;
 		}
-
 		String umlString = VisualizationHelper.createMatrix(traceModel, firstModelElements, secondModelElements);
 
 		return umlString;