From 09c2fb067709ac9228b35a75a83373721819784b Mon Sep 17 00:00:00 2001
From: Alexander Diewald <diewald@fortiss.org>
Date: Thu, 1 Feb 2018 12:18:27 +0000
Subject: [PATCH] Exploration: Use SuperSets to pass model data to the backend.

* Modify (Super)Sets to use a generic that denotes the types of elements within a set. Thereby, it is ensured that only elements of this kind are contained/referenced in a specific set.
* Introduce a SuperSetMap that allows to associate the types of elements of supersets with superset instances.
* Use the SuperSetMap as the main entity to pass model elements from the DSE Project to backends.
* Add the ComponentToTaskAllocationTable to the DSESuperSet and the DSE model element: This is the new way to identify which Tasks belong to which Component.
refs 2939
---
 .../af3/exploration/alg/contribution/.ratings |  2 +-
 .../alg/contribution/Opt4JDseBackend.java     | 38 +++++++++++++++----
 .../exploration/alg/port/DSEPortingUtils.java | 34 ++++++++---------
 3 files changed, 49 insertions(+), 25 deletions(-)

diff --git a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/contribution/.ratings b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/contribution/.ratings
index 9f9c181e..cb13d606 100644
--- a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/contribution/.ratings
+++ b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/contribution/.ratings
@@ -1 +1 @@
-Opt4JDseBackend.java d0d8a516267b93c4b32a4af10166f41ac633d219 RED
+Opt4JDseBackend.java 10829afdc8b0cfc58ac2dcfbc9564b6d38f0c5d1 RED
diff --git a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/contribution/Opt4JDseBackend.java b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/contribution/Opt4JDseBackend.java
index 29863ce7..eca54265 100644
--- a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/contribution/Opt4JDseBackend.java
+++ b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/contribution/Opt4JDseBackend.java
@@ -18,6 +18,8 @@ package org.fortiss.af3.exploration.alg.contribution;
 import static org.fortiss.af3.exploration.alg.port.DSEPortingUtils.createSystemParameterContainer;
 import static org.fortiss.af3.exploration.alg.util.DesignSpaceExplorationModelElementFactory.createDefaultDesignSpaceExploration;
 import static org.fortiss.af3.exploration.util.DesignSpaceExplorationModelElementFactory.createExplorationSpecification;
+import static org.fortiss.tooling.common.util.LambdaUtils.getFirst;
+import static org.fortiss.tooling.kernel.utils.EcoreUtils.getParentsWithType;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -38,8 +40,9 @@ import org.fortiss.af3.exploration.alg.port.plot.XYPlotter;
 import org.fortiss.af3.exploration.alg.service.IExplorationEncoding;
 import org.fortiss.af3.exploration.backend.DseInputContainer;
 import org.fortiss.af3.exploration.backend.IDseBackend;
-import org.fortiss.af3.exploration.backend.IDseInputContainer;
 import org.fortiss.af3.exploration.backend.RuleSetContainer;
+import org.fortiss.af3.exploration.backend.SuperSetMap;
+import org.fortiss.af3.exploration.dsl_v2.model.expression.SuperSet;
 import org.fortiss.af3.exploration.model.ExplorationSolution;
 import org.fortiss.af3.exploration.model.ExplorationSpecification;
 import org.fortiss.af3.exploration.model.IExplorationFeature;
@@ -47,11 +50,16 @@ import org.fortiss.af3.exploration.model.solutions.ExplorationSolutionSet;
 import org.fortiss.af3.exploration.moea.model.DseSpecification;
 import org.fortiss.af3.exploration.moea.model.feature.FeatureFactory;
 import org.fortiss.af3.exploration.projectmodel.RuleSet;
+import org.fortiss.af3.platform.model.ExecutionUnit;
 import org.fortiss.af3.platform.model.PlatformArchitecture;
+import org.fortiss.af3.project.model.FileProject;
+import org.fortiss.af3.project.utils.ProjectUtils;
+import org.fortiss.af3.task.model.Task;
 import org.fortiss.af3.task.model.TaskArchitecture;
 import org.fortiss.tooling.base.model.element.IModelElement;
 import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
 import org.fortiss.tooling.kernel.service.IPersistencyService;
