Skip to content
Snippets Groups Projects
Commit 9c1e0dfb authored by Thomas's avatar Thomas
Browse files

Fixed breaking API changes of FeatureIDE

The previous version of the API employs `configuration.getPropagator()`
to hide the propagation of updates of the configuration.

This has changed in FeatureIDE 3.6.1.

Thanks for suggesting the correct code go to Sebastian Krieter.
parent 5e8d92e0
Branches
No related tags found
No related merge requests found
......@@ -47,35 +47,32 @@ import de.ovgu.featureide.fm.core.analysis.cnf.formula.FeatureModelFormula;
import de.ovgu.featureide.fm.core.base.IFeatureModel;
import de.ovgu.featureide.fm.core.configuration.Configuration;
import de.ovgu.featureide.fm.core.configuration.ConfigurationAnalyzer;
import de.ovgu.featureide.fm.core.configuration.ConfigurationPropagator;
import de.ovgu.featureide.fm.core.configuration.ConfigurationPropagator.UpdateMethod;
import de.ovgu.featureide.fm.core.configuration.SelectableFeature;
import de.ovgu.featureide.fm.core.configuration.Selection;
import de.ovgu.featureide.fm.core.configuration.TreeElement;
import de.ovgu.featureide.fm.core.io.manager.FeatureModelManager;
import de.ovgu.featureide.fm.core.job.LongRunningJob;
import de.ovgu.featureide.fm.core.job.monitor.IMonitor;
import de.ovgu.featureide.fm.ui.editors.featuremodel.operations.FeatureModelOperationWrapper;
import de.ovgu.featureide.fm.ui.views.FeatureModelEditView;
/**
* the feature editor used by the {@link MultipageEditor}
* <p>
* It loads the feature model and its standard configuration. With that informations it can build
* a tree in which the user can make changes of the configuration. After a change in the tree view
* a command is used to make the chosen changes to the configuration of the edited diagram.
* It loads the feature model and its standard configuration. With that
* informations it can build a tree in which the user can make changes of the
* configuration. After a change in the tree view a command is used to make the
* chosen changes to the configuration of the edited diagram.
*
* @author Kevin Kassin
*/
public class FRaMEDFeatureEditor extends EditorPart {
/**
* URLs to the feature model and its standard configuration gathered from {@link URLLiterals}
* URLs to the feature model and its standard configuration gathered from
* {@link URLLiterals}
*/
private final URL URL_TO_FEATUREMODEL = UILiterals.URL_TO_FEATUREMODEL;
/**
* the color values used for the {@link #infoLabel} showing if the chosen configuration is valid or not
* gathered {@link LayoutLiterals}
* the color values used for the {@link #infoLabel} showing if the chosen
* configuration is valid or not gathered {@link LayoutLiterals}
*/
private final Color COLOR_VALID_CONFIGURATION = UILiterals.COLOR_VALID_CONFIGURATION,
COLOR_INVALID_CONFIGURATION = UILiterals.COLOR_INVALID_CONFIGURATION;
......@@ -93,17 +90,20 @@ public class FRaMEDFeatureEditor extends EditorPart {
private MultipageEditor multipageEditor;
/**
* the feature model that used to create configuration and use its rules in the {@link ChangeConfigurationsFeature}
* the feature model that used to create configuration and use its rules in the
* {@link ChangeConfigurationsFeature}
*/
private IFeatureModel featureModel;
/**
* the configuration that used to manage the features in the tree view of the editor
* the configuration that used to manage the features in the tree view of the
* editor
*/
private Configuration configuration;
/**
* the tree view of the editor that is used by the user to edit the configuration of the diagram
* the tree view of the editor that is used by the user to edit the
* configuration of the diagram
*/
private Tree tree;
......@@ -112,19 +112,20 @@ public class FRaMEDFeatureEditor extends EditorPart {
*/
private final Map<SelectableFeature, TreeItem> itemMap = new HashMap<SelectableFeature, TreeItem>();
private ConfigurationPropagator configurationPropagator;
private ConfigurationAnalyzer propagator;
/**
* returns the ConfigurationPropagator for the configuration.
* returns the ConfigurationAnalyzer for the configuration.
*
* @return
*/
public ConfigurationPropagator getConfigurationPropagator() {
return configurationPropagator;
public ConfigurationAnalyzer getConfigurationAnalyzer() {
return propagator;
}
/**
* the get method the configuration of the feature editor
*
* @return the class variable {@link #configuration}
*/
public Configuration getConfiguration() {
......@@ -142,6 +143,7 @@ public class FRaMEDFeatureEditor extends EditorPart {
* (3) {@link #readFeatureModel}<br>
* (4) {@link EditorInputUtil#getResourceFromEditorInput}<br>
* (5) {@link #loadConfiguration}
*
* @param editorInput the opened diagram
* @param multipageEditor the multipage editor that uses this editor
*/
......@@ -149,7 +151,9 @@ public class FRaMEDFeatureEditor extends EditorPart {
super();
this.multipageEditor = multipageEditor;
Resource resource = UIUtil.getResourceFromEditorInput(editorInput);
if (resource == null) { throw new NullPointerException("The resource could not be loaded."); }
if (resource == null) {
throw new NullPointerException("The resource could not be loaded.");
}
Model rootModel = readRootModel(editorInput);
IFeatureModel featureModel = readFeatureModel();
loadConfiguration(rootModel, featureModel);
......@@ -167,10 +171,13 @@ public class FRaMEDFeatureEditor extends EditorPart {
/**
* fetches the root model for a resource
* <p>
* If diagram is null in this operation there is no exception thrown, since this already happens in
* If diagram is null in this operation there is no exception thrown, since this
* already happens in
* {@link DiagramUtil#getMainDiagramForIEditorInput(IEditorInput)}.
*
* @param resource the resource to get the root model from
* @return the root model of the resource is not null and the diagram has a root model and return null else
* @return the root model of the resource is not null and the diagram has a root
* model and return null else
*/
private Model readRootModel(IEditorInput editorInput) {
Diagram diagram = UIUtil.getMainDiagramForIEditorInput(editorInput);
......@@ -181,13 +188,16 @@ public class FRaMEDFeatureEditor extends EditorPart {
/**
* fetches the feature model file and gets its feature model
*
* @return the feature model that is used for the {@link MultipageEditor}
*/
private IFeatureModel readFeatureModel() {
File featureModelFile = null;
try {
featureModelFile = new File(resolveURL(FileLocator.resolve(URL_TO_FEATUREMODEL)));
} catch (URISyntaxException | IOException e) { e.printStackTrace(); }
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
}
FeatureModelManager featureModelManager = FeatureModelManager.getInstance(featureModelFile.toPath());
if (featureModelManager.getLastProblems().containsError()) {
throw new FeatureModelNotReadableException();
......@@ -197,41 +207,33 @@ public class FRaMEDFeatureEditor extends EditorPart {
}
/**
* gets the configuration of the editor using the previously fetched root model and feature model
* @param rootModel the root model to get the {@link FRaMEDConfiguration} from
* gets the configuration of the editor using the previously fetched root model
* and feature model
*
* @param rootModel the root model to get the {@link FRaMEDConfiguration}
* from
* @param featureModel the feature model to instantiate the configuration with
*/
private void loadConfiguration(Model rootModel, IFeatureModel featureModel) {
FRaMEDConfiguration framedConfiguration = rootModel.getFramedConfiguration();
// configuration = new Configuration(featureModel);
// configuration.getPropagator().update();
// Code for new version
FeatureModelFormula formula = new FeatureModelFormula(featureModel);
configuration = new Configuration(new FeatureModelFormula(featureModel));
configurationPropagator=new ConfigurationPropagator(formula,configuration);
//configuration = new Configuration(featureModel);
//configuration.getPropagator().update();
propagator = new ConfigurationAnalyzer(formula, configuration);
propagator.setIncludeAbstractFeatures(true);
propagator.update();
if (framedConfiguration != null) {
for (FRaMEDFeature f : framedConfiguration.getFeatures())
configuration.setManual(f.getName().getLiteral(), Selection.SELECTED);
}
// final LongRunningJob<Collection<SelectableFeature>> job=new LongRunningJob<>("updateing configuration", configurationPropagator.update());
// job.schedule();
// try {
// job.join();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// if (job.getResults()!=null) {
// System.out.println("INFO : "+job.getResults());
// for (SelectableFeature sf:job.getResults()) {
// configuration.setAutomatic(sf, sf.getAutomatic());
// }
// }
}
/**
* Translator from URLs to URIs that creates correct URIs, in contrast to URL.toURI().
* (cf. https://stackoverflow.com/questions/14676966/escape-result-of-filelocator-resolveurl/14677157)
* Translator from URLs to URIs that creates correct URIs, in contrast to
* URL.toURI(). (cf.
* https://stackoverflow.com/questions/14676966/escape-result-of-filelocator-resolveurl/14677157)
*
* @param url the given URL
* @return a new correctly initialized URI object
......@@ -244,13 +246,13 @@ public class FRaMEDFeatureEditor extends EditorPart {
// tree related operation
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* creates the graphical representation of the tree view creating the following parts:
* creates the graphical representation of the tree view creating the following
* parts:
* <p>
* Step 1: the parent composite<br>
* Step 2: the first composite for the label if configuration is valid or not
* Step 3: the label if configuration is valid or not
* Step 4: the second composite for the tree
* Step 5: the tree view
* Step 3: the label if configuration is valid or not Step 4: the second
* composite for the tree Step 5: the tree view
*/
@Override
public void createPartControl(Composite parent) {
......@@ -300,14 +302,16 @@ public class FRaMEDFeatureEditor extends EditorPart {
/**
* add an selection listener to the tree view
* <p>
* The added selection listener calls this editors operation {@link #changeSelection} that uses
* the command {@link ChangeConfigurationCommand} to actually change the configuration of the
* diagram.
* The added selection listener calls this editors operation
* {@link #changeSelection} that uses the command
* {@link ChangeConfigurationCommand} to actually change the configuration of
* the diagram.
*/
private void createSelectionListener() {
tree.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {}
public void widgetDefaultSelected(SelectionEvent e) {
}
@Override
public void widgetSelected(SelectionEvent event) {
......@@ -327,24 +331,22 @@ public class FRaMEDFeatureEditor extends EditorPart {
case UNDEFINED:
changeSelection(item, true);
break;
} } } } } ); }
}
// New call
//updateTree();
}
}
}
});
}
/**
* updates the labels text and color if the configuration is valid or not
*/
private void updateInfoLabel() {
// Boolean valid = configuration.isValid();
boolean valid = propagator.isValid();
// Code for new version
LongRunningJob<Boolean> job=new LongRunningJob<Boolean>("isValid check",configurationPropagator.isValid());
job.schedule();
Boolean valid=false;
try {
job.join();
if (job.getResults()!=null)
valid=job.getResults();
} catch (InterruptedException e) {
e.printStackTrace();
}
infoLabel.setText(valid ? "VALID Configuration" : "INVALID Configuration");
infoLabel.setForeground(valid ? COLOR_VALID_CONFIGURATION : COLOR_INVALID_CONFIGURATION);
}
......@@ -355,23 +357,7 @@ public class FRaMEDFeatureEditor extends EditorPart {
private void updateTree() {
tree.removeAll();
final TreeItem root = new TreeItem(tree, 0);
//New code
// final LongRunningJob<Collection<SelectableFeature>> job=new LongRunningJob<>("updateing configuration", configurationPropagator.update());
// job.setPriority(LongRunningJob.SHORT);
// job.schedule();
// try {
// job.join();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// if (job.getResults()!=null) {
// System.out.println("INFO : "+job.getResults());
// for (SelectableFeature sf:job.getResults()) {
// configuration.setAutomatic(sf, sf.getAutomatic());
// }
// }
propagator.update();
final SelectableFeature rootFeature = configuration.getRoot();
root.setText(configuration.getRoot().getName());
root.setData(configuration.getRoot());
......@@ -382,6 +368,7 @@ public class FRaMEDFeatureEditor extends EditorPart {
/**
* set the selection of a item in the tree view
*
* @param item the item to set the selection of
* @param feature the corresponding feature of the item
*/
......@@ -402,10 +389,14 @@ public class FRaMEDFeatureEditor extends EditorPart {
item.setForeground(null);
item.setChecked(feature.getManual() == Selection.SELECTED);
break;
} }
}
// Always expand the full feature tree
item.setExpanded(true);
}
/**
* builds the tree view from a specific root on
*
* @param parent the root the tree is build from on
* @param children the children of the specific root
*/
......@@ -418,19 +409,23 @@ public class FRaMEDFeatureEditor extends EditorPart {
// This try for the case that the parent item is already disposed.
try {
childNode = new TreeItem(parent, 0);
} catch (Exception e) { return; }
} catch (Exception e) {
return;
}
childNode.setText(currentFeature.getFeature().getName());
childNode.setData(currentFeature);
refreshItem(childNode, currentFeature);
itemMap.put(currentFeature, childNode);
if (currentFeature.hasChildren()) {
buildTree(childNode, currentFeature.getChildren());
} } }
parent.setExpanded(true);
}
}
}
}
/**
* updates the selections of the tree view from a specific root on
*
* @param parent the root the tree is build from on
* @param children the children of the specific root
*/
......@@ -444,12 +439,16 @@ public class FRaMEDFeatureEditor extends EditorPart {
refreshItem(t, currentFeature);
updateSelections(t, currentFeature.getChildren());
break;
} } } }
}
}
}
}
}
/**
* uses the command {@link ChangeConfigurationCommand} to change the configuration of the
* diagram.
* uses the command {@link ChangeConfigurationCommand} to change the
* configuration of the diagram.
*
* @param item the tree item to change the selection of
* @param select the new selection
*/
......@@ -464,6 +463,7 @@ public class FRaMEDFeatureEditor extends EditorPart {
/**
* sets the selection of a feature in the feature editors configuration
*
* @param item the item to get corresponding feature from
* @param select the new selection of the feature
*/
......@@ -483,6 +483,7 @@ public class FRaMEDFeatureEditor extends EditorPart {
default:
configuration.setManual(feature, Selection.UNDEFINED);
}
propagator.update();
TreeElement configRootFeature = configuration.getRoot();
updateSelections(itemMap.get(configRootFeature), configRootFeature.getChildren());
}
......@@ -492,13 +493,15 @@ public class FRaMEDFeatureEditor extends EditorPart {
/**
* synchonizes the configuration of the diagram and the feature editor
* <p>
* This is needed because their can be inconsistent states be between these two configuration
* after the use of undo and redo. The method uses the following steps:<br>
* Step 1: It searches for features are chosen in the diagram but aren't checked in the
* feature model configuration and checks them in the second configuration<br>
* Step 2: If a feature was not chosen in the diagram, but it is checked in the feature model
* configuration, uncheck it in the feature editor
* Step 3: update tree to show the change to the user
* This is needed because their can be inconsistent states be between these two
* configuration after the use of undo and redo. The method uses the following
* steps:<br>
* Step 1: It searches for features are chosen in the diagram but aren't checked
* in the feature model configuration and checks them in the second
* configuration<br>
* Step 2: If a feature was not chosen in the diagram, but it is checked in the
* feature model configuration, uncheck it in the feature editor Step 3: update
* tree to show the change to the user
*/
public void synchronizeConfigurationEditorAndModelConfiguration() {
EList<FRaMEDFeature> selectedFeatures = multipageEditor.getDiagramEditor().getSelectedFeatures();
......@@ -512,13 +515,17 @@ public class FRaMEDFeatureEditor extends EditorPart {
setSelection(entry.getValue(), true);
}
mapEntryFound = true;
} } }
}
}
}
// Step 2
if (!mapEntryFound) {
if (entry.getKey().getAutomatic() == Selection.UNDEFINED) {
if ((entry.getValue().getChecked())) {
setSelection(entry.getValue(), false);
} } }
}
}
}
mapEntryFound = false;
}
// Step 3
......@@ -532,10 +539,12 @@ public class FRaMEDFeatureEditor extends EditorPart {
* empty implementation of setFocus
*/
@Override
public void setFocus() {}
public void setFocus() {
}
/**
* since the resource of this editor is not to save by Graphiti always return false as dirty bit
* since the resource of this editor is not to save by Graphiti always return
* false as dirty bit
*/
@Override
public boolean isDirty() {
......@@ -546,7 +555,8 @@ public class FRaMEDFeatureEditor extends EditorPart {
* empty implementation of doSave
*/
@Override
public void doSave(IProgressMonitor monitor) {}
public void doSave(IProgressMonitor monitor) {
}
/**
* disable the saveAs function
......@@ -560,8 +570,7 @@ public class FRaMEDFeatureEditor extends EditorPart {
* empty implementation of doSaveAs
*/
@Override
public void doSaveAs() {}
public void doSaveAs() {
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment