Added Zest View

Change-Id: Iac90708581ba7431391582b24a03e217e6ff88ac
diff --git a/org.eclipse.capra.feature/feature.xml b/org.eclipse.capra.feature/feature.xml
index 42be4a9..d8fca1a 100644
--- a/org.eclipse.capra.feature/feature.xml
+++ b/org.eclipse.capra.feature/feature.xml
@@ -146,4 +146,11 @@
          version="0.0.0"
          unpack="false"/>
 
+   <plugin
+         id="org.eclipse.capra.ui.zest"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
 </feature>
diff --git a/org.eclipse.capra.releng.target/org.eclipse.capra.releng.target.target b/org.eclipse.capra.releng.target/org.eclipse.capra.releng.target.target
index fb9cdc8..e104344 100644
--- a/org.eclipse.capra.releng.target/org.eclipse.capra.releng.target.target
+++ b/org.eclipse.capra.releng.target/org.eclipse.capra.releng.target.target
@@ -44,5 +44,19 @@
 <unit id="org.eclipse.rmf.reqif10.pror.sdk.feature.feature.group" version="0.13.0.201509161042"/>
 <repository location="http://download.eclipse.org/rmf/updates/releases"/>
 </location>
+<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.gef4.common.sdk.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.gef4.geometry.sdk.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.gef4.fx.sdk.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.gef4.mvc.sdk.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.gef4.mvc.examples.source.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.gef4.layout.sdk.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.gef4.graph.sdk.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.gef4.zest.sdk.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.gef4.zest.examples.source.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.gef4.dot.sdk.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.gef4.cloudio.sdk.feature.group" version="0.0.0"/>
+<repository location="http://download.eclipse.org/tools/gef/gef4/updates/releases"/>
+</location>
 </locations>
 </target>
