tools.vitruv.change.testutils.changevisualization.tree.decoder.TreeChangeDataSetDecoder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tools.vitruv.change.testutils.changevisualization Show documentation
Show all versions of tools.vitruv.change.testutils.changevisualization Show documentation
Utilities for visualization changes on models
The newest version!
package tools.vitruv.change.testutils.changevisualization.tree.decoder;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.stream.Collectors;
import javax.swing.tree.DefaultMutableTreeNode;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import tools.vitruv.change.atomic.EChange;
import tools.vitruv.change.composite.description.PropagatedChange;
import tools.vitruv.change.composite.description.VitruviusChange;
import tools.vitruv.change.testutils.changevisualization.common.ChangeDataSet;
import tools.vitruv.change.testutils.changevisualization.common.ChangeDataSet.ChangeType;
import tools.vitruv.change.testutils.changevisualization.tree.TreeChangeDataSet;
import tools.vitruv.change.testutils.changevisualization.tree.decoder.feature.MultipleFeatureProcessor;
import tools.vitruv.change.testutils.changevisualization.tree.decoder.feature.OldValueNewValueProcessor;
/**
* Helper class to generate {@link TreeChangeDataSet}s from propagation results and
* register {@link MultipleFeatureProcessor}s.
*
* @author Andreas Loeffler
*/
public class TreeChangeDataSetDecoder {
/**
* The string used to name propagated changes in the list.
*/
private static final String PROPAGATED_CHANGE_STRING="Propagated Change";
/**
* The string used to name original changes in the list.
*/
private static final String ORIGINAL_CHANGE_STRING="Original Change";
/**
* The string used to name consequential changes in the list.
*/
private static final String CONSEQUENTIAL_CHANGE_STRING="Consequential Change";
/**
* Processors which apply multiple structural feature enhancements to structural feature leaf nodes
*/
private static List multipleFeatureProcessors=new Vector();
//register additional multiple feature processors
static {
//processor that combines oldValue / newValue pairs
registerMultipleFeatureProcessor(new OldValueNewValueProcessor());
}
/**
* Can be called to register new processors implementing multiple structural feature enhancements
*
* @param proc The processor for multi feature enhancements
*/
public static void registerMultipleFeatureProcessor(MultipleFeatureProcessor proc) {
multipleFeatureProcessors.add(proc);
}
/**
* The generated changeDataSet
*/
private final TreeChangeDataSet changeDataSet;
/**
* The root node for the changeDataSet
*/
private final DefaultMutableTreeNode rootNode;
/**
* The number of propagated changes
*/
private int nrPropagatedChanges=0;
/**
* The number of consequential changes
*/
private int nrConsequentialChanges=0;
/**
* The number of original changes
*/
private int nrOriginalChanges=0;
/**
* Constructs a new TreeChangeDataSetDecoder instance from which a generated
* {@link ChangeDataSet} can be acquired.
*
* @param id The id of the changeDataSet to create
* @param changes The changes to present, must not be null
*/
public TreeChangeDataSetDecoder(String id, Iterable changes) {
rootNode = new DefaultMutableTreeNode(id);
for(PropagatedChange propChange:changes) {
DefaultMutableTreeNode propChangeNode = encodeTree(propChange);
rootNode.add(propChangeNode);
}
changeDataSet = new TreeChangeDataSet(id, rootNode);
changeDataSet.setNrPropagatedChanges(getNrPropagatedChanges());
changeDataSet.setNrOriginalChanges(getNrOriginalChanges());
changeDataSet.setNrConsequentialChanges(getNrConsequentialChanges());
}
/**
* Return the generated ChangeDataSet
*
* @return The generated ChangeDataSet
*/
public ChangeDataSet getChangeDataSet() {
return changeDataSet;
}
/**
* Creates the node for the given propagated change and appends it to the root node.
* Calls methods that create the original/consequential change child nodes for the propagted change
* @param propChange The propagated change
* @return The node representing the given propagated change
*/
private DefaultMutableTreeNode encodeTree(PropagatedChange propChange) {
//Count the propagated changes in the list, prior to creating the propChangeNode so it gets counted from 1 upwards.
setNrPropagatedChanges(getNrPropagatedChanges()+1);
//Create a propagated change childnode
String sourceMetamodelsString = propChange.getOriginalChange().getAffectedEObjectsMetamodelDescriptors().stream().flatMap(descriptor -> descriptor.getNsUris().stream()).collect(Collectors.joining(", "));
String targetMetamodelsString = propChange.getConsequentialChanges().getAffectedEObjectsMetamodelDescriptors().stream().flatMap(descriptor -> descriptor.getNsUris().stream()).collect(Collectors.joining(", "));
DefaultMutableTreeNode propChangeNode=new DefaultMutableTreeNode(PROPAGATED_CHANGE_STRING+" "+getNrPropagatedChanges() + "(from: " + sourceMetamodelsString + "; to: " + targetMetamodelsString + ")");
//Process original changes
DefaultMutableTreeNode origNode = encodeTree(ChangeType.ORIGINAL_CHANGE,propChange.getOriginalChange());
setNrOriginalChanges(getNrOriginalChanges()+origNode.getChildCount());//Count the original changes
propChangeNode.add(origNode);
//Process consequential changes
DefaultMutableTreeNode consequentialNode = encodeTree(ChangeType.CONSEQUENTIAL_CHANGE,propChange.getConsequentialChanges());
setNrConsequentialChanges(getNrConsequentialChanges()+consequentialNode.getChildCount());//Count the consequential changes
propChangeNode.add(consequentialNode);
return propChangeNode;
}
/**
* Sets the number of propagated changes
*
* @param nrPropagatedChanges The number of propagated changes
*/
protected void setNrPropagatedChanges(int nrPropagatedChanges) {
this.nrPropagatedChanges=nrPropagatedChanges;
}
/**
* Sets the number of original changes
*
* @param nrOriginalChanges The number of original changes
*/
protected void setNrOriginalChanges(int nrOriginalChanges) {
this.nrOriginalChanges=nrOriginalChanges;
}
/**
* Sets the number of consequential changes
*
* @param nrConsequentialChanges The number of consequential changes
*/
protected void setNrConsequentialChanges(int nrConsequentialChanges) {
this.nrConsequentialChanges=nrConsequentialChanges;
}
/**
* Gets the number of propagated changes
*
* @return The number of propagated changes
*/
public int getNrPropagatedChanges() {
return nrPropagatedChanges;
}
/**
* Gets the number of original changes
*
* @return The number of original changes
*/
public int getNrOriginalChanges() {
return nrOriginalChanges;
}
/**
* Gets the number of consequential changes
*
* @return The number of consequential changes
*/
public int getNrConsequentialChanges() {
return nrConsequentialChanges;
}
/**
* Creates the node that represent original changes or consequential changes.
* It calls a method that creates the child nodes representing eChanges
*
* @param changeType The type of change
* @param change The vitruvius change that gets encoded
* @return A TreeNode representing the given arguments
*/
private DefaultMutableTreeNode encodeTree(ChangeType changeType, VitruviusChange change) {
//Create the change-node
DefaultMutableTreeNode node=new DefaultMutableTreeNode();
//Walk all eChanges and create their sub-trees
for(EChange eChange:change.getEChanges()) {
encodeTree(eChange,node);
}
//Depending on the type of change and its echange-count, set the correct change node name
switch(changeType) {
case ORIGINAL_CHANGE:
node.setUserObject(ORIGINAL_CHANGE_STRING+(node.getChildCount()>1?"s":""));
break;
case CONSEQUENTIAL_CHANGE:
node.setUserObject(CONSEQUENTIAL_CHANGE_STRING+(node.getChildCount()>1?"s":""));
break;
default:
//this should never happens
throw new RuntimeException("Unknown change type : "+changeType);
}
return node;
}
/**
* Creates a node representing an eChange and the nodes for the eChanges structural features.
* Multiple feature processors are applied here before the new eChange node is added to the parentNode.
*
* @param eChange The eChange
* @param parentNode The parent node to add the new eChange node to
*/
private void encodeTree(EChange eChange, DefaultMutableTreeNode parentNode) {
//Create the eChange node
DefaultMutableTreeNode node=createEChangeNode(eChange);
Map featureName2index=new Hashtable();
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy