Added rudimentary support for reverse link direction in PlantUML viewer

Transitive links and internal links are not supported yet, but it is
possible to see incoming links now.
Change-Id: I12ea25ae2a33c8ad6ae9e107990d4020bf5bcc62
diff --git a/bundles/org.eclipse.capra.ui.plantuml/OSGI-INF/l10n/bundle.properties b/bundles/org.eclipse.capra.ui.plantuml/OSGI-INF/l10n/bundle.properties
index accf529..cad6717 100644
--- a/bundles/org.eclipse.capra.ui.plantuml/OSGI-INF/l10n/bundle.properties
+++ b/bundles/org.eclipse.capra.ui.plantuml/OSGI-INF/l10n/bundle.properties
@@ -26,5 +26,6 @@
 command.label.depth = Set transitivity depth
 command.name.lock = Lock current diagram
 command.label.lock = Lock current diagram
+command.name.reverseLinkDirection = Reverse link direction
 Bundle-Vendor = Eclipse Capra
 Bundle-Name = Eclipse Capra Trace Visualisation Support (PlantUML)
diff --git a/bundles/org.eclipse.capra.ui.plantuml/plugin.xml b/bundles/org.eclipse.capra.ui.plantuml/plugin.xml
index 2835040..62ad9eb 100644
--- a/bundles/org.eclipse.capra.ui.plantuml/plugin.xml
+++ b/bundles/org.eclipse.capra.ui.plantuml/plugin.xml
@@ -78,6 +78,14 @@
                id="org.eclipse.ui.commands.toggleState">
          </state>
       </command>
+      <command
+            id="org.eclipse.capra.ui.plantuml.reverseLinkDirection"
+            name="%command.name.reverseLinkDirection">
+         <state
+               class="org.eclipse.jface.commands.ToggleState"
+               id="org.eclipse.ui.commands.toggleState">
+         </state>
+      </command>
    </extension>
    <extension
          point="org.eclipse.ui.handlers">
@@ -105,6 +113,10 @@
             class="org.eclipse.capra.ui.plantuml.handlers.ToggleLockDiagramHandler"
             commandId="org.eclipse.capra.ui.plantuml.lockDiagram">
       </handler>
+      <handler
+            class="org.eclipse.capra.ui.plantuml.handlers.ReverseLinkDirectionHandler"
+            commandId="org.eclipse.capra.ui.plantuml.reverseLinkDirection">
+      </handler>
    </extension>
 	<extension
          point="org.eclipse.ui.menus">
@@ -140,6 +152,11 @@
                label="%command.name.lock"
                style="toggle">
          </command>
+         <command
+               commandId="org.eclipse.capra.ui.plantuml.reverseLinkDirection"
+               label="%command.name.reverseLinkDirection"
+               style="toggle">
+         </command>
       </menuContribution>
    </extension>
    
diff --git a/bundles/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/CapraDiagramTextProvider.java b/bundles/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/CapraDiagramTextProvider.java
index 5c0f9c9..f6c9c10 100644
--- a/bundles/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/CapraDiagramTextProvider.java
+++ b/bundles/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/CapraDiagramTextProvider.java
@@ -19,8 +19,8 @@
 import java.util.stream.Collectors;
 
 import org.eclipse.capra.core.adapters.Connection;
-import org.eclipse.capra.core.adapters.ITraceabilityInformationModelAdapter;
 import org.eclipse.capra.core.adapters.IPersistenceAdapter;
+import org.eclipse.capra.core.adapters.ITraceabilityInformationModelAdapter;
 import org.eclipse.capra.core.handlers.IArtifactHandler;
 import org.eclipse.capra.core.handlers.IArtifactUnpacker;
 import org.eclipse.capra.core.helpers.ArtifactHelper;
@@ -29,6 +29,7 @@
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.capra.ui.helpers.SelectionSupportHelper;
 import org.eclipse.capra.ui.plantuml.handlers.DisplayInternalLinksHandler;
+import org.eclipse.capra.ui.plantuml.handlers.ReverseLinkDirectionHandler;
 import org.eclipse.capra.ui.plantuml.handlers.SelectRelationshipsHandler;
 import org.eclipse.capra.ui.plantuml.handlers.ToggleDisplayGraphHandler;
 import org.eclipse.capra.ui.plantuml.handlers.ToggleTransitivityHandler;
@@ -89,7 +90,8 @@
 		EObject traceModel = null;
 
 		IPersistenceAdapter persistenceAdapter = ExtensionPointHelper.getPersistenceAdapter().orElseThrow();
-		ITraceabilityInformationModelAdapter metamodelAdapter = ExtensionPointHelper.getTraceabilityInformationModelAdapter().orElseThrow();
+		ITraceabilityInformationModelAdapter metamodelAdapter = ExtensionPointHelper
+				.getTraceabilityInformationModelAdapter().orElseThrow();
 
 		ResourceSet resourceSet = EditingDomainHelper.getResourceSet();
 
