Skip to content
Snippets Groups Projects
Commit d223d063 authored by Johannes Eder's avatar Johannes Eder
Browse files

removed development process from rcp applicaiton

parent aee35e7c
No related branches found
No related tags found
1 merge request!193891: FOCUSer removal
......@@ -19,14 +19,10 @@
<product
application="org.fortiss.af3.rcp.application.af3app"
description="AutoFOCUS 3 - &quot;Phoenix&quot; Release"
name="AutoFOCUS 3 - &quot;Phoenix&quot;">
name="AutoFOCUS 3 - &quot;Phoenix&quot; 2.14">
<property
name="appName"
value="AutoFOCUS 3 - &quot;Phoenix&quot;">
</property>
<property
name="preferenceCustomization"
value="plugin_customization.ini">
value="AutoFOCUS 3 - &quot;Phoenix&quot; 2.14">
</property>
<property
name="aboutImage"
......@@ -38,7 +34,7 @@
</property>
<property
name="aboutText"
value="AutoFOCUS 3 - &quot;Phoenix&quot;&#x0A;&#x0A;Version: 2.16.0&#x0A;&#x0A;Copyright 2011-present fortiss GmbH&#x0A;&#x0A;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#x0A;you may not use this file except in compliance with the License.&#x0A;You may obtain a copy of the License at&#x0A;&#x0A; http://www.apache.org/licenses/LICENSE-2.0&#x0A;&#x0A;Unless required by applicable law or agreed to in writing, software&#x0A;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#x0A;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either &#x0A;express or implied. See the License for the specific language &#x0A;governing permissions and limitations under the License.">
value="AutoFOCUS 3 - &quot;Phoenix&quot;&#x0A;&#x0A;Version: 2.16.0&#x0A;&#x0A;Copyright 2011-2018 fortiss GmbH&#x0A;&#x0A;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#x0A;you may not use this file except in compliance with the License.&#x0A;You may obtain a copy of the License at&#x0A;&#x0A; http://www.apache.org/licenses/LICENSE-2.0&#x0A;&#x0A;Unless required by applicable law or agreed to in writing, software&#x0A;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#x0A;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either&#x0A;express or implied. See the License for the specific language&#x0A;governing permissions and limitations under the License.">
</property>
<property
name="startupProgressRect"
......@@ -64,6 +60,10 @@
name="introBrandingImageText"
value="Welcome page">
</property>
<property
name="preferenceCustomization"
value="plugin_customization.ini">
</property>
</product>
</extension>
......
ApplicationActionBarAdvisor.java 262a98c4953b79c35d8d001a5d9a93de26f8b937 YELLOW
ApplicationWorkbenchAdvisor.java ef25d5783a4f75e88334fd679834a6e0421f8c2f GREEN
ApplicationWorkbenchWindowAdvisor.java da5cb38300b384579532c678fbc9faa961c2ca6b GREEN
CurrentObjectiveContributionItem.java f5d2504cc9fd548037440da32405a28d77f40283 RED
UpcomingObjectiveContributionItem.java 5721c93ac6ea39842af09703ebc2b0f841bc9ed5 RED
ApplicationActionBarAdvisor.java 262a98c4953b79c35d8d001a5d9a93de26f8b937 YELLOW
ApplicationWorkbenchAdvisor.java 5d1792809c752bedc08b6d9d993ecbf70b40982c YELLOW
ApplicationWorkbenchWindowAdvisor.java da5cb38300b384579532c678fbc9faa961c2ca6b GREEN
CurrentObjectiveContributionItem.java f5d2504cc9fd548037440da32405a28d77f40283 RED
UpcomingObjectiveContributionItem.java 5721c93ac6ea39842af09703ebc2b0f841bc9ed5 RED
......@@ -125,12 +125,6 @@ public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
/** AF3-Specific Export Action. */
private static WorkbenchCommandAction exportAF3ProjectsAction;
/** The current objective combo box. */
private static CurrentObjectiveContributionItem currentObjective;
/** The upcoming objective combo box. */
private static UpcomingObjectiveContributionItem upcomingObjective;
// Actions to open Examples.
/** AF3-Specific Action to open the SimpleTrafficLights-Example. */
......@@ -238,8 +232,6 @@ public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
registerAboutAction(window);
registerGoBack(window);
registerGoForward(window);
createCurrentObjective();
createUpcomingObjective();
}
/**
......@@ -532,21 +524,6 @@ public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
register(goBack);
}
/**
* Creates the "current objective" label by loading the text from a file
*/
private void createCurrentObjective() {
currentObjective = new CurrentObjectiveContributionItem();
}
/**
* Creates the "upcoming objective" label by loading the text from a file
* (for better alignment with the other toolbar elements)
*/
private void createUpcomingObjective() {
upcomingObjective = new UpcomingObjectiveContributionItem();
}
/** {@inheritDoc} */
@Override
protected void fillCoolBar(ICoolBarManager coolBar) {
......@@ -560,10 +537,6 @@ public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
toolBarManager.add(goBack);
toolBarManager.add(goForward);
toolBarManager.add(new Separator());
toolBarManager.add(currentObjective);
toolBarManager.add(upcomingObjective);
upcomingObjective.setCurrentObjective(currentObjective);
}
/** {@inheritDoc} */
......
......@@ -30,7 +30,6 @@ import org.fortiss.af3.exploration.service.IDSEBackendService;
import org.fortiss.af3.exploration.smt.backend.Z3Backend;
import org.fortiss.af3.exploration.ui.AF3ExplorationUIActivator;
import org.fortiss.af3.project.AF3Project;
import org.fortiss.af3.project.ui.AF3ProjectUI;
import org.fortiss.af3.timing.ITimingSpecificationService;
import org.fortiss.tooling.base.ToolingBase;
import org.fortiss.tooling.kernel.ToolingKernel;
......@@ -69,8 +68,6 @@ public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
ToolingKernel.start();
ToolingBase.start();
ToolingKernelUI.start();
AF3Project.start();
AF3ProjectUI.start();
IAllocationService.getInstance().startService();
ITimingSpecificationService.getInstance().startService();
IDSEBackendService.getInstance().startService();
......
/*--------------------------------------------------------------------------+
| |
| |
| 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.af3.rcp.application.advisors;
import static java.util.stream.Collectors.toList;
import static org.eclipse.core.resources.ResourcesPlugin.getWorkspace;
import static org.eclipse.wb.swt.SWTResourceManager.getColor;
import static org.fortiss.tooling.base.ui.utils.ConstraintsBaseUIUtils.activateConfiguration;
import static org.fortiss.tooling.base.ui.utils.ConstraintsBaseUIUtils.deactivateConfiguration;
import static org.fortiss.tooling.base.utils.ConstraintsBaseUtils.getActiveConfigurationsTransitively;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getFirstParentWithType;
import java.text.DecimalFormat;
import java.util.List;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
import org.fortiss.af3.project.model.FileProject;
import org.fortiss.af3.project.model.IProjectConfigurationElement;
import org.fortiss.af3.project.model.configuration.DevelopmentProcessConfiguration;
import org.fortiss.af3.project.model.development.ConstraintBasedDevelopmentProcess;
import org.fortiss.af3.project.model.development.DummyDevelopmentProcess;
import org.fortiss.af3.project.model.impl.ProjectConfigurationImpl;
import org.fortiss.tooling.base.model.element.ConstraintConfiguration;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.model.IProjectRootElement;
import org.fortiss.tooling.kernel.model.constraints.ConstraintInstance;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceContainer;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceStatus;
import org.fortiss.tooling.kernel.model.constraints.SuccessConstraintInstanceStatus;
import org.fortiss.tooling.kernel.service.IPersistencyService;
import org.fortiss.tooling.kernel.ui.service.IConstraintUIService;
/**
* {@link ContributionItem} to select current development process objective.
*
* @author rahman
*
*/
class CurrentObjectiveContributionItem extends WorkbenchWindowControlContribution
implements ISelectionListener, IResourceChangeListener {
/** Helper to align the upcoming objective combo with the current objective combo. */
public class SizedComposite extends Composite {
/** Constructor. */
public SizedComposite(Composite parent, int style) {
super(parent, style);
}
/** {@inheritDoc} */
@Override
public void setSize(Point size) {
super.setSize(computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
}
/** {@inheritDoc} */
@Override
public void setSize(int width, int height) {
Point size = computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
super.setSize(size.x, size.y);
}
}
/** The initial objectives. */
private String[] initialSetOfObjectives = {};
/** Placeholder string for when no objective is selected. */
private String initialObjective = "No modeling objective selected";
/** The Combo holding the time between the simulation steps. */
private CCombo currentObjectiveCombo;
/** The control object holding the combo. */
// private ToolItem toolitem;
/** Composite instance to hold several controls */
private Composite composite;
/** Configuration of the current project selected in the combo box. */
private ConstraintBasedDevelopmentProcess currentDevelopmentProcess = null;
/** Constructor. */
public CurrentObjectiveContributionItem() {
super("CurrentObjectiveContributionItem");
// TODO (SB, 12): See
// org.fortiss.tooling.kernel.ui.util.EObjectSelectionUtils.getSelectionService()
ISelectionService ss =
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService();
ss.addSelectionListener(this);
getWorkspace().addResourceChangeListener(this);
}
/** {@inheritDoc} */
@Override
public boolean isDynamic() {
return true;
}
/** {@inheritDoc} */
@Override
protected Control createControl(Composite parent) {
composite = new SizedComposite(parent, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
layout.marginWidth = 0;
composite.setLayout(layout);
Label label = new Label(composite, SWT.TRANSPARENT);
label.setText("Current Objective");
// Objective Combo
currentObjectiveCombo = new CCombo(composite, SWT.DROP_DOWN);
currentObjectiveCombo.setItems(initialSetOfObjectives);
currentObjectiveCombo.setText(initialObjective);
currentObjectiveCombo.setToolTipText("Set the next modelling objective.");
currentObjectiveCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String textInCombo = ((CCombo)e.getSource()).getText();
if(!textInCombo.isEmpty()) {
updateObjectiveByName(textInCombo);
}
}
});
parent.setSize(composite.computeSize(parent.getSize().x, SWT.DEFAULT, true));
return composite;
}
/** Compute Combo width. */
@Override
protected int computeWidth(Control control) {
return control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x;
}
/**
* Get the pointer to the configuration having a given name.
*
* @param constraintName
* The name of the constraint to look for.
* @return The real configuration.
*/
private ConstraintConfiguration getConstraintConfigByName(String constraintName) {
ConstraintConfiguration ret = null;
if(currentDevelopmentProcess != null) {
EList<ConstraintConfiguration> configs = currentDevelopmentProcess.getConfigurations();
for(ConstraintConfiguration constraintConfiguration : configs) {
if(constraintConfiguration.getName().equals(constraintName)) {
ret = constraintConfiguration;
}
}
}
return ret;
}
/** {@inheritDoc} */
@Override
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
// Updates the current objective if any object is selected on the navigator window.
EList<ConstraintConfiguration> configs = null;
if(selection instanceof ITreeSelection) {
if(((ITreeSelection)selection).getFirstElement() != null) {
Object objectChosenElement = ((ITreeSelection)selection).getFirstElement();
if(objectChosenElement instanceof EObject) {
EObject chosenElement = (EObject)objectChosenElement;
FileProject fileProject = null;
if(chosenElement instanceof FileProject) {
fileProject = (FileProject)chosenElement;
} else {
fileProject = getFirstParentWithType(chosenElement, FileProject.class);
if(fileProject == null) {
// We are in the context of a Library.
return;
}
}
EList<IProjectRootElement> rootElems = fileProject.getRootElements();
// TODO (SB, 14): Test and justify that list is not empty
// there only exists one root for each project
ProjectConfigurationImpl config = (ProjectConfigurationImpl)rootElems.get(0);
EList<IProjectConfigurationElement> configElements =
config.getConfigurationElements();
// TODO (SB, 14): Test and justify that list contains at least two elements (or
// exactly two elements, what-ever makes more sense)
DevelopmentProcessConfiguration processConfig =
(DevelopmentProcessConfiguration)configElements.get(1);
if(!(processConfig.getDevelopment() instanceof DummyDevelopmentProcess)) {
ConstraintBasedDevelopmentProcess process =
(ConstraintBasedDevelopmentProcess)processConfig.getDevelopment();
configs = process.getConfigurations();
currentDevelopmentProcess = process;
List<String> configNames =
configs.stream().map(c -> c.getName()).collect(toList());
String[] configNamesArray = new String[configNames.size()];
configNames.toArray(configNamesArray);
currentObjectiveCombo.setItems(configNamesArray);
String currObjName = currentDevelopmentProcess != null
? currentDevelopmentProcess.getCurrentObjective().getName() : null;
currentObjectiveCombo.setText(currObjName);
updateObjectiveByName(currObjName);
}
}
}
}
}
/**
* Helper structure to keep the number of instances of a constraint that are satisfied
* versus the total number of instances of that constraint.
*/
private class ConstraintResultHolder {
// TODO(SB, 4): Use text from Constructor parameter documentation
// TODO(SB, do you really need a Float object here?)
/** successful constraints count */
private Float successCount;
// TODO(SB, 4): Use text from Constructor parameter documentation
// TODO(SB, do you really need a Float object here?)
/** total constraints count */
private Float totalCount;
// TODO: Just document with /** Constructor. */
/**
* Getter and setter for the number of instances of a constraint that are satisfied
* versus the total number of instances of that constraint.
*
* @param satisfiedConstraintCount
* the count of constraints that are satisfied
* @param totalConstraintCount
* the total number of constraints to be considered
*/
public ConstraintResultHolder(float satisfiedConstraintCount, float totalConstraintCount) {
this.successCount = satisfiedConstraintCount;
this.totalCount = totalConstraintCount;
}
}
/**
* Calculate the scores for the current objectives and all objectives it depends on, display it
* in the tool tip and set the background color of the current objective accordingly.
*/
private void generateScoresAndUpdateUI(ConstraintBasedDevelopmentProcess process) {
float successPercentage = -1f;
ConstraintResultHolder resultHolder = generateScoresForConfig(process);
if(resultHolder.totalCount == 0) {
currentObjectiveCombo.setBackground(null);
currentObjectiveCombo.setToolTipText(
new DecimalFormat("##").format(0 * 100) + "% of the constraints are satisfied");
} else {
successPercentage = resultHolder.successCount / resultHolder.totalCount;
if(successPercentage == 0) {
RGB color = new RGB(0, .5f, 1);
currentObjectiveCombo.setBackground(getColor(color));
} else if(successPercentage < 1f && successPercentage > 0f) {
RGB color = new RGB(20, .5f, 1);
currentObjectiveCombo.setBackground(getColor(color));
} else if(successPercentage == 1f) {
RGB color = new RGB(130, .5f, 1);
currentObjectiveCombo.setBackground(getColor(color));
}
String tooltiptext = new DecimalFormat("##").format(successPercentage * 100) +
"% of the constraints are satisfied";
currentObjectiveCombo.setToolTipText(tooltiptext);
}
}
/**
* Updates the current objective to the objective having the name passed as a parameter.
*
* @param newObjectiveName
* The name of the objective to update to.
*/
public void updateObjectiveByName(String newObjectiveName) {
ConstraintConfiguration newObjective = getConstraintConfigByName(newObjectiveName);
ConstraintConfiguration currentObjective = currentDevelopmentProcess.getCurrentObjective();
final ConstraintConfiguration oldObjective = currentObjective;
if(newObjective != null) {
IPersistencyService ps = IPersistencyService.getInstance();
ITopLevelElement modelContext = ps.getTopLevelElementFor(currentDevelopmentProcess);
modelContext.runAsNonDirtyingCommand(() -> {
currentDevelopmentProcess.setCurrentObjective(newObjective);
List<ConstraintConfiguration> activeConfigs =
getActiveConfigurationsTransitively(newObjective, null);
if(!activeConfigs.contains(oldObjective)) {
IConstraintInstanceContainer constraintInstanceContainer =
currentDevelopmentProcess.getConstraintInstanceContainer();
deactivateConfiguration(oldObjective, constraintInstanceContainer,
newObjective);
}
// TODO(SB, 11): Can't you just shift the definition of
// constraintInstanceContainer in the above if one level up? Or can
// deactivateConfiguration() influence the result of
// currentDevelopmentProcess.getConstraintInstanceContainer()?
IConstraintInstanceContainer constraintInstanceContainer =
currentDevelopmentProcess.getConstraintInstanceContainer();
activateConfiguration(newObjective, constraintInstanceContainer);
});
String currentObjectiveName = currentDevelopmentProcess.getCurrentObjective().getName();
currentObjectiveCombo.setText(currentObjectiveName);
generateScoresAndUpdateUI(currentDevelopmentProcess);
List<String> configNames = currentDevelopmentProcess.getConfigurations().stream()
.map(c -> c.getName()).collect(toList());
String[] configNamesArray = new String[configNames.size()];
configNames.toArray(configNamesArray);
currentObjectiveCombo.removeAll();
for(String comboString : configNamesArray) {
currentObjectiveCombo.add(comboString);
}
String currentObjectiveNewName =
currentDevelopmentProcess.getCurrentObjective().getName();
currentObjectiveCombo.setText(currentObjectiveNewName);
// toolitem.setWidth(computeWidth(composite));
}
}
/**
* Generates an object containing how many instances of a given constraints are satisfied and
* how many constraints in all exist in the given objective.
*/
private ConstraintResultHolder getConstraintValueObjectByName(String constraintName) {
Integer success = 0;
Integer total = 0;
EList<ConstraintInstance> instances =
currentDevelopmentProcess.getConstraintInstanceContainer().getConstraintInstances();
IConstraintUIService cs = IConstraintUIService.getInstance();
for(ConstraintInstance ci : instances) {
if(constraintName.equalsIgnoreCase(ci.getConstraintName())) {
IConstraintInstanceStatus status = cs.getStatus(ci);
if(status instanceof SuccessConstraintInstanceStatus) {
success++;
}
total++;
}
}
return new ConstraintResultHolder(success, total);
}
/** Generates scores for configuration. */
private ConstraintResultHolder
generateScoresForConfig(ConstraintBasedDevelopmentProcess process) {
float totalConstraintCount = 0;
float satisfiedConstraintCount = 0;
EList<String> activeConstraints = process.getCurrentObjective().getActiveConstraints();
for(String activeConstraintName : activeConstraints) {
ConstraintResultHolder constraintValueObjectByName =
getConstraintValueObjectByName(activeConstraintName);
satisfiedConstraintCount += constraintValueObjectByName.successCount;
totalConstraintCount += constraintValueObjectByName.totalCount;
}
return new ConstraintResultHolder(satisfiedConstraintCount, totalConstraintCount);
}
/** {@inheritDoc} */
@Override
public void resourceChanged(IResourceChangeEvent event) {
Display display = Display.getCurrent();
if(event.getType() == IResourceChangeEvent.POST_CHANGE &&
currentDevelopmentProcess != null && display != null) {
display.syncExec(() -> {
generateScoresAndUpdateUI(currentDevelopmentProcess);
EList<ConstraintConfiguration> configurations =
currentDevelopmentProcess.getConfigurations();
List<String> configNames =
configurations.stream().map(c -> c.getName()).collect(toList());
String[] configNamesArray = new String[configNames.size()];
configNames.toArray(configNamesArray);
currentObjectiveCombo.removeAll();
for(String comboString : configNamesArray) {
currentObjectiveCombo.add(comboString);
}
currentObjectiveCombo
.setText(currentDevelopmentProcess.getCurrentObjective().getName());
});
}
}
}
/*-------------------------------------------------------------------------+
| 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.af3.rcp.application.advisors;
import static java.util.Collections.emptyList;
import static org.fortiss.tooling.base.ui.utils.ConstraintsBaseUIUtils.activateConfiguration;
import static org.fortiss.tooling.base.ui.utils.ConstraintsBaseUIUtils.activateOneConfiguration;
import static org.fortiss.tooling.base.ui.utils.ConstraintsBaseUIUtils.deactivateConfiguration;
import static org.fortiss.tooling.base.ui.utils.ConstraintsBaseUIUtils.deactivateOneConfiguration;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
import org.fortiss.af3.project.model.IProjectConfigurationElement;
import org.fortiss.af3.project.model.configuration.DevelopmentProcessConfiguration;
import org.fortiss.af3.project.model.development.ConstraintBasedDevelopmentProcess;
import org.fortiss.af3.project.model.development.impl.DummyDevelopmentProcessImpl;
import org.fortiss.af3.project.model.impl.FileProjectImpl;
import org.fortiss.af3.project.model.impl.ProjectConfigurationImpl;
import org.fortiss.tooling.base.model.element.ConstraintConfiguration;
import org.fortiss.tooling.common.util.LambdaUtils;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.model.IProjectRootElement;
import org.fortiss.tooling.kernel.model.constraints.ConstraintInstance;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceContainer;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceStatus;
import org.fortiss.tooling.kernel.model.constraints.SuccessConstraintInstanceStatus;
import org.fortiss.tooling.kernel.ui.service.IConstraintUIService;
import org.fortiss.tooling.kernel.utils.EcoreUtils;
// TODO (SB, 3)
// TODO (SB, 24): There seem to be many commonalities with CurrentObjectiveContributionItem -> derive base class and/or utility methods. Transfer my review and cleanup in CurrentObjectiveContributionItem also to this class!
/**
* @author levilucio
*/
public class UpcomingObjectiveContributionItem extends WorkbenchWindowControlContribution
implements ISelectionListener, IResourceChangeListener {
/** Helper to align the upcoming objective combo with the current objective combo. */
public class SizedComposite extends Composite {
/** Constructor. */
public SizedComposite(Composite parent, int style) {
super(parent, style);
}
/** {@inheritDoc} */
@Override
public void setSize(Point size) {
super.setSize(computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
}
/** {@inheritDoc} */
@Override
public void setSize(int width, int height) {
Point size = computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
super.setSize(size.x, size.y);
}
}
/** The initial upcoming objectives. */
private String[] initialSetOfObjectives = {};
/** Placeholder string for when no objective is selected. */
private String initialObjective = "No upcoming objective available";
/** The Combo holding the upcoming objectives. */
private CCombo upcomingObjectiveCombo;
/** Configuration of the current project selected in the combo box. */
private ConstraintBasedDevelopmentProcess currentDevelopmentProcess = null;
/** The current objective combo box. */
CurrentObjectiveContributionItem currentObjective;
/** Composite instance to hold several controls */
private Composite composite;
/** Constructor. */
public UpcomingObjectiveContributionItem() {
ISelectionService ww = org.eclipse.ui.PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getSelectionService();
ww.addSelectionListener(this);
IWorkspace workspace = org.eclipse.core.resources.ResourcesPlugin.getWorkspace();
workspace.addResourceChangeListener(this);
}
/** {@inheritDoc} */
@Override
public boolean isDynamic() {
return true;
}
/** {@inheritDoc} */
@Override
protected Control createControl(Composite parent) {
// This extra composite is only required here...
composite = new SizedComposite(parent, SWT.NONE);
GridLayout layout = new GridLayout(3, false);
layout.marginWidth = 0;
composite.setLayout(layout);
// Add a separator to the current objective combo.
new Label(composite, SWT.HORIZONTAL);
Label label = new Label(composite, SWT.TRANSPARENT);
label.setText("Upcoming Objective");
// Objective Combo
upcomingObjectiveCombo = new CCombo(composite, SWT.DROP_DOWN);
upcomingObjectiveCombo.setItems(initialSetOfObjectives);
upcomingObjectiveCombo.setText(initialObjective);
upcomingObjectiveCombo.setToolTipText("Set the next modelling objective.");
upcomingObjectiveCombo.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
currentObjective.updateObjectiveByName(((CCombo)e.getSource()).getText());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// do nothing
}
});
upcomingObjectiveCombo.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
if(currentDevelopmentProcess != null) {
List<ConstraintConfiguration> upcomingConfigs = getUpcomingObjectives();
if(upcomingConfigs.size() != 0) {
List<String> configNames = new ArrayList<String>();
for(ConstraintConfiguration constraintConfiguration : upcomingConfigs) {
configNames.add(constraintConfiguration.getName());
}
String[] configNamesArray = new String[configNames.size()];
configNames.toArray(configNamesArray);
upcomingObjectiveCombo.setItems(configNamesArray);
upcomingObjectiveCombo.setText(configNamesArray[0]);
} else {
upcomingObjectiveCombo.setItems(new String[0]);
upcomingObjectiveCombo.setText(initialObjective);
}
}
}
@Override
public void focusLost(FocusEvent e) {
// do nothing
}
});
parent.setSize(composite.computeSize(parent.getSize().x, SWT.DEFAULT));
return composite;
}
/** Compute Combo Width */
@Override
protected int computeWidth(Control control) {
return control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x;
}
/** {@inheritDoc} */
@Override
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
// set the current project to the one selected on the navigation tree
if(selection instanceof ITreeSelection) {
if(((ITreeSelection)selection).getFirstElement() != null) {
Object objectChosenElement = ((ITreeSelection)selection).getFirstElement();
if(objectChosenElement instanceof EObject) {
EObject chosenElement = (EObject)objectChosenElement;
FileProjectImpl fileProject = null;
if(chosenElement instanceof FileProjectImpl) {
fileProject = (FileProjectImpl)chosenElement;
} else {
fileProject = EcoreUtils.getFirstParentWithType(chosenElement,
FileProjectImpl.class);
if(fileProject == null) {
// We are in the context of a Library.
return;
}
}
EList<IProjectRootElement> rootElems = fileProject.getRootElements();
// there only exists one root for each project
ProjectConfigurationImpl config = (ProjectConfigurationImpl)rootElems.get(0);
EList<IProjectConfigurationElement> configElements =
config.getConfigurationElements();
DevelopmentProcessConfiguration processConfig =
(DevelopmentProcessConfiguration)configElements.get(1);
if(!(processConfig.getDevelopment() instanceof DummyDevelopmentProcessImpl)) {
ConstraintBasedDevelopmentProcess process =
(ConstraintBasedDevelopmentProcess)processConfig.getDevelopment();
currentDevelopmentProcess = process;
}
}
setUpcomingComboBasedOnCrieterion();
}
}
}
/**
* Find the upcoming objectives. These are the objectives following the ones in the
* dependence tree that have already been completely fulfilled (for which all the
* constraints are satisfied).
*
* @return List of configurations not yet satisfied.
*/
private List<ConstraintConfiguration> getUpcomingObjectives() {
// TODO: See #3246, 3248: This may or may not be the right solution
if(currentDevelopmentProcess == null) {
return emptyList();
}
EList<ConstraintConfiguration> configs = currentDevelopmentProcess.getConfigurations();
List<ConstraintConfiguration> atomicConfigs =
LambdaUtils.filterList(configs, c -> c.getIncludedConfigurations().isEmpty());
List<ConstraintConfiguration> satisfiedObjectives = new ArrayList<>();
List<ConstraintConfiguration> upcomingObjectives = new ArrayList<>();
for(ConstraintConfiguration constraintConfiguration : atomicConfigs) {
if(isConfigurationSatisfied(constraintConfiguration)) {
satisfiedObjectives.add(constraintConfiguration);
} else {
upcomingObjectives.add(constraintConfiguration);
}
}
boolean newSatisfiedAddedObjectives = !satisfiedObjectives.isEmpty();
List<ConstraintConfiguration> newConfigsToTreat;
while(newSatisfiedAddedObjectives) {
newSatisfiedAddedObjectives = false;
newConfigsToTreat = getDependentConfigurations(satisfiedObjectives);
newConfigsToTreat.removeAll(upcomingObjectives);
for(ConstraintConfiguration cstr : newConfigsToTreat) {
if(isConfigurationSatisfied(cstr)) {
satisfiedObjectives.add(cstr);
newSatisfiedAddedObjectives = true;
} else
upcomingObjectives.add(cstr);
}
}
return upcomingObjectives;
}
/**
* Find all configurations that depend on a set of given configurations.
*
* @param configs
* The configurations for which dependent configurations will be searched for.
* @return the configurations that depend on the input set of configuration.
*/
private List<ConstraintConfiguration>
getDependentConfigurations(List<ConstraintConfiguration> configs) {
List<ConstraintConfiguration> allConfigs = currentDevelopmentProcess.getConfigurations();
ArrayList<ConstraintConfiguration> res = new ArrayList<ConstraintConfiguration>();
for(ConstraintConfiguration cstr : allConfigs) {
if(cstr.getIncludedConfigurations().size() != 0) {
if(!configs.contains(cstr) &&
configs.containsAll(cstr.getIncludedConfigurations())) {
res.add(cstr);
}
}
}
return res;
}
/**
* Find if a given configuration is satisfied by the current state of the model.
*
* @param constraintConfiguration
* The configuration to check
* @return true if the configuration is satisfied, false otherwise
*/
private boolean isConfigurationSatisfied(ConstraintConfiguration constraintConfiguration) {
ITopLevelElement modelContext = org.fortiss.tooling.kernel.service.IPersistencyService
.getInstance().getTopLevelElementFor(currentDevelopmentProcess);
boolean result = true;
if(modelContext == null) {
return result;
}
EList<String> activeConstraints = constraintConfiguration.getActiveConstraints();
if(!activeConstraints.isEmpty()) {
ConstraintConfiguration currentObjective =
currentDevelopmentProcess.getCurrentObjective();
IConstraintInstanceContainer constraintInstanceContainer =
currentDevelopmentProcess.getConstraintInstanceContainer();
modelContext.runAsNonDirtyingCommand(() -> {
// deactivate current configurations
deactivateConfiguration(currentObjective, constraintInstanceContainer);
// activate configuration to be checked
activateOneConfiguration(constraintConfiguration, constraintInstanceContainer);
});
for(String constraintName : activeConstraints) {
EList<ConstraintInstance> instances =
constraintInstanceContainer.getConstraintInstances();
for(ConstraintInstance ci : instances) {
if(constraintName.equalsIgnoreCase(ci.getConstraintName())) {
IConstraintInstanceStatus status =
IConstraintUIService.getInstance().getStatus(ci);
if(!(status instanceof SuccessConstraintInstanceStatus)) {
result = false;
break;
}
}
}
}
modelContext.runAsNonDirtyingCommand(() -> {
// deactivate configuration to be checked
deactivateOneConfiguration(constraintConfiguration, constraintInstanceContainer);
// reactivate current configuration
activateConfiguration(currentObjective, constraintInstanceContainer);
});
}
return result;
}
/** Sets currentObjective. */
public void setCurrentObjective(CurrentObjectiveContributionItem currentObjective) {
this.currentObjective = currentObjective;
}
/** listener for resource changes */
@Override
public void resourceChanged(IResourceChangeEvent event) {
if(event.getType() == org.eclipse.core.resources.IResourceChangeEvent.POST_CHANGE &&
currentDevelopmentProcess != null && Display.getCurrent() != null) {
setUpcomingComboBasedOnCrieterion();
}
}
/**
* shows and hides the upcoming objective panel based on the number of upcoming objective
*/
private void setUpcomingComboBasedOnCrieterion() {
if(getUpcomingObjectives().isEmpty() && composite != null) {
upcomingObjectiveCombo.setEnabled(false);
} else {
upcomingObjectiveCombo.setEnabled(true);
upcomingObjectiveCombo.setFocus();
}
upcomingObjectiveCombo.redraw();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment