Bug 517292 - [Feature] Prevent the creation of trace links that already exists
This is done by first creating a Connection that represents a trace link to be
created and comparing this to existing connections in the trace model.
In the current implementation, Connection A is equal to Connection B
if it contains the same elements (origin and targets) irrespective of
the order and has the same trace link type.
Change-Id: Iefcc574a8b19138828e020ba800c660176bbc640
diff --git a/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/Connection.java b/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/Connection.java
index 7c4e604..1c16ece 100644
--- a/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/Connection.java
+++ b/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/Connection.java
@@ -10,8 +10,11 @@
*******************************************************************************/
package org.eclipse.capra.core.adapters;
+import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
+import org.eclipse.capra.core.helpers.EMFHelper;
import org.eclipse.emf.ecore.EObject;
/**
@@ -43,4 +46,37 @@
public EObject getTlink() {
return tlink;
}
+
+ @Override
+ public boolean equals(Object object) {
+ if (object == null) {
+ return false;
+ }
+ if (!(object instanceof Connection)) {
+ return false;
+ }
+ if (object == this) {
+ return true;
+ }
+ Connection connection = (Connection) object;
+
+ List<EObject> allFirstElements = new ArrayList<>(this.getTargets());
+ allFirstElements.add(this.getOrigin());
+
+ List<EObject> allSecondElements = new ArrayList<>(connection.getTargets());
+ allSecondElements.add(connection.getOrigin());
+
+ String firstTraceType = EMFHelper.getIdentifier(this.getTlink().eClass());
+ String secondTracetype = EMFHelper.getIdentifier(connection.getTlink().eClass());
+ if (!(firstTraceType.equals(secondTracetype))) {
+ return false;
+ }
+
+ List<String> firstElementsIds = allFirstElements.stream().map(e -> EMFHelper.getIdentifier(e))
+ .collect(Collectors.toList());
+ List<String> secondElementsIds = allSecondElements.stream().map(e -> EMFHelper.getIdentifier(e))
+ .collect(Collectors.toList());
+ return firstElementsIds.containsAll(secondElementsIds);
+ }
+
}
diff --git a/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/TraceMetaModelAdapter.java b/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/TraceMetaModelAdapter.java
index 4a26093..2bfe5ef 100644
--- a/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/TraceMetaModelAdapter.java
+++ b/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/TraceMetaModelAdapter.java
@@ -57,7 +57,7 @@
* returned.
* @param selection
* Objects to create the trace for
- * @return root of trace model that now contains the newly created trace
+ * @return the trace link that has just been created
*/
EObject createTrace(EClass traceType, EObject traceModel, List<EObject> selection);
diff --git a/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/helpers/TraceHelper.java b/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/helpers/TraceHelper.java
index bf41ffb..b37ee24 100644
--- a/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/helpers/TraceHelper.java
+++ b/bundles/org.eclipse.capra.core/src/org/eclipse/capra/core/helpers/TraceHelper.java
@@ -23,6 +23,7 @@
import org.eclipse.capra.core.handlers.IArtifactHandler;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
/**
* Helper class for creating traces
@@ -45,9 +46,10 @@
*
* @param wrappers
* @param traceType
+ * @return the trace link that has been created
*/
- public void createTrace(List<EObject> wrappers, EClass traceType) {
- traceAdapter.createTrace(traceType, traceModel, wrappers);
+ public EObject createTrace(List<EObject> wrappers, EClass traceType) {
+ return traceAdapter.createTrace(traceType, traceModel, wrappers);
}
/**
@@ -102,4 +104,35 @@
}
+ /**
+ * Checks if a trace link of a certain type containing a certain selection
+ * already exists in the trace model.
+ *
+ * @param selection
+ * the selected elements
+ * @param traceType
+ * the type of trace link
+ * @param traceModel
+ * the trace model to be checked
+ * @return true if the link exists
+ */
+
+ public boolean traceExists(List<EObject> selection, EClass traceType, EObject traceModel) {
+ TraceMetaModelAdapter traceAdapter = ExtensionPointHelper.getTraceMetamodelAdapter().get();
+ // create a connection
+ List<EObject> allElements = new ArrayList<>(selection);
+ EObject source = allElements.get(0);
+ allElements.remove(0);
+ List<EObject> targets = allElements;
+
+ // create temporary trace model with a temporary trace link
+ EObject tempTraceModel = ExtensionPointHelper.getTracePersistenceAdapter().get()
+ .getTraceModel(new ResourceSetImpl());
+ EObject tempTlink = traceAdapter.createTrace(traceType, tempTraceModel, selection);
+
+ Connection connection = new Connection(source, targets, tempTlink);
+
+ return traceAdapter.getAllTraceLinks(traceModel).stream().anyMatch(c -> c.equals(connection));
+ }
+
}
diff --git a/bundles/org.eclipse.capra.generic.tracemodels/src/org/eclipse/capra/generic/tracemodels/GenericMetaModelAdapter.java b/bundles/org.eclipse.capra.generic.tracemodels/src/org/eclipse/capra/generic/tracemodels/GenericMetaModelAdapter.java
index aa2b755..26d4cbc 100644
--- a/bundles/org.eclipse.capra.generic.tracemodels/src/org/eclipse/capra/generic/tracemodels/GenericMetaModelAdapter.java
+++ b/bundles/org.eclipse.capra.generic.tracemodels/src/org/eclipse/capra/generic/tracemodels/GenericMetaModelAdapter.java
@@ -83,7 +83,7 @@
}
relatedToTrace.setName(name.toString());
tm.getTraces().add(relatedToTrace);
- return tm;
+ return relatedToTrace;
}
@Override
@@ -177,9 +177,11 @@
List<Connection> allLinks = new ArrayList<>();
for (RelatedTo trace : model.getTraces()) {
- EObject origin = trace.getItem().get(0);
- trace.getItem().remove(0);
- allLinks.add(new Connection(origin, trace.getItem(), trace));
+ List<EObject> allItems = new ArrayList<>();
+ allItems.addAll(trace.getItem());
+ EObject origin = allItems.get(0);
+ allItems.remove(0);
+ allLinks.add(new Connection(origin, allItems, trace));
}
return allLinks;
}
diff --git a/bundles/org.eclipse.capra.ui/src/org/eclipse/capra/ui/handlers/TraceCreationHandler.java b/bundles/org.eclipse.capra.ui/src/org/eclipse/capra/ui/handlers/TraceCreationHandler.java
index 0f2a467..a7d60e1 100644
--- a/bundles/org.eclipse.capra.ui/src/org/eclipse/capra/ui/handlers/TraceCreationHandler.java
+++ b/bundles/org.eclipse.capra.ui/src/org/eclipse/capra/ui/handlers/TraceCreationHandler.java
@@ -30,6 +30,7 @@
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.ui.IWorkbenchWindow;
@@ -70,9 +71,15 @@
// Create trace
if (chosenType.isPresent()) {
+ // check if the connection already exists
+ if (traceHelper.traceExists(wrappers, chosenType.get(), traceModel)) {
+ MessageDialog.openInformation(window.getShell(), "Capra Information",
+ "The trace link you want to create already exists and will therefore not be created");
+ } else {
traceHelper.createTrace(wrappers, chosenType.get());
persistenceAdapter.saveTracesAndArtifacts(traceModel, artifactModel);
- traceHelper.annotateTrace(wrappers);
+ traceHelper.annotateTrace(wrappers);
+ }
}
}
@@ -95,4 +102,5 @@
return Optional.empty();
}
+
}