Commit 2c61e615 authored by Simon Barner's avatar Simon Barner

Merge branch 'master' of https://git.fortiss.org/af3/af3.git into 3712

parents a29cc18b 9c3737ec
AF3z3Activator.java 3b41854f824afc76c3f804e627ca24dc438df758 YELLOW
AF3z3Activator.java 3b41854f824afc76c3f804e627ca24dc438df758 GREEN
Z3Type.java 73e319ae206d2fd456ec9430c01b5ff7fc7282d0 GREEN
Z3javaAPIWrapper.java d21fa89f50dd9afe49eaad0901384bdf99df548f GREEN
AllocationTableEditor.java 2887c438b6dbd629f4eb795e68ffd540da6f4c16 GREEN
ModelListenerEditorBase.java 0393577edf52d2cf97e060df93e2d79ea71d9481 GREEN
AllocationTableEditor.java f6f1c153cb555b7cf5b42fec63fce7ae217517f6 GREEN
ArchitectureParameterEditorBase.java c9e9a721f5b8aee62c39ae3307c9ad32a78bce4a GREEN
ArchitectureParameterTableEditorBase.java c5af213271a7a4e9d7d3bc18ab82879ef4030213 GREEN
ModelListenerEditorBase.java 0d0b5bc9c4385061cc69d30f7d9bcd19d5837324 GREEN
ParameterTableEditor.java 435231b3020dca1e20189a132439cc666cc72eb6 GREEN
......@@ -18,6 +18,7 @@ package org.fortiss.af3.allocation.ui.editor;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Stream.concat;
import static org.conqat.ide.commons.ui.selection.SelectionUtils.checkAndPickFirstSafe;
import static org.conqat.lib.commons.reflect.ReflectionUtils.isInstanceOfAny;
import static org.eclipse.jface.dialogs.MessageDialog.openConfirm;
......@@ -25,6 +26,7 @@ import static org.fortiss.af3.allocation.utils.AllocationUtils.checkAllocationEn
import static org.fortiss.af3.allocation.utils.AllocationUtils.getAllocationTableType;
import static org.fortiss.af3.allocation.utils.AllocationUtils.isAllocated;
import static org.fortiss.tooling.common.util.LambdaUtils.asStream;
import static org.fortiss.tooling.common.util.LambdaUtils.getFirst;
import static org.fortiss.tooling.common.util.LambdaUtils.isAssignableFromAny;
import static org.fortiss.tooling.kernel.ui.util.KernelUIUtils.getName;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getEClassForClass;
......@@ -203,11 +205,11 @@ public abstract class AllocationTableEditor<T extends AllocationTable>
}
final IAllocationService as = IAllocationService.getInstance();
if(getSourceModelType() == null) {
if(getSourceModelTypes().isEmpty()) {
throw new RuntimeException("Source model type must be set.");
}
if(getTargetModelType() == null) {
if(getTargetModelTypes().isEmpty()) {
throw new RuntimeException("Target model type must be set.");
}
......@@ -227,16 +229,22 @@ public abstract class AllocationTableEditor<T extends AllocationTable>
return allocationEntryType;
}
/** Returns the source model type. */
private Class<? extends IProjectRootElement> getSourceModelType() {
return IAllocationService.getInstance()
.getSourceModelType(getAllocationTableType(getEditedObject().getClass()));
/** Returns the source model types. */
private Collection<Class<? extends IProjectRootElement>> getSourceModelTypes() {
IAllocationService as = IAllocationService.getInstance();
Class<? extends AllocationTable> allocationTableType =
getAllocationTableType(getEditedObject().getClass());
return as.getSourceModelTypes(allocationTableType);
}
/** Returns the target model type. */
private Class<? extends IProjectRootElement> getTargetModelType() {
return IAllocationService.getInstance()
.getTargetModelType(getAllocationTableType(getEditedObject().getClass()));
/** Returns the target model types. */
private Collection<Class<? extends IProjectRootElement>> getTargetModelTypes() {
IAllocationService as = IAllocationService.getInstance();
Class<? extends AllocationTable> allocationTableType =
getAllocationTableType(getEditedObject().getClass());
return as.getTargetModelTypes(allocationTableType);
}
/** Returns {@link #sourceEntityType}. */
......@@ -292,16 +300,20 @@ public abstract class AllocationTableEditor<T extends AllocationTable>
/** {@inheritDoc} */
@Override
protected boolean isEditedModel(Object object) {
return isInstanceOfAny(object, getSourceModelType(), getTargetModelType());
Stream<Class<? extends IProjectRootElement>> modelTypes =
concat(getSourceModelTypes().stream(), getTargetModelTypes().stream());
return isInstanceOfAny(object, modelTypes.toArray(Class[]::new));
}
/** Performs a refresh for the given {@link IProjectRootElement}. */
protected void refresh(IProjectRootElement model) {
if(model != null) {
Class<? extends IProjectRootElement> sourceModelType = getSourceModelType();
Class<? extends IProjectRootElement> targetModelType = getTargetModelType();
Collection<Class<? extends IProjectRootElement>> sourceModelTypes =
getSourceModelTypes();
Collection<Class<? extends IProjectRootElement>> targetModelTypes =
getTargetModelTypes();
updateModelSelectionComboBox(gui.getComboViewerSource(), getModels(sourceModelType),
updateModelSelectionComboBox(gui.getComboViewerSource(), getModels(sourceModelTypes),
getEditedObject().getSourceView());
// Update available source entity types and super-ordinate elements (that might have
......@@ -313,7 +325,7 @@ public abstract class AllocationTableEditor<T extends AllocationTable>
updateSuperOrdinateElementComboBox(gui.getComboViewerSourceSuperOrdinateElement(),
getSourceSuperOrdinateElements(), this::setSourceSuperOrdinateElement);
updateModelSelectionComboBox(gui.getComboViewerTarget(), getModels(targetModelType),
updateModelSelectionComboBox(gui.getComboViewerTarget(), getModels(targetModelTypes),
getEditedObject().getTargetView());
// Update available target entity types and super-ordinate elements (that might have
......@@ -347,12 +359,12 @@ public abstract class AllocationTableEditor<T extends AllocationTable>
protected void comboViewerOpened(ComboViewer viewer) {
if(viewer == gui.getComboViewerSource()) {
updateModelSelectionComboBox(gui.getComboViewerSource(),
getModels(getSourceModelType()), getEditedObject().getSourceView());
getModels(getSourceModelTypes()), getEditedObject().getSourceView());
gui.getComboViewerSource().refresh();
} else if(viewer == gui.getComboViewerTarget()) {
updateModelSelectionComboBox(gui.getComboViewerTarget(),
getModels(getTargetModelType()), getEditedObject().getTargetView());
getModels(getTargetModelTypes()), getEditedObject().getTargetView());
gui.getComboViewerTarget().refresh();
}
}
......@@ -532,28 +544,28 @@ public abstract class AllocationTableEditor<T extends AllocationTable>
final IAllocationService as = IAllocationService.getInstance();
IProjectRootElement sourceView = null;
IProjectRootElement targetView = null;
List<IProjectRootElement> sourceModels = emptyList();
List<IProjectRootElement> targetModels = emptyList();
Collection<IProjectRootElement> sourceModels = emptyList();
Collection<IProjectRootElement> targetModels = emptyList();
if(getEditedObject() != null) {
targetView = getEditedObject().getTargetView();
targetModels = getModels(getTargetModelType());
targetModels = getModels(getTargetModelTypes());
if(targetView == null && !targetModels.isEmpty()) {
// Set target view if there is none yet, and the at is at least one available.
//
// This must be performed before setting the source view, in order to make the
// special case for the available source view elements in getModels() work
// correctly.
targetView = targetModels.get(0);
targetView = getFirst(targetModels).orElse(null);
final IProjectRootElement view = targetView;
runAsCommand(getEditedObject(), () -> {
getEditedObject().setTargetView(view);
});
}
sourceView = getEditedObject().getSourceView();
sourceModels = getModels(getSourceModelType());
sourceModels = getModels(getSourceModelTypes());
if(sourceView == null && !sourceModels.isEmpty()) {
// Set source view if there is none yet, and the at is at least one available.
sourceView = sourceModels.get(0);
sourceView = getFirst(sourceModels).orElse(null);
final IProjectRootElement view = sourceView;
runAsCommand(getEditedObject(), () -> {
getEditedObject().setSourceView(view);
......@@ -875,12 +887,12 @@ public abstract class AllocationTableEditor<T extends AllocationTable>
/********************* Binding to underlying model *********************/
/**
* Returns the {@link List} of models (i.e., {@link IProjectRootElement}s) of the given type;
* Returns the {@link List} of models (i.e., {@link IProjectRootElement}s) of are of any of the
* given types;
*/
@SuppressWarnings("unchecked")
private List<IProjectRootElement> getModels(Class<? extends IProjectRootElement> type) {
List<? extends IProjectRootElement> models = getRootElements(getEditedObject(), type);
if(uniqueSourceView && type == getSourceModelType()) {
private Collection<IProjectRootElement>
getModels(Collection<Class<? extends IProjectRootElement>> types) {
if(uniqueSourceView && types.containsAll(getSourceModelTypes())) {
for(AllocationTableCollection atc : getRootElements(getEditedObject(),
AllocationTableCollection.class)) {
......@@ -893,7 +905,8 @@ public abstract class AllocationTableEditor<T extends AllocationTable>
}
}
}
return (List<IProjectRootElement>)models;
return getRootElements(getEditedObject(), types);
}
/** Determines the list of model elements offered for a given {@code modelView}. */
......
......@@ -13,9 +13,10 @@
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.task.ui.editor;
package org.fortiss.af3.allocation.ui.editor;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static org.eclipse.emf.ecore.util.EcoreUtil.create;
import static org.fortiss.af3.allocation.model.AF3AllocationPackage.Literals.ALLOCATION_TABLE__SOURCE_VIEW;
......@@ -23,11 +24,13 @@ import static org.fortiss.af3.allocation.model.AF3AllocationPackage.Literals.ALL
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getEClassForClass;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getFirstChildWithType;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickFirstInstanceOf;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickInstanceOf;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.getParentElement;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.getRootElements;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.runAsCommand;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
......@@ -39,14 +42,11 @@ import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.fortiss.af3.allocation.IAllocationService;
import org.fortiss.af3.allocation.model.AllocationTable;
import org.fortiss.af3.allocation.model.AllocationTableCollection;
import org.fortiss.af3.allocation.ui.editor.AllocationTableEditorGUI;
import org.fortiss.af3.allocation.ui.editor.ModelListenerEditorBase;
import org.fortiss.af3.platform.model.PlatformArchitecture;
import org.fortiss.af3.task.model.TaskArchitecture;
import org.fortiss.af3.task.model.allocation.TaskParameterTable;
import org.fortiss.af3.task.model.allocation.TaskToExecutionUnitAllocationTable;
import org.fortiss.af3.allocation.model.ParameterEntry;
import org.fortiss.af3.allocation.model.ParameterTable;
import org.fortiss.tooling.base.model.element.IModelElement;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.model.IProjectRootElement;
......@@ -54,59 +54,101 @@ import org.fortiss.tooling.kernel.service.IElementCompositorService;
import org.fortiss.tooling.kernel.service.IPersistencyService;
/**
* Base class for editors for user-provided properties of {@link TaskArchitecture}s.
* Base class for editors for user-provided properties of various architectures.
*
* @author barner
*/
public abstract class TaskArchitectureParameterEditorBase<T extends TaskParameterTable>
extends ModelListenerEditorBase<TaskArchitecture> {
public abstract class ArchitectureParameterEditorBase<A extends IProjectRootElement, T extends ParameterTable>
extends ModelListenerEditorBase<A> {
/** Type of edited {@link TaskParameterTable}. */
/** Type of edited {@link ParameterTable}. */
private Class<T> paramTableType;
/**
* {@link EReference} that links the edited {@link TaskParameterTable} in the underlying
* {@link TaskArchitecture}.
* {@link EReference} that links the edited {@link ParameterTable} in the underlying
* architecture.
*/
private EReference paramTableRef;
/**
* {@link Collection} of all {@link AllocationTable} types that reference the same target view
* as the underlying parameter table.
*/
private Collection<Class<? extends AllocationTable>> archAllocationTableTypes;
/** The GUI element. */
private TaskArchitectureParameterEditorGUI gui;
private ArchitectureParameterEditorGUI gui;
/** Embedded {@link TaskArchitectureParameterTableEditorBase}. */
private TaskArchitectureParameterTableEditorBase<T> taskParameterTableEditor;
/** Embedded {@link ArchitectureParameterTableEditorBase}. */
private ArchitectureParameterTableEditorBase<A, T> parameterTableEditor;
/** Constructor. */
public TaskArchitectureParameterEditorBase(Class<T> paramTableType, EReference paramTableRef) {
public ArchitectureParameterEditorBase(Class<T> paramTableType, EReference paramTableRef,
Class<? extends ParameterEntry> paramEntryType) {
super(asList(ALLOCATION_TABLE__SOURCE_VIEW, ALLOCATION_TABLE__TARGET_VIEW));
this.paramTableType = paramTableType;
this.paramTableRef = paramTableRef;
this.archAllocationTableTypes = getArchitectureAllocationTableTypes(paramEntryType);
}
/**
* Determines the {@link Collection} of all architecture (i.e., non-parameter)
* {@link AllocationTable} types that reference the same source and target view as the parameter
* tables associated to the given {@code paramEntryType}.
*/
private static Collection<Class<? extends AllocationTable>>
getArchitectureAllocationTableTypes(Class<? extends ParameterEntry> paramEntryType) {
IAllocationService as = IAllocationService.getInstance();
Collection<Class<? extends AllocationTable>> paramTableTypes =
as.getAllocationTableTypesForEntryType(paramEntryType);
Collection<Class<? extends AllocationTable>> rval = new HashSet<>();
for(Class<? extends AllocationTable> parameterTableType : paramTableTypes) {
// Candidates: all allocation table types with matching target view type
Collection<Class<? extends AllocationTable>> atTypes = new HashSet<>();
for(Class<? extends IProjectRootElement> targetViewType : as
.getTargetModelTypes(parameterTableType)) {
atTypes.addAll(as.getAllocationTableTypesForTargetView(targetViewType));
}
// Remove all allocation table types that do not have a matching source view type
for(Class<? extends IProjectRootElement> sourceViewType : as
.getSourceModelTypes(parameterTableType)) {
atTypes.retainAll(as.getAllocationTableTypesForSourceView(sourceViewType));
}
rval.addAll(atTypes);
}
// Filter parameter tables
rval.removeIf(t -> ParameterTable.class.isAssignableFrom(t));
return rval;
}
/** {@inheritDoc} */
@Override
public void dispose() {
super.dispose();
if(taskParameterTableEditor != null) {
taskParameterTableEditor.dispose();
if(parameterTableEditor != null) {
parameterTableEditor.dispose();
}
}
/**
* From the given {@link AllocationTableCollection}, sets the edited {@link TaskArchitecture}'s
* TaskParameterTable}.
* From the given {@link AllocationTableCollection}, sets the edited architecture's
* ParameterTable}.
*/
private void setParameterTableFromRootElement(IProjectRootElement atc) {
T taskParamTable = atc != null ? getFirstChildWithType(atc, paramTableType) : null;
getEditedObject().eSet(paramTableRef, taskParamTable);
if(taskParameterTableEditor != null) {
taskParameterTableEditor.update(taskParamTable);
T paramTable = atc != null ? getFirstChildWithType(atc, paramTableType) : null;
getEditedObject().eSet(paramTableRef, paramTable);
if(parameterTableEditor != null) {
parameterTableEditor.update(paramTable);
}
}
/**
* Returns the {@link AllocationTableCollection} that contains the edited
* {@link TaskArchitecture}'s {@link TaskParameterTable}.
* Returns the {@link AllocationTableCollection} that contains the edited architecture's
* {@link ParameterTable}.
*/
private IProjectRootElement getParameterTableRootElement() {
return getParentElement((EObject)getEditedObject().eGet(paramTableRef),
......@@ -114,78 +156,91 @@ public abstract class TaskArchitectureParameterEditorBase<T extends TaskParamete
}
/**
* Returns the {@link List} of {@link AllocationTableCollection}s that contain a
* {@link TaskToExecutionUnitAllocationTable} for the edited {@link TaskArchitecture} and that
* therefore can be used to the store a {@link TaskParameterTable}.
* Returns the {@link List} of {@link AllocationTableCollection}s that contain a hardware
* allocation table of the given type for the edited architecture and that therefore can be used
* to the store a {@link ParameterTable}.
*/
private List<IProjectRootElement> getTaskAllocationTableCollections() {
final Predicate<? super AllocationTable> containsTaskToExecutionAllocationTable =
at -> (at instanceof TaskToExecutionUnitAllocationTable &&
at.getSourceView() == getEditedObject() &&
at.getTargetView() instanceof PlatformArchitecture);
List<AllocationTableCollection> atcsWithTaskToExecutionUnitAllocationTable =
getRootElements(getEditedObject(), AllocationTableCollection.class).stream()
.filter(atc -> atc.getAllocationTables().stream()
.anyMatch(containsTaskToExecutionAllocationTable))
.collect(toList());
// Add missing TaskParameterTables (for AllocationTableCollections that contain a hardware
// mapping.
for(AllocationTableCollection atc : atcsWithTaskToExecutionUnitAllocationTable) {
if(pickFirstInstanceOf(paramTableType, atc.getAllocationTables()) == null) {
ITopLevelElement topLevel =
IPersistencyService.getInstance().getTopLevelElementFor(getEditedObject());
@SuppressWarnings("unchecked") T taskParamTable =
(T)create(getEClassForClass(paramTableType));
taskParamTable.setSourceView(getEditedObject());