+import org.fortiss.tooling.kernel.utils.EcoreUtils;
 import org.jfree.ui.RefineryUtilities;
 
 /**
@@ -80,15 +88,16 @@ public class Opt4JDseBackend implements IDseBackend {
 	@SuppressWarnings("unchecked")
 	@Override
 	public Optional<ExplorationSolution> executeDSE(RuleSetContainer expSpec,
-			Set<Class<? extends IModelElement>> solutionModels, IDseInputContainer inputContainer,
+			Set<Class<? extends IModelElement>> solutionModels, SuperSetMap superSets,
 			Collection<IExplorationFeature> explorationModules, IProgressMonitor monitor,
 			int timeoutMS) throws Exception {
 		ExplorationSolutionSet explorationSolutionSet;
 		SystemModelAdapter<?, ?, ?, ?, ?, ?> systemModelAdapter;
 		// TODO: Find a cleaner way to extract the model context.
-		ComponentArchitecture refModel = inputContainer.getInputModel(ComponentArchitecture.class);
+		TaskArchitecture taskArchitecture =
+				getArchModel(superSets, TaskArchitecture.class, Task.class);
 		ITopLevelElement context =
-				IPersistencyService.getInstance().getTopLevelElementFor(refModel);
+				IPersistencyService.getInstance().getTopLevelElementFor(taskArchitecture);
 
 		ExplorationSpecification spec = createExplorationSpecification();
 		for(RuleSet ruleSet : expSpec) {
@@ -98,11 +107,12 @@ public class Opt4JDseBackend implements IDseBackend {
 
 		// Input to DSE: {@link SystemModelAdapter} and {@link DesignSpaceExploration}.
 		// SystemModelAdapter systemModelAdapter;
+		FileProject fp = ProjectUtils.getFileProject(taskArchitecture);
 		ComponentArchitecture componentArchitecture =
-				inputContainer.getInputModel(ComponentArchitecture.class);
+				EcoreUtils.pickFirstInstanceOf(ComponentArchitecture.class, fp.getRootElements());
+
 		PlatformArchitecture platformArchitecture =
-				inputContainer.getInputModel(PlatformArchitecture.class);
-		TaskArchitecture taskArchitecture = inputContainer.getInputModel(TaskArchitecture.class);
+				getArchModel(superSets, PlatformArchitecture.class, ExecutionUnit.class);
 		SystemParameterContainer paramContainer =
 				createSystemParameterContainer(platformArchitecture, taskArchitecture, spec);
 		systemModelAdapter = new AF3SystemModelAdapter(componentArchitecture, platformArchitecture,
@@ -151,6 +161,20 @@ public class Opt4JDseBackend implements IDseBackend {
 		return Optional.of(explorationSolutionSet);
 	}
 
+	/**
+	 * Temporary helper method to extract the architecture model from a {@link SuperSet} provided in
+	 * the {@link SuperSetMap} to the DSE.
+	 */
+	private <T extends IModelElement, S extends IModelElement> T getArchModel(SuperSetMap superSets,
+			Class<T> archModelType, Class<S> elementType) throws Exception {
+		Optional<S> anyElem = getFirst(superSets.get(elementType).getEntries());
+		if(!anyElem.isPresent()) {
+			throw new Exception("No " + elementType.getSimpleName() +
+					" has been passed to the DSE in the corresponding set. Exiting.");
+		}
+		return getFirst(getParentsWithType(anyElem.get(), archModelType)).orElse(null);
+	}
+
 	/**
 	 * Creates and launches the Dialog that displays the results from the exploration.
 	 * Pareto-optimal points are displayed in a 2D-graph, while schedules can be inspected for
diff --git a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/port/DSEPortingUtils.java b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/port/DSEPortingUtils.java
index 374d5ea3..b94ffa63 100644
--- a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/port/DSEPortingUtils.java
+++ b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/port/DSEPortingUtils.java
@@ -71,8 +71,8 @@ public class DSEPortingUtils {
 	 * {@link IConnector}.
 	 */
 	// TODO: UsePlatformPort?
