Commit 17576b24 authored by Simon Barner's avatar Simon Barner
Browse files

Add marker interface IDirection to specify if an allocation entry is

- bidirectional, i.e. if the source(s) can be determined from the target
- unidirectional, i.e., if multiple source(s) reference the same target(s)

It is mandatory that any concrete AllocationEntrys inherit either IBidirectional or IUnidirectional.

TODO: Correctly handle IUnidirectional allocation entries in the getSource/TargetElement[s] eOperations of AllocationTable
refs 2950
parent 8f505d84
......@@ -20,6 +20,7 @@ package org.fortiss.af3.allocation.ui.editor;
import static java.util.Collections.emptyList;
import static org.conqat.lib.commons.reflect.ReflectionUtils.isInstanceOfAny;
import static org.fortiss.af3.allocation.utils.AllocationUtils.addAllocationEntry;
import static org.fortiss.af3.allocation.utils.AllocationUtils.checkAllocationEntryType;
import static org.fortiss.af3.allocation.utils.AllocationUtils.deleteAllocationEntry;
import static org.fortiss.af3.allocation.utils.AllocationUtils.isAllocated;
import static org.fortiss.af3.allocation.utils.AllocationUtils.isModifiableAllocationEntry;
......@@ -118,6 +119,9 @@ public abstract class AllocationTableEditor<T extends AllocationTable> extends
Class<? extends IModelElement> sourceEntityType,
Class<? extends IModelElement> targetEntityType,
ViewElementFilter sourceViewElementFilter, ViewElementFilter targetViewElementFilter) {
checkAllocationEntryType(allocationEntryType);
this.allocationEntryType = allocationEntryType;
this.sourceModelType = sourceModelType;
this.targetModelType = targetModelType;
......
......@@ -198,4 +198,21 @@
</eAnnotations>
</eStructuralFeatures>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="IDirection" abstract="true" interface="true">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Maker interface to specify direction of an {@link AllocationEntry}. All concrete {@link AllocationEntry}s must inherit from either {@link IUniDirectional} or {@link IBiDirectional}."/>
</eAnnotations>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="IUnidirectional" abstract="true" interface="true"
eSuperTypes="#//IDirection">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Maker interface to specify that an {@link AllocationEntry} is unidirectional, i.e. that target elements can be reused in more than one {@link AllocationEntry}."/>
</eAnnotations>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="IBidirectional" abstract="true" interface="true"
eSuperTypes="#//IDirection">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Maker interface to specify that an {@link AllocationEntry} is bidirectional, i.e. that the mapping between target elements and source elements is unique (i.e., target elements may be used in only one {@link AllocationEntry})."/>
</eAnnotations>
</eClassifiers>
</ecore:EPackage>
......@@ -56,5 +56,8 @@
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference allocation.ecore#//ManyToOneAllocationEntry/sourceElements"/>
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference allocation.ecore#//ManyToOneAllocationEntry/targetElement"/>
</genClasses>
<genClasses image="false" ecoreClass="allocation.ecore#//IDirection"/>
<genClasses image="false" ecoreClass="allocation.ecore#//IUnidirectional"/>
<genClasses image="false" ecoreClass="allocation.ecore#//IBidirectional"/>
</genPackages>
</genmodel:GenModel>
......@@ -26,6 +26,7 @@ import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EOperation;
import org.fortiss.af3.allocation.model.AllocationEntry;
import org.fortiss.af3.allocation.model.AllocationTable;
import org.fortiss.af3.allocation.model.IBidirectional;
import org.fortiss.af3.allocation.model.ManyToOneAllocationEntry;
import org.fortiss.af3.allocation.model.OneToManyAllocationEntry;
import org.fortiss.af3.allocation.model.OneToOneAllocationEntry;
......@@ -123,6 +124,10 @@ public class AllocationTableStaticImpl {
* Returns the target element to which the given source element is mapped in a
* {@link OneToOneAllocationEntry}, or {@code null} in case no such mapping has been defined.
*
* <p>
* <b>Note:</b> This method is only applicable for {@link IBidirectional} allocation entries.
* </p>
*
* @param allocationTable
* {@link AllocationTable} in which to lookup target model element for given source
* model element.
......@@ -150,11 +155,15 @@ public class AllocationTableStaticImpl {
* {@link ManyToOneAllocationEntry}, or {@code null} in case no such mapping has been defined.
* </p>
* <p>
* <b>Note:</b> The list of {@code sourceElements} does not have to be complete. I.e., it is
* <b>Note 1:</b> The list of {@code sourceElements} does not have to be complete. I.e., it is
* sufficient if there is an {@link ManyToOneAllocationEntry} whose source list contains the
* provided {@code sourceElements}.
* </p>
*
* <p>
* <b>Note 2:</b> This method is only applicable for {@link IBidirectional} allocation entries.
* </p>
*
* @param allocationTable
* {@link AllocationTable} in which to lookup target model element for given source
* model elements.
......@@ -204,8 +213,14 @@ public class AllocationTableStaticImpl {
}
/**
* <p>
* Returns the source element which is mapped to the given target element in a
* {@link OneToOneAllocationEntry}, or {@code null} in case no such mapping has been defined.
* </p>
*
* <p>
* <b>Note</b> This method is only applicable for {@link IBidirectional} allocation entries.
* </p>
*
* @param allocationTable
* {@link AllocationTable} in which to lookup source model element for given target
......@@ -234,10 +249,13 @@ public class AllocationTableStaticImpl {
* {@link OneToManyAllocationEntry}, or {@code null} in case no such mapping has been defined.
* </p>
* <p>
* <b>Note:</b> The list of {@code targetElements} does not have to be complete. I.e., it is
* <b>Note 1:</b> The list of {@code targetElements} does not have to be complete. I.e., it is
* sufficient if there is an {@link OneToManyAllocationEntry} whose target list contains the
* provided {@code targetElements}.
* </p>
* <p>
* <b>Note 2:</b> This method is only applicable for {@link IBidirectional} allocation entries.
* </p>
*
* @param allocationTable
* {@link AllocationTable} in which to lookup source model elements for given target
......
......@@ -18,6 +18,7 @@ $Id$
package org.fortiss.af3.allocation.utils;
import static org.eclipse.emf.ecore.util.EcoreUtil.create;
import static org.fortiss.af3.allocation.utils.AllocationUtils.checkAllocationEntryType;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getEClassForClass;
import org.fortiss.af3.allocation.model.AF3AllocationFactory;
......@@ -63,6 +64,7 @@ public class AllocationModelElementFactory {
*/
@SuppressWarnings("unchecked")
public static <T extends AllocationEntry> T createAllocationEntry(Class<T> type) {
checkAllocationEntryType(type);
return (T)create(getEClassForClass(type));
}
}
......@@ -23,6 +23,8 @@ import static org.fortiss.tooling.kernel.utils.JavaUtils.isDirectlyDerived;
import org.fortiss.af3.allocation.model.AllocationEntry;
import org.fortiss.af3.allocation.model.AllocationTable;
import org.fortiss.af3.allocation.model.AllocationTableCollection;
import org.fortiss.af3.allocation.model.IBidirectional;
import org.fortiss.af3.allocation.model.IUnidirectional;
import org.fortiss.af3.allocation.model.ManyToOneAllocationEntry;
import org.fortiss.af3.allocation.model.OneToManyAllocationEntry;
import org.fortiss.af3.allocation.model.OneToOneAllocationEntry;
......@@ -189,9 +191,20 @@ public class AllocationUtils {
if(isAllocated(allocationTable, entryType, sourceElement, targetElement)) {
return true;
}
// Remember in the following that the case (sourceElement, targetElement) has just been
// ruled out
// ruled out. Because of that, adding further entries to unidirectional allocation entries
// is always possible:
//
// - 1:1: Adds a new OneToOne allocation entry
// - 1:n: If no entry exists for the given sourceElement, a new entry is created. Otherwise,
// the existing entry is extended with the additional targetElement.
// - n:1: If no entry exists for the given targetElement, a new entry is created. Otherwise,
// the existing entry is extended with the additional sourceElement.
if(isDirectlyDerived(entryType, IUnidirectional.class)) {
return true;
}
// From now on, we assume that the allocation entry is bidirectional.
if(isOneToOne(entryType)) {
return !(isAllocated(allocationTable, entryType, null, targetElement) || isAllocated(
allocationTable, entryType, sourceElement, null));
......@@ -281,4 +294,22 @@ public class AllocationUtils {
private static boolean isManyToOne(Class<? extends AllocationEntry> entryType) {
return isDirectlyDerived(entryType, ManyToOneAllocationEntry.class);
}
/**
* Checks if the given {@code allocationEntryType} implements either the {@link IUnidirectional}
* or {@link IBidirectional} marker interface.
*
* @throws RuntimeException
* in case the condition is violated.
*/
public static void
checkAllocationEntryType(Class<? extends AllocationEntry> allocationEntryType)
throws RuntimeException {
if(!(IUnidirectional.class.isAssignableFrom(allocationEntryType) || IBidirectional.class
.isAssignableFrom(allocationEntryType))) {
throw new RuntimeException("AllocationEntry type " +
allocationEntryType.getCanonicalName() +
" must implement either IUniDirectional or IBidirectional.");
}
}
}
......@@ -64,20 +64,20 @@
</eOperations>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="LogicalComponentToPartitionAllocationEntry"
eSuperTypes="platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//ManyToOneAllocationEntry">
eSuperTypes="platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//ManyToOneAllocationEntry platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//IBidirectional">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="TODO"/>
</eAnnotations>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="LogicalChannelToPartitionChannelAllocationEntry"
eSuperTypes="platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//ManyToOneAllocationEntry">
eSuperTypes="platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//ManyToOneAllocationEntry platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//IBidirectional">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="TODO"/>
</eAnnotations>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="LogicalInPortToPartitionInPortAllocationEntry"
eSuperTypes="platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//ManyToOneAllocationEntry"/>
eSuperTypes="platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//ManyToOneAllocationEntry platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//IBidirectional"/>
<eClassifiers xsi:type="ecore:EClass" name="LogicalOutPortToPartitionOutPortAllocationEntry"
eSuperTypes="platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//ManyToOneAllocationEntry"/>
eSuperTypes="platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//ManyToOneAllocationEntry platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//IBidirectional"/>
</eSubpackages>
</ecore:EPackage>
......@@ -275,7 +275,7 @@
<eParameters name="core" eType="#//processor/Core"/>
</eOperations>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="PartitionToCoreAllocationEntry" eSuperTypes="platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//OneToManyAllocationEntry">
<eClassifiers xsi:type="ecore:EClass" name="PartitionToCoreAllocationEntry" eSuperTypes="platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//OneToManyAllocationEntry platform:/resource/org.fortiss.af3.allocation/model/allocation.ecore#//IUnidirectional">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="{@link AllocationEntry} specialization to defines the allocation of a {@link Partition} to {@link Core}s."/>
</eAnnotations>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment