Commit bca08638 authored by Johannes Eder's avatar Johannes Eder

cleaned up tooling.base + ui

* removed all constraint classes

Issue-Ref: 3891
Issue-Url: https://af3-developer.fortiss.org/issues/3891Signed-off-by: Johannes Eder's avatarJohannes Eder <eder@fortiss.org>
parent 7cb54791
......@@ -17,7 +17,6 @@ Export-Package: org.fortiss.tooling.base.ui,
org.fortiss.tooling.base.ui.annotation.view,
org.fortiss.tooling.base.ui.annotation.view.generic,
org.fortiss.tooling.base.ui.annotation.view.generic.filter,
org.fortiss.tooling.base.ui.compose,
org.fortiss.tooling.base.ui.contentprovider,
org.fortiss.tooling.base.ui.dialog,
org.fortiss.tooling.base.ui.dnd.gef,
......
ConstraintBasedProcessCompositor.java 6b98bc9c8096ff6553ffc49040a0919dadb20bae GREEN
/*-------------------------------------------------------------------------+
| Copyright 2011 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.compose;
import static org.eclipse.emf.ecore.util.EcoreUtil.delete;
import static org.fortiss.tooling.base.ui.utils.ConstraintsBaseUIUtils.deactivateConfiguration;
import static org.fortiss.tooling.base.utils.ConstraintsBaseUtils.getDefaultConfig;
import static org.fortiss.tooling.base.utils.ConstraintsBaseUtils.isDefaultConfiguration;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.emf.ecore.EObject;
import org.fortiss.tooling.base.model.element.ConstraintConfiguration;
import org.fortiss.tooling.base.model.element.IConstraintBasedProcess;
import org.fortiss.tooling.kernel.extension.IElementCompositor;
import org.fortiss.tooling.kernel.extension.data.IElementCompositionContext;
import org.fortiss.tooling.kernel.extension.data.Prototype;
import org.fortiss.tooling.kernel.model.IProjectRootElement;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceContainer;
/**
* {@link IElementCompositor} implementation for the {@link IProjectRootElement} s.
*
* @author hoelzl
*/
public class ConstraintBasedProcessCompositor<CBP extends IConstraintBasedProcess>
implements IElementCompositor<CBP> {
/** {@inheritDoc} */
@Override
public boolean canCompose(CBP container, EObject contained,
IElementCompositionContext context) {
return contained instanceof ConstraintConfiguration;
}
/** {@inheritDoc} */
@Override
public boolean compose(CBP container, EObject contained, IElementCompositionContext context) {
ConstraintConfiguration config = (ConstraintConfiguration)contained;
Stream<ConstraintConfiguration> configNamesStream = container.getConfigurations().stream();
List<String> existingNames =
configNamesStream.map(c -> c.getName()).collect(Collectors.toList());
String name = config.getName();
while(existingNames.contains(name)) {
name += " bis";
}
config.setName(name);
container.getConfigurations().add(config);
return true;
}
/** {@inheritDoc} */
@Override
public boolean canComposePrototype(Prototype prototype) {
// As of now constraint configurations should never be added by prototype.
return false;
}
/** {@inheritDoc} */
@Override
public boolean canDecompose(EObject contained) {
return contained instanceof ConstraintConfiguration &&
!isDefaultConfiguration((ConstraintConfiguration)contained);
}
/** {@inheritDoc} */
@Override
public boolean decompose(EObject contained) {
if(contained.eContainer() instanceof IConstraintBasedProcess) {
IConstraintBasedProcess cbdp = (IConstraintBasedProcess)contained.eContainer();
if(contained.equals(cbdp.getCurrentObjective())) {
ConstraintConfiguration defaultConfig = getDefaultConfig(cbdp);
cbdp.setCurrentObjective(defaultConfig);
if(cbdp.eContainer() instanceof IConstraintInstanceContainer) {
IConstraintInstanceContainer cstrContainer =
(IConstraintInstanceContainer)cbdp.eContainer();
deactivateConfiguration((ConstraintConfiguration)contained, cstrContainer,
defaultConfig);
}
}
}
delete(contained);
return true;
}
}
/*-------------------------------------------------------------------------+
| Copyright 2017 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.editor;
import static org.eclipse.jface.resource.FontDescriptor.createFrom;
import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.viewers.StyledString.Styler;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.swt.widgets.Display;
import org.fortiss.tooling.base.model.element.ConstraintConfiguration;
import org.fortiss.tooling.kernel.extension.IConstraint;
// TODO Refactor together with ConstraintBasedProcessEditor and provide a dedicated perspective (see #3189)
/**
* This class is a helper class that provides, 1) the colors for the constraint groups,
* 2) manage the references between the constraint configurations and
* 3) manages the tree manipulation that is used to visualize the constraintsGroups,
* constraintConfigurations and constraints.
*
* @author abid
*
*/
public class ConstraintBasedProcessEditorHelper {
/** Color Array for at least seven groups. */
private static int[] colorArray =
{SWT.COLOR_DARK_GREEN, SWT.COLOR_DARK_BLUE, SWT.COLOR_DARK_YELLOW, SWT.COLOR_BLACK,
SWT.COLOR_DARK_RED, SWT.COLOR_GREEN, SWT.COLOR_CYAN};
/** Counter for the colorArray */
private static int colorCtr = 0;
/** Reference to a constraint configuration. */
private static class WithContextualConfiguration {
/** Contextual constraint configuration. */
ConstraintConfiguration config;
/** Constructor. */
public WithContextualConfiguration(ConstraintConfiguration config) {
this.config = config;
}
}
/** Constraint accompanied with a configuration providing the context. */
public static class ConstraintWithContextualConfiguration extends WithContextualConfiguration {
/** Constraint. */
/* package */Class<? extends IConstraint> cstr;
/** Constructor. */
public ConstraintWithContextualConfiguration(Class<? extends IConstraint> cstr,
ConstraintConfiguration config) {
super(config);
this.cstr = cstr;
}
}
/**
* Configuration accompanied with another configuration providing the context.
* Intent is that the contained configuration is a dependency of the context one.
*/
public static class ConfigurationRefWithContextualConfiguration
extends WithContextualConfiguration {
/** Constraint. */
/* package */ConstraintConfiguration target;
/** Constructor. */
public ConfigurationRefWithContextualConfiguration(ConstraintConfiguration configRef,
ConstraintConfiguration config) {
super(config);
this.target = configRef;
}
/** {@inheritDoc} */
@Override
public boolean equals(Object obj) {
if(obj instanceof ConfigurationRefWithContextualConfiguration) {
// current target name
String currentTargetName = this.target.getName();
// contextualRef Target of the configuration
String configRefTrgtObjName =
((ConfigurationRefWithContextualConfiguration)obj).target.getName();
// current configuration
String currentConfigName = this.config.getName();
// contextualRef Object of the configuration
String configRefObjName =
((ConfigurationRefWithContextualConfiguration)obj).config.getName();
return currentTargetName.equalsIgnoreCase(configRefTrgtObjName) &&
currentConfigName.equalsIgnoreCase(configRefObjName);
}
return false;
}
/** {@inheritDoc} */
@Override
public int hashCode() {
return target.hashCode();
}
}
/** Class to manipulate and store parent of elements. */
public static class TreeStructureNode {
/** Parent object variable. */
/* package */Object parent;
/** Data object variable. */
/* package */Object data;
/** Constructor. */
public TreeStructureNode(Object parent, Object children) {
this.parent = parent;
this.data = children;
}
/** {@inheritDoc} */
@Override
public boolean equals(Object obj) {
if(obj instanceof TreeStructureNode) {
// the current tree node to be compared with
String currentStructureNode = this.data.toString();
// the tree node to be checked
String treeStructureNode = ((TreeStructureNode)obj).data.toString();
// parent of the current tree node
String currentParentNode = this.parent.toString();
// parent of the object that needs to be checked
String objectParentNode = ((TreeStructureNode)obj).parent.toString();
return currentStructureNode.equalsIgnoreCase(treeStructureNode) &&
currentParentNode.equalsIgnoreCase(objectParentNode);
}
return false;
}
/** {@inheritDoc} */
@Override
public int hashCode() {
return parent.hashCode();
}
}
/** Styler class to create colored bold labels for constraint group name. */
public static class NormalFontStyler extends Styler {
/** Counter to keep track of currently used color in color array. */
private int colorIndex = 0;
/** Constructor. */
public NormalFontStyler() {
this.colorIndex = colorCtr;
}
/** {@inheritDoc} */
@Override
public void applyStyles(final TextStyle textStyle) {
FontDescriptor boldDescriptor = createFrom(new FontData()).setStyle(SWT.BOLD);
Font boldFont = boldDescriptor.createFont(Display.getCurrent());
textStyle.font = boldFont;
textStyle.foreground = Display.getCurrent().getSystemColor(colorArray[colorIndex]);
}
}
/** Styler class to create red color labels. */
public static class RedFontStyler extends Styler {
/** {@inheritDoc} */
@Override
public void applyStyles(final TextStyle textStyle) {
FontDescriptor boldDescriptor = createFrom(new FontData()).setStyle(SWT.BOLD);
Font boldFont = boldDescriptor.createFont(Display.getCurrent());
textStyle.font = boldFont;
textStyle.foreground = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED);
}
}
/** Styler class to create green color labels. */
public static class GreenFontStyler extends Styler {
/** {@inheritDoc} */
@Override
public void applyStyles(final TextStyle textStyle) {
FontDescriptor boldDescriptor = createFrom(new FontData()).setStyle(SWT.BOLD);
Font boldFont = boldDescriptor.createFont(Display.getCurrent());
textStyle.font = boldFont;
textStyle.foreground = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN);
}
}
/**
* This function is responsible for updating the color of the constraints groups as they are
* added by updating the color counter (i.e., ColorCtr)
*
* @param groupSize
* is the size of the constraints groups
*/
public static void adjustColorIndex(int groupSize) {
colorCtr++;
colorCtr %= groupSize;
}
}
/*-------------------------------------------------------------------------+
| Copyright 2016 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.utils;
import static org.fortiss.tooling.base.utils.ConstraintsBaseUtils.getActiveConstraintsTransitively;
import static org.fortiss.tooling.base.utils.ConstraintsBaseUtils.removeFromConstraintInstanceContainer;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.fortiss.tooling.base.model.base.ConstraintBasedProcess;
import org.fortiss.tooling.base.model.element.ConstraintConfiguration;
import org.fortiss.tooling.base.model.element.IConstraintBasedProcess;
import org.fortiss.tooling.kernel.extension.IConstraint;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.model.constraints.IConstrained;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceContainer;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceStatus;
import org.fortiss.tooling.kernel.service.IConstraintService;
import org.fortiss.tooling.kernel.service.IPersistencyService;
import org.fortiss.tooling.kernel.service.listener.IPersistencyServiceListener;
import org.fortiss.tooling.kernel.ui.service.IConstraintUIService;
import org.fortiss.tooling.kernel.utils.EcoreUtils;
/**
* Utility methods related to constraints.
*
* @author aravantinos
*/
public class ConstraintsBaseUIUtils {
/** Factorized behaviour. */
public static void doActivateAll(IConstraintInstanceContainer cstrContainer,
IConstraintBasedProcess cbdProcess) {
// First activate the constraints which should always be activated
for(Class<? extends IConstraint> cstrClass : IConstraintUIService.getInstance()
.getAlwaysActivatedConstraints()) {
IConstraintUIService.getInstance().activate(cstrClass, cstrContainer);
}
// Then activate the constraints of the current objective
ConstraintConfiguration currentObj = cbdProcess.getCurrentObjective();
if(currentObj != null) {
List<Class<? extends IConstraint>> activeCstrs =
getActiveConstraintsTransitively(currentObj, null);
for(Class<? extends IConstraint> cstrClass : activeCstrs) {
IConstraintUIService.getInstance().activate(cstrClass, cstrContainer);
}
}
}
/**
* Activates all constraints which are active in the given configuration, potentially adding new
* constraint instances to the provided container.
*/
public static void activateConfiguration(ConstraintConfiguration config,
IConstraintInstanceContainer cstrContainer) {
for(Class<? extends IConstraint> cstr : getActiveConstraintsTransitively(config, null)) {
IConstraintUIService.getInstance().activate(cstr, cstrContainer);
}
}
/**
* Activates all constraints which are active in the given configuration
* (non-transitively).
*/
public static void activateOneConfiguration(ConstraintConfiguration config,
IConstraintInstanceContainer cstrContainer) {
List<Class<? extends IConstraint>> configConstraints = new ArrayList<>();
for(String name : config.getActiveConstraints()) {
configConstraints.add(IConstraintService.getInstance().getConstraintByName(name));
}
for(Class<? extends IConstraint> cstr : configConstraints) {
IConstraintUIService.getInstance().activate(cstr, cstrContainer);
}
}
/**
* Deactivates all constraints which are active in the given configuration, if they are not
* still active in the provided context.
*/
public static void deactivateConfiguration(ConstraintConfiguration config,
IConstraintInstanceContainer cstrContainer, ConstraintConfiguration context) {
List<Class<? extends IConstraint>> stillActiveConstraints =
getActiveConstraintsTransitively(context, config);
for(Class<? extends IConstraint> cstr : getActiveConstraintsTransitively(config, null)) {
if(!stillActiveConstraints.contains(cstr)) {
IConstraintUIService.getInstance().deactivate(cstr, cstrContainer);
}
}
}
/**
* Deactivates all constraints which are active in the given configuration
*/
public static void deactivateConfiguration(ConstraintConfiguration config,
IConstraintInstanceContainer cstrContainer) {
for(Class<? extends IConstraint> cstr : getActiveConstraintsTransitively(config, null)) {
IConstraintUIService.getInstance().deactivate(cstr, cstrContainer);
}
}
/**
* Deactivates all constraints which are active in the given configuration
* (non-transitively).
*/
public static void deactivateOneConfiguration(ConstraintConfiguration config,
IConstraintInstanceContainer cstrContainer) {
List<Class<? extends IConstraint>> configConstraints = new ArrayList<>();
for(String name : config.getActiveConstraints()) {
configConstraints.add(IConstraintService.getInstance().getConstraintByName(name));
}
for(Class<? extends IConstraint> cstr : configConstraints) {
IConstraintUIService.getInstance().deactivate(cstr, cstrContainer);
}
}
/**
* Factorized behavior to install the various listeners necessary for constraints.
* This made in a generic manner so that the client only needs to give a function providing
* access to a {@link ConstraintBasedProcess} given a {@link ITopLevelElement}. The rest is for
* free.
*/
public static class ConstraintBasedProcessAwareActivator {
/**
* Function to access a {@link ConstraintBasedProcess} given a {@link ITopLevelElement}.
* Project-dependent.
*/
private Function<ITopLevelElement, ConstraintBasedProcess> getConstraintBasedProcess;
/** Constructor. */
public ConstraintBasedProcessAwareActivator(
Function<ITopLevelElement, ConstraintBasedProcess> getConstraintBasedProcess) {
this.getConstraintBasedProcess = getConstraintBasedProcess;
}
/** Start the kernel. */
public void start() {
for(ITopLevelElement top : IPersistencyService.getInstance().getTopLevelElements()) {
installListener(top);
activateAllConstraints(top);
}
IPersistencyService.getInstance()
.addTopLevelElementListener(new ConstraintBasedDevelopmentProcessListener());
}
/** Go through all constraints in <code>top</code> and (re-)activates them. */
private void activateAllConstraints(ITopLevelElement top) {
ConstraintBasedProcess cbp = getConstraintBasedProcess.apply(top);
if(cbp != null) {
IConstraintInstanceContainer cic = cbp.getConstraintInstanceContainer();
try {
doActivateAll(cic, cbp);
// The only case where the activation above can trigger a model change is if it
// is discovered that constraints shall be added.
// This should not happen in most cases: the constraint was normally active when
// the project was left and therefore the constraint should already be present.
// However there is a case where this is not the case: when AF3 developers added
// a new constraint and start then AF3 for the first time; then the constraint
// has to be added (sort of migration of the model actually). In such a case the
// line above will trigger an exception because not run in a command. That is
// the whole reason for the catch block thereafter.
// Note that we do not run the activation directly in a command because we do
// not want to mark the model as dirty for nothing.
} catch(IllegalStateException e) {
top.runAsCommand(() -> doActivateAll(cic, cbp));
}
}
}
/**
* Install the listener triggering activation of constraints for the given top level
* element.
* Returns the installed listener.
*/
private void installListener(ITopLevelElement top) {
ConstraintBasedProcess cbp = getConstraintBasedProcess.apply(top);
if(cbp == null) {
return;
}
IConstraintInstanceContainer cic = cbp.getConstraintInstanceContainer();
EContentAdapter listener = new EContentAdapter() {
private boolean isAlreadyAddingMissingConstraints = false;
/** {@inheritDoc} */
@Override
public void notifyChanged(Notification notification) {
super.notifyChanged(notification);
if(isTouch(notification) || isAlreadyAddingMissingConstraints) {
return;
}
// Do not react to change of status.
if(notification.getNewValue() instanceof IConstraintInstanceStatus) {
return;
}
if(notification.getEventType() == Notification.REMOVE &&
notification.getOldValue() instanceof IConstrained) {
IConstrained constrained = (IConstrained)notification.getOldValue();
removeFromConstraintInstanceContainer(constrained);
}
isAlreadyAddingMissingConstraints = true;
IConstraintUIService.getInstance().addMissingConstraintInstances(cic);
isAlreadyAddingMissingConstraints = false;
}
};
top.getRootModelElement().eAdapters().add(listener);
}
/**
* Listener to (re)activate constraints when the project changes.
* Typically to install adequate constraints when a new element was added to the project.
*/
private class ConstraintBasedDevelopmentProcessListener
implements IPersistencyServiceListener {
/** {@inheritDoc} */
@Override
public void topLevelElementLoaded(ITopLevelElement element) {
// ignore
}
/** {@inheritDoc} */
@Override
public void topLevelElementAdded(ITopLevelElement element) {
installListener(element);
}
/** {@inheritDoc} */
@Override
public void topLevelElementContentChanged(ITopLevelElement element) {
// Not our concern.
}
/** {@inheritDoc} */
@Override
public void topLevelElementRemoved(ITopLevelElement element) {
// Not our concern