-	public static Map<Class<? extends IConnector>, ConnectionType> connectionTypeLUT = Collections
-			.unmodifiableMap(new HashMap<Class<? extends IConnector>, ConnectionType>() {
+	public static Map<Class<? extends IConnector>, ConnectionType> connectionTypeLUT =
+			Collections.unmodifiableMap(new HashMap<Class<? extends IConnector>, ConnectionType>() {
 				{
 				}
 			});
@@ -103,9 +103,9 @@ public class DSEPortingUtils {
 				EcoreUtils.getChildrenWithType(expSpec, Allocation.class);
 		for(Allocation alloc : allocConstrSet) {
 			Collection<IModelElement> targetElementSet =
-					alloc.getRight().getSetReference().getEntries();
-			filterStream(targetElementSet, e -> e instanceof ExecutionUnit).map(
-					ExecutionUnit.class::cast).forEach(e -> rval.add(e));
+					(Collection<IModelElement>)alloc.getRight().getSetReference().getEntries();
+			filterStream(targetElementSet, e -> e instanceof ExecutionUnit)
+					.map(ExecutionUnit.class::cast).forEach(e -> rval.add(e));
 		}
 
 		// for(PlatformArchitecture curPA : platformArchitectures) {
@@ -148,10 +148,10 @@ public class DSEPortingUtils {
 
 		if(rval.isEmpty()) {
 			throw new Exception(
-					"No deployment targets have been specified in the target platform architecture(s)."
-							+ " Please check whether the correct platform architecture was selected and whether"
-							+ " the desired Execution Units were selected as deployment targets"
-							+ " (Platform Model --> Annotation View --> Deployment Target)");
+					"No deployment targets have been specified in the target platform architecture(s)." +
+							" Please check whether the correct platform architecture was selected and whether" +
+							" the desired Execution Units were selected as deployment targets" +
+							" (Platform Model --> Annotation View --> Deployment Target)");
 		}
 
 		return rval;
@@ -277,8 +277,8 @@ public class DSEPortingUtils {
 	 * {@link Component} are not supported.
 	 */
 	// TODO: The period is hard-coded here. It must be taken from the yet-to-come timing model.
-	public static Map<Component, Double> createComponentPeriodMap(
-			Collection<Component> deployableComponents) {
+	public static Map<Component, Double>
+			createComponentPeriodMap(Collection<Component> deployableComponents) {
 		Map<Component, Double> componentPeriodMap = new HashMap<>();
 		for(Component deployableComponent : deployableComponents) {
 			componentPeriodMap.put(deployableComponent, 10.0);
@@ -291,8 +291,8 @@ public class DSEPortingUtils {
 	 * selected as their diverse implementations by means of the {@link ComponentDiverseImplRef}
 	 * annotation.
 	 */
-	public static Multimap<Component, Component> createComponentReplacementMap(
-			Collection<Component> deployableComponent) {
+	public static Multimap<Component, Component>
+			createComponentReplacementMap(Collection<Component> deployableComponent) {
 		Multimap<Component, Component> replacementComponentMap = HashMultimap.create();
 		for(Component component : deployableComponent) {
 			// ComponentDiverseImplRef componentReplacementRef =
@@ -346,8 +346,8 @@ public class DSEPortingUtils {
 	}
 
 	/** Maps the {@link OutputPort}s of {@link Component}s to their respective bit size. */
-	public static Map<OutputPort, Long> createMessageSizeMap(
-			Collection<Component> deployableComponents) throws Exception {
+	public static Map<OutputPort, Long>
+			createMessageSizeMap(Collection<Component> deployableComponents) throws Exception {
 		Map<OutputPort, Long> messageSizes = new HashMap<>();
 		for(Component component : deployableComponents) {
 			for(OutputPort port : component.getOutputPorts()) {
@@ -388,8 +388,8 @@ public class DSEPortingUtils {
 		// --> no duplicates.
 		Set<PlatformArchitecture> targetPlatforms = new HashSet<>();
 		targetPlatforms.add(platformArchitecture);
-		targetPlatforms.add(PlatformArchitectureUtils
-				.getPhysicalPlatformArchitecture(platformArchitecture));
+		targetPlatforms.add(
+				PlatformArchitectureUtils.getPhysicalPlatformArchitecture(platformArchitecture));
 
 		Collection<ExecutionUnit> deploymentTargets = createDeploymentTargets(expSpec);
 
-- 
GitLab