@@ -201,7 +203,8 @@
 			traces = metamodelAdapter.getTransitivelyConnectedElements(selectedObject, traceModel,
 					selectedRelationshipTypes, transitivityDepth);
 		} else {
-			traces = metamodelAdapter.getConnectedElements(selectedObject, traceModel, selectedRelationshipTypes);
+			traces = metamodelAdapter.getConnectedElements(selectedObject, traceModel, selectedRelationshipTypes,
+					ReverseLinkDirectionHandler.isReverseLinkDirection());
 		}
 		if (DisplayInternalLinksHandler.areInternalLinksShown() && ToggleTransitivityHandler.isTraceViewTransitive()) {
 			EObject previousElement = SelectRelationshipsHandler.getPreviousElement();
diff --git a/bundles/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/handlers/ReverseLinkDirectionHandler.java b/bundles/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/handlers/ReverseLinkDirectionHandler.java
new file mode 100644
index 0000000..fc1aa9b
--- /dev/null
+++ b/bundles/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/handlers/ReverseLinkDirectionHandler.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2016, 2022 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 v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *  
+ * SPDX-License-Identifier: EPL-2.0
+ *  
+ * Contributors:
+ *      Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *      Chalmers | University of Gothenburg - additional features, updated API
+ *******************************************************************************/
+package org.eclipse.capra.ui.plantuml.handlers;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+
+/**
+ * Toggles between showing incoming and outgoing traceability links
+ * 
+ * @author Jan-Philipp Steghöfer
+ */
+public class ReverseLinkDirectionHandler extends AbstractHandler {
+
+	private static final String REVERSE_DIRECTION_PREFERENCE_NODE = "reverseDirection";
+	private static final String REVERSE_DIRECTION_PREFERENCE = "org.eclipse.capra.ui.plantuml.reverseLinkDirection";
+
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		Command command = event.getCommand();
+		boolean oldValue = HandlerUtil.toggleCommandState(command);
+		setReverseLinkDirection(!oldValue);
+		return null;
+	}
+
+	/**
+	 * Checks whether instead of outcoming links, ingoing links should be shown.
+	 * 
+	 * @return {@code true} if incoming links should be shown, {@code false}
+	 *         otherwise
+	 */
+	public static boolean isReverseLinkDirection() {
+		Preferences reverseDirection = getPreference();
+		return reverseDirection.getBoolean("option", false);
+	}
+
+	private static Preferences getPreference() {
+		Preferences preferences = InstanceScope.INSTANCE.getNode(REVERSE_DIRECTION_PREFERENCE);
+		return preferences.node(REVERSE_DIRECTION_PREFERENCE_NODE);
+	}
+
+	/**
+	 * Sets whether the instead of outcoming links, ingoing links should be shown.
+	 * 
+	 * @param value {@code true} if incoming links should be shown, {@code false}
+	 *              otherwise
+	 * 
+	 */
+	public static void setReverseLinkDirection(boolean value) {
+		Preferences reverseLinkDirection = getPreference();
+		reverseLinkDirection.putBoolean("option", value);
+
+		try {
+			// forces the application to save the preferences
+			reverseLinkDirection.flush();
+		} catch (BackingStoreException e) {
+			e.printStackTrace();
+		}
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/views/CapraPlantUmlView.java b/bundles/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/views/CapraPlantUmlView.java
index 7d7a56f..21756fe 100644
--- a/bundles/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/views/CapraPlantUmlView.java
+++ b/bundles/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/views/CapraPlantUmlView.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016, 2019 Chalmers | University of Gothenburg, rt-labs and others.
+ * Copyright (c) 2016, 2022 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 v2.0
  * which accompanies this distribution, and is available at
@@ -13,6 +13,7 @@
  *******************************************************************************/
 package org.eclipse.capra.ui.plantuml.views;
 
+import org.eclipse.capra.ui.plantuml.handlers.ReverseLinkDirectionHandler;
 import org.eclipse.capra.ui.plantuml.handlers.ToggleDisplayGraphHandler;
 import org.eclipse.capra.ui.plantuml.handlers.ToggleLockDiagramHandler;
 import org.eclipse.capra.ui.plantuml.handlers.ToggleTransitivityHandler;
@@ -41,13 +42,16 @@
 		}
 		Command displayGraph = cmdService.getCommand("org.eclipse.capra.ui.plantuml.displayGraph");
 		if (displayGraph != null) {
-			displayGraph.getState(COMMANDS_TOGGLE_STATE)
-					.setValue(ToggleDisplayGraphHandler.isDisplayGraph());
+			displayGraph.getState(COMMANDS_TOGGLE_STATE).setValue(ToggleDisplayGraphHandler.isDisplayGraph());
 		}
 		Command lockDiagram = cmdService.getCommand("org.eclipse.capra.ui.plantuml.lockDiagram");
 		if (lockDiagram != null) {
-			lockDiagram.getState(COMMANDS_TOGGLE_STATE)
-					.setValue(ToggleLockDiagramHandler.isLockDiagram());
+			lockDiagram.getState(COMMANDS_TOGGLE_STATE).setValue(ToggleLockDiagramHandler.isLockDiagram());
+		}
+		Command reverseLinkDirection = cmdService.getCommand("org.eclipse.capra.ui.plantuml.reverseLinkDirection");
+		if (reverseLinkDirection != null) {
+			reverseLinkDirection.getState(COMMANDS_TOGGLE_STATE)
+					.setValue(ReverseLinkDirectionHandler.isReverseLinkDirection());
 		}
 
 	}