diff --git a/org.eclipse.capra.ui.zest/.classpath b/org.eclipse.capra.ui.zest/.classpath
new file mode 100644
index 0000000..16d067f
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.capra.ui.zest/.gitignore b/org.eclipse.capra.ui.zest/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/org.eclipse.capra.ui.zest/.project b/org.eclipse.capra.ui.zest/.project
new file mode 100644
index 0000000..9a086fa
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.capra.ui.zest</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.capra.ui.zest/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.capra.ui.zest/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..0c68a61
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/org.eclipse.capra.ui.zest/META-INF/MANIFEST.MF b/org.eclipse.capra.ui.zest/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..c6207fd
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/META-INF/MANIFEST.MF
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Zest
+Bundle-SymbolicName: org.eclipse.capra.ui.zest;singleton:=true
+Bundle-Version: 0.7.0.qualifier
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.ui,
+ org.eclipse.capra.core;bundle-version="0.7.0",
+ org.eclipse.capra.generic.tracemodels,
+ org.eclipse.gef4.graph;bundle-version="1.1.0",
+ org.eclipse.gef4.fx;bundle-version="1.0.1",
+ com.google.inject;bundle-version="3.0.0",
+ org.eclipse.gef4.zest.fx.jface;bundle-version="1.0.1",
+ org.eclipse.gef4.zest.fx.ui;bundle-version="1.0.1",
+ org.eclipse.gef4.zest.fx;bundle-version="1.1.0",
+ org.eclipse.zest.layouts;bundle-version="1.1.300",
+ org.eclipse.fx.javafx;bundle-version="2.2.0",
+ org.eclipse.capra.ui,
+ org.eclipse.gef4.layout;bundle-version="1.0.1"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/org.eclipse.capra.ui.zest/build.properties b/org.eclipse.capra.ui.zest/build.properties
new file mode 100644
index 0000000..0d3d3a7
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+               META-INF/,\
+               .,\
+               icons/
diff --git a/org.eclipse.capra.ui.zest/icons/capra.png b/org.eclipse.capra.ui.zest/icons/capra.png
new file mode 100644
index 0000000..4e60434
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/icons/capra.png
Binary files differ
diff --git a/org.eclipse.capra.ui.zest/plugin.xml b/org.eclipse.capra.ui.zest/plugin.xml
new file mode 100644
index 0000000..f54b4ef
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/plugin.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<!--
+    Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs 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:
+         Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ -->
+<plugin>
+
+   <extension
+         point="org.eclipse.ui.views">
+      <view
+            category="org.eclipse.capra.generic.views"
+            class="org.eclipse.capra.ui.zest.ZestView"
+            icon="icons/capra.png"
+            id="org.eclipse.capra.ui.zest.zestView"
+            name="Traceability View"
+            restorable="true">
+      </view>
+   </extension>
+
+</plugin>
diff --git a/org.eclipse.capra.ui.zest/pom.xml b/org.eclipse.capra.ui.zest/pom.xml
new file mode 100644
index 0000000..fa7cf56
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/pom.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs 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:
+         Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<relativePath>../pom.xml</relativePath>
+		<groupId>org.eclipse.capra</groupId>
+		<artifactId>parent</artifactId>
+		<version>0.7.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>org.eclipse.capra.ui.zest</artifactId>
+	<packaging>eclipse-plugin</packaging>
+
+</project>
diff --git a/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/ToggleTransitivityHandler.java b/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/ToggleTransitivityHandler.java
new file mode 100644
index 0000000..d500c61
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/ToggleTransitivityHandler.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs 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:
+ *      Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.capra.ui.zest;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+
+/**
+ * 
+ * This class checks if the user has clicked on Toggle transitivity and changes
+ * the input of the Zest view accordingly. Given a selected element, the view
+ * can switch between showing only directly connected elements or all connected
+ * elements (transitive view).
+ *
+ */
+public class ToggleTransitivityHandler extends AbstractHandler {
+
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		if (isTraceViewTransitive())
+			setTraceViewTransitive(false);
+		else
+			setTraceViewTransitive(true);
+
+		return null;
+	}
+
+	/**
+	 * Checks whether the trace view is set to show transitive traces.
+	 * 
+	 * @return {@code true} if transitive traces are enabled, {@code false}
+	 *         otherwise
+	 */
+	public static boolean isTraceViewTransitive() {
+		Preferences transitivity = getPreference();
+
+		return transitivity.get("option", "direct").equals("transitive");
+	}
+
+	/**
+	 * Sets whether the trace view is set to show transitive traces.
+	 * 
+	 * @param value
+	 *            indicates whether transitive traces should be shown
+	 */
+	public static void setTraceViewTransitive(boolean value) {
+		Preferences transitivity = getPreference();
+
+		transitivity.put("option", value ? "transitive" : "direct");
+
+		try {
+			// forces the application to save the preferences
+			transitivity.flush();
+		} catch (BackingStoreException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private static Preferences getPreference() {
+		Preferences preferences = InstanceScope.INSTANCE.getNode("org.eclipse.capra.ui.zest.toggleTransitivity");
+		Preferences transitivity = preferences.node("transitivity");
+		return transitivity;
+	}
+
+}
diff --git a/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/TraceNodeContentProvider.java b/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/TraceNodeContentProvider.java
new file mode 100644
index 0000000..43a3e47
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/TraceNodeContentProvider.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs 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:
+ *      Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.capra.ui.zest;
+
+import java.util.ArrayList;
+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.emf.ecore.EObject;
+import org.eclipse.gef4.zest.fx.jface.IGraphContentProvider;
+
+/**
+ * 
+ * This class provides the content to be displayed on the Zest view in form of a
+ * graph. It gets the traceability links and forms a graph with the connected
+ * elements as nodes and the traceability links as edges.
+ *
+ */
+public class TraceNodeContentProvider implements IGraphContentProvider {
+
+	private TraceMetaModelAdapter metaModelAdapter;
+	private EObject traceModel = null;
+	private List<Connection> connections = new ArrayList<>();
+	private List<Object> currentSelection = null;
+
+	/**
+	 * This constructor gets the trace model, traceMetamodel adapter and the
+	 * list of selected objects by the user and sets them to the private
+	 * variables of the class
+	 * 
+	 * @param traceModel
+	 *            the current trace model
+	 * @param metaModelAdapter
+	 *            the metamodel adapter
+	 * @param element
+	 *            the current selection
+	 */
+	public TraceNodeContentProvider(EObject traceModel, TraceMetaModelAdapter metaModelAdapter, List<Object> element) {
+		this.traceModel = traceModel;
+		this.currentSelection = element;
+		this.metaModelAdapter = metaModelAdapter;
+
+	}
+
+	@Override
+	public Object[] getAdjacentNodes(Object node) {
+		List<EObject> nodes = new ArrayList<>();
+
+		if (node instanceof EObject) {
+			EObject object = (EObject) node;
+			connections = metaModelAdapter.getConnectedElements(object, traceModel);
+			for (Connection c : connections) {
+				nodes.addAll(c.getTargets());
+			}
+		}
+		return nodes.toArray();
+	}
+
+	@Override
+	public Object[] getNestedGraphNodes(Object node) {
+		return null;
+	}
+
+	@Override
+	public Object[] getNodes() {
+		List<EObject> nodes = new ArrayList<>();
+		if (currentSelection.get(0) instanceof EObject) {
+			EObject object = (EObject) currentSelection.get(0);
+			connections = metaModelAdapter.getTransitivelyConnectedElements(object, traceModel);
+			for (Connection c : connections) {
+				nodes.add(c.getOrigin());
+				nodes.addAll(c.getTargets());
+			}
+		}
+		// return only distinct values as nodes of the graph
+		return nodes.stream().distinct().collect(Collectors.toList()).toArray();
+
+	}
+
+	@Override
+	public boolean hasNestedGraph(Object node) {
+		return false;
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/TraceNodeLabelProvider.java b/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/TraceNodeLabelProvider.java
new file mode 100644
index 0000000..1b9a1e3
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/TraceNodeLabelProvider.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs 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:
+ *      Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.capra.ui.zest;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.helpers.ExtensionPointHelper;
+import org.eclipse.jface.viewers.LabelProvider;
+
+/**
+ * 
+ * This class provides labels for the nodes and edges for the graph to be
+ * displayed in the zest view.
+ *
+ */
+public class TraceNodeLabelProvider extends LabelProvider {
+
+	@Override
+	public String getText(Object element) {
+
+		Collection<ArtifactHandler> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
+		List<ArtifactHandler> availableHandlers = artifactHandlers.stream()
+				.filter(handler -> handler.canHandleSelection(element)).collect(Collectors.toList());
+		if (availableHandlers.size() >= 1) {
+			return availableHandlers.get(0).getDisplayName(element);
+		} else
+			return element.toString();
+
+	}
+
+	// TODO Add labels for the edges
+
+}
\ No newline at end of file
diff --git a/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/ZestView.java b/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/ZestView.java
new file mode 100644
index 0000000..1d3c621
--- /dev/null
+++ b/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/ZestView.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs 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:
+ *      Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.capra.ui.zest;
+
+import java.util.List;
+
+import org.eclipse.capra.core.adapters.TraceMetaModelAdapter;
+import org.eclipse.capra.core.adapters.TracePersistenceAdapter;
+import org.eclipse.capra.core.helpers.ExtensionPointHelper;
+import org.eclipse.capra.ui.helpers.TraceCreationHelper;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.gef4.layout.ILayoutAlgorithm;
+import org.eclipse.gef4.layout.algorithms.TreeLayoutAlgorithm;
+import org.eclipse.gef4.zest.fx.jface.ZestContentViewer;
+import org.eclipse.gef4.zest.fx.jface.ZestFxJFaceModule;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.part.ViewPart;
+
+import com.google.inject.Module;
+
+/**
+ * This class creates the view to hold the content of the model displayed as a
+ * graph in the Zest view. The view is connected to the model using a content
+ * provider.
+ * <p>
+ * The view uses a label provider to define how model objects should be
+ * presented in the view. Each view can present the same model objects using
+ * different labels and icons, if needed. Alternatively, a single label provider
+ * can be shared between views in order to ensure that objects of the same type
+ * are presented in the same way everywhere.
+ * <p>
+ */
+public class ZestView extends ViewPart {
+
+	static ZestContentViewer viewer = null;
+	private ISelectionListener selectionListener;
+
+	@Override
+	public void createPartControl(Composite parent) {
+
+		TracePersistenceAdapter tracePersistenceAdapter;
+
+		tracePersistenceAdapter = ExtensionPointHelper.getTracePersistenceAdapter().get();
+
+		viewer = new ZestContentViewer((Module) new ZestFxJFaceModule());
+		viewer.createControl(parent, SWT.NONE);
+		viewer.setLabelProvider(new TraceNodeLabelProvider());
+		ILayoutAlgorithm layout = new TreeLayoutAlgorithm();
+		viewer.setLayoutAlgorithm(layout);
+
+		selectionListener = new ISelectionListener() {
+
+			@Override
+			public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+				EObject traceModel;
+				TraceMetaModelAdapter metaModelAdapter;
+				ResourceSet resourceSet;
+
+				List<Object> selectedModels = TraceCreationHelper.extractSelectedElements(selection);
+
+				if (selectedModels.size() >= 1 && selectedModels.get(0) instanceof EObject) {
+					EObject selectedEObject = (EObject) selectedModels.get(0);
+					resourceSet = selectedEObject.eResource().getResourceSet();
+					traceModel = tracePersistenceAdapter.getTraceModel(resourceSet);
+					metaModelAdapter = ExtensionPointHelper.getTraceMetamodelAdapter().get();
+					viewer.setContentProvider(
+							new TraceNodeContentProvider(traceModel, metaModelAdapter, selectedModels));
+					viewer.setInput(null);
+					viewer.refresh();
+
+				}
+				// TODO Implement what should be displayed when more than one
+				// element has been selected
+			}
+
+		};
+		getViewSite().getPage().addSelectionListener(selectionListener);
+
+	}
+
+	@Override
+	public void dispose() {
+		getSite().getPage().removeSelectionListener((ISelectionListener) selectionListener);
+		super.dispose();
+	}
+
+	@Override
+	public void setFocus() {
+		// TODO Auto-generated method stub
+
+	}
+}
diff --git a/pom.xml b/pom.xml
index e03b0c1..d0eb887 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,7 @@
 		<module>org.eclipse.capra.releng.p2</module>
 		<module>org.eclipse.capra.ui.cdt</module>
 		<module>org.eclipse.capra.ui.jdt</module>
+		<module>org.eclipse.capra.ui.zest</module>
 	</modules>
 
 	<properties>