import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
+import org.simantics.Simantics;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.Session;
import org.simantics.db.WriteGraph;
import org.simantics.db.common.request.WriteRequest;
import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.exception.DoesNotContainValueException;
-import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
-import org.simantics.db.exception.ServiceException;
-import org.simantics.db.layer0.util.Layer0Utils;
import org.simantics.db.request.Read;
import org.simantics.interop.test.GraphChanges;
-import org.simantics.interop.test.GraphComparator;
import org.simantics.interop.update.Activator;
+import org.simantics.interop.update.model.ModelUpdate;
+import org.simantics.interop.update.model.ModelUpdate.WarningListener;
+import org.simantics.interop.update.model.PropertyChange;
+import org.simantics.interop.update.model.UpdateList;
import org.simantics.interop.update.model.UpdateNode;
-import org.simantics.interop.update.model.UpdateNode.Status;
import org.simantics.interop.update.model.UpdateOp;
+import org.simantics.interop.update.model.UpdateStatus;
import org.simantics.interop.update.model.UpdateTree;
import org.simantics.interop.utils.TableUtils;
-import org.simantics.ui.SimanticsUI;
-import org.simantics.utils.datastructures.Callback;
import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.ui.ExceptionUtils;
* @author Marko Luukkainen <marko.luukkainen@vtt.fi>
*
*/
-public abstract class ModelUpdateEditor extends Composite{
+public abstract class ModelUpdateEditor extends Composite implements WarningListener{
private Composite errorComposite;
private CheckboxTreeViewer changeBrowser;
private TableViewer changeViewer;
- private GraphChanges changes;
- private UpdateTree updateTree;
-
private Button updateAllButton;
private Button updateSelectedButton;
private Color containsColor;
private Color deletedColor;
private Color addedColor;
+ private Color disabledColor;
+
+ private ModelUpdate update;
- private HashSet<Pair<Statement, Statement>> selected = new HashSet<Pair<Statement,Statement>>();
private HashSet<UpdateNode> selectedStructure = new HashSet<UpdateNode>();
- private List<ChangeFilter> filters = new ArrayList<ChangeFilter>();
-
public ModelUpdateEditor(Composite parent) {
super(parent,SWT.NONE);
checked = manager.createImage(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/tick.png"));
unchecked = manager.createImage(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/cross.png"));
+ unchecked = manager.createImage(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/cross.png"));
warning = manager.createImage(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/error.png"));
containsColor = new Color(parent.getDisplay(), new RGB(255,255,220));
deletedColor = new Color(parent.getDisplay(), new RGB(255,220,220));
addedColor = new Color(parent.getDisplay(), new RGB(220,255,220));
+ disabledColor = new Color(parent.getDisplay(), new RGB(128,128,128));
this.setLayout(new GridLayout(1,false));
changeViewer.setUseHashlookup(true);
- TableViewerColumn selection = TableUtils.addColumn(changeViewer, getColumntTitle(0), false, false, 20);
- TableViewerColumn diagram = TableUtils.addColumn(changeViewer, getColumntTitle(1), true, true, 100);
- TableViewerColumn symbol = TableUtils.addColumn(changeViewer, getColumntTitle(2), true, true, 100);
- TableViewerColumn property = TableUtils.addColumn(changeViewer, getColumntTitle(3), true, true, 100);
- TableViewerColumn oldValue = TableUtils.addColumn(changeViewer, getColumntTitle(4), true, true, 100);
- TableViewerColumn newValue = TableUtils.addColumn(changeViewer, getColumntTitle(5), true, true, 100);
-
- diagram.setLabelProvider(getLabelProvider(1));
- symbol.setLabelProvider(getLabelProvider(2));
- property.setLabelProvider(getLabelProvider(3));
- oldValue.setLabelProvider(getLabelProvider(4));
- newValue.setLabelProvider(getLabelProvider(5));
+ TableViewerColumn cols[] = new TableViewerColumn[getChangeListColumnCount()];
+ TableViewerColumn selection = TableUtils.addColumn(changeViewer, getColumntTitle(0), false, false, getChangeListColumnWidth(0));
+ cols[0] = selection;
+ for (int i = 1 ; i < getChangeListColumnCount(); i++) {
+ TableViewerColumn column = TableUtils.addColumn(changeViewer, getColumntTitle(i), true, getChangeListColumnSortable(i), getChangeListColumnWidth(i));
+ cols[i] = column;
+ column.setLabelProvider(getLabelProvider(i));
+ configureChangeListColumn(i, column);
+ }
- selection.setLabelProvider(new SelectionLabelProvider(selected));
+ selection.setLabelProvider(new SelectionLabelProvider());
selection.getColumn().addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- if (changes.getModifications().size() > 0) {
- if (selected.contains(changes.getModifications().get(0))) {
- for (Pair<Statement, Statement> nr : changes.getModifications())
- selected.remove(nr);
+ if (update.getUpdateList().getChanges().size() > 0) {
+ if (update.getUpdateList().getSelected().size() > 0) {
+ update.getUpdateList().clearSelected();
} else {
- for (Pair<Statement, Statement> nr : changes.getModifications())
- selected.add(nr);
+ for (PropertyChange nr : update.getUpdateList().getChanges())
+ nr.select(true);
}
changeViewer.refresh();
}
}
});
- selection.setEditingSupport(new SelectionEditingSupport(changeViewer, selected));
+ selection.setEditingSupport(new SelectionEditingSupport(changeViewer));
}
Composite buttonComposite = new Composite(this, SWT.NONE);
});
}
+ protected int getChangeListColumnCount() {
+ return 6;
+ }
+
+ protected int getChangeListColumnWidth(int col) {
+ if (col == 0)
+ return 20;
+ return 100;
+ }
+
+ protected boolean getChangeListColumnSortable(int col) {
+ if (col == 0)
+ return false;
+ return true;
+ }
+
+ protected void configureChangeListColumn(int col, TableViewerColumn column) {
+
+ }
+
protected Session getSession() {
- return SimanticsUI.getSession();
+ return Simantics.getSession();
}
protected String getColumntTitle(int i) {
}
protected abstract ColumnLabelProvider getLabelProvider(int i);
- protected abstract Pair<GraphComparator,Boolean> getChanges(Resource r1, Resource r2) throws DatabaseException;
- protected abstract UpdateTree getUpdateTree(GraphChanges changes) throws DatabaseException;
-
- protected void addFilters(List<ChangeFilter> filters) {
-
- }
public GraphChanges getChanges() {
- return changes;
+ return update.getChanges();
}
public UpdateTree getUpdateTree() {
- return updateTree;
+ return update.getUpdateTree();
+ }
+
+ public UpdateList getUpdateList() {
+ return update.getUpdateList();
}
public CheckboxTreeViewer getChangeBrowser() {
return changeViewer;
}
- private void showWarning(String text) {
+ public void showWarning(ModelUpdate update, String text) {
errorComposite.setVisible(true);
Label label = new Label(errorComposite, SWT.NONE);
public void refreshChecked() {
Stack<UpdateNode> nodeStack = new Stack<UpdateNode>();
- nodeStack.push((UpdateNode)updateTree.getRootNode());
+ nodeStack.push((UpdateNode)update.getUpdateTree().getRootNode());
while (!nodeStack.isEmpty()) {
UpdateNode n = nodeStack.pop();
if (n.getOp() != null) {
UpdateOp op = n.getOp();
- if (!op.isAdd() && !op.isDelete()) {
+ if (!op.isChange()) {
changeBrowser.setGrayed(n, true);
changeBrowser.setChecked(n, true);
} else {
selectedStructure.remove(n);
}
changeBrowser.setChecked(n, sel);
- changeBrowser.setGrayed(n, false);
+ changeBrowser.setGrayed(n, !op.enabled());
}
}
} else {
for (ICheckStateListener l : checkStateListeners) {
l.checkStateChanged(new CheckStateChangedEvent(changeBrowser, null, false));
}
+ changeViewer.refresh();
}
+ protected abstract ModelUpdate createUpdate();
+
public void load(UpdateEditorInput uei) {
-
- addFilters(filters);
-
- Resource r1 = uei.getR1();
- Resource r2 = uei.getR2();
-
+ Resource oldModel = uei.getR1(); // old model that is being updated, contains user made changes
+ Resource newModel = uei.getR2(); // new model,
+ Resource originalModel = uei.getR3(); // original old model without user made changes
+ boolean newDistinct = uei.isNewDistinct();
try {
-
- Pair<GraphComparator,Boolean> result = getChanges(r1,r2);
- GraphComparator comparator = result.first;
- if (result.second)
- showWarning("Structural symbols have been changed. Model update is not able to update these, please create a new model.");
- comparator.test(getSession());
- changes = comparator.getChanges();
- changes = getSession().syncRequest(new FilterChangesRead(changes));
- updateTree = getUpdateTree(changes);
+ if (update != null)
+ update.removeListener(this);
+ update = createUpdate();
+ update.addListener(this);
+ update.setInput(oldModel, newModel, originalModel, newDistinct);
} catch (DatabaseException e) {
Text text = new Text(this, SWT.MULTI);
text.setText(e.getMessage());
return;
}
-
-
- changeViewer.setInput(changes.getModifications());
- changeBrowser.setInput(updateTree);
+ setInputs();
+
refreshChecked();
}
-
+ protected void setInputs() {
+ changeViewer.setInput(update.getUpdateList().getChanges());
+ changeBrowser.setInput(update.getUpdateTree());
+ updateAllButton.setEnabled(true);
+ updateSelectedButton.setEnabled(true);
+ }
private void applyAll() {
updateAllButton.setEnabled(false);
getSession().asyncRequest(new WriteRequest(){
@Override
public void perform(WriteGraph graph) throws DatabaseException {
- Layer0Utils.addCommentMetadata(graph, "Apply all model updates");
- graph.markUndoPoint();
- for (Pair<Statement, Statement> mod : changes.getModifications()) {
- applyLiteralChange(graph, mod);
- }
- selected.clear();
- changes.getModifications().clear();
-
- updateTree.getUpdateOps().applyAll(graph);
+ update.applyAll(graph);
Display.getDefault().asyncExec(new Runnable() {
}
- }, new Callback<DatabaseException>() {
- @Override
- public void run(DatabaseException parameter) {
- if (parameter != null)
- ExceptionUtils.logAndShowError("Cannot update model", parameter);
- }
+ }, e -> {
+ if (e != null)
+ ExceptionUtils.logAndShowError("Cannot update model", e);
});
}
- private void applyLiteralChange(WriteGraph graph, Pair<Statement, Statement> mod) throws DoesNotContainValueException, ServiceException, ManyObjectsForFunctionalRelationException {
-
- Resource s = changes.getComparable().getLeft(mod.second.getSubject());
- Resource pred = mod.first.getPredicate();
- if (graph.hasValue(mod.second.getObject())) {
- Object value = graph.getValue(mod.second.getObject());
- graph.claimLiteral(s, pred, value);
- } else {
- graph.deny(s,pred);
- }
-
-
- }
-
private void applySelected() {
updateAllButton.setEnabled(false);
updateSelectedButton.setEnabled(false);
getSession().asyncRequest(new WriteRequest(){
@Override
public void perform(WriteGraph graph) throws DatabaseException {
- Layer0Utils.addCommentMetadata(graph, "Apply selected model updates");
- graph.markUndoPoint();
- for (Pair<Statement, Statement> mod : selected) {
- changes.getModifications().remove(mod);
- applyLiteralChange(graph, mod);
- }
- selected.clear();
-
- updateTree.getUpdateOps().applySelected(graph);
+ update.applySelected(graph);
Display.getDefault().asyncExec(new Runnable() {
});
}
});
- }
-
-
- /**
- * Filters changes:
- * 1. Changes that are not essential for model update (changes that can be found when the models are axcatly the same)
- * 2. Runs custom filters for value changes.
- *
- * @param g
- * @param changes
- * @return
- * @throws DatabaseException
- */
- protected GraphChanges filterChanges(ReadGraph g, GraphChanges changes) throws DatabaseException
- {
-
- List<Pair<Statement,Statement>> modifications = new ArrayList<Pair<Statement,Statement>>();
-
- for (Pair<Statement, Statement> mod : changes.getModifications()) {
-
- boolean accept = true;
- for (ChangeFilter filter : filters) {
- if (!filter.accept(g, mod)) {
- accept = false;
- break;
- }
- }
- if (accept)
- modifications.add(mod);
- }
- GraphChanges newChanges = new GraphChanges(changes.getResource1(),changes.getResource2(),changes.getDeletions(), changes.getAdditions(), modifications, changes.getComparable());
- return newChanges;
- }
-
- public interface ChangeFilter {
- public boolean accept(ReadGraph g, Pair<Statement, Statement> change) throws DatabaseException;
- }
-
-
-
-
- /**
- *
- * Filters floating point value changes (default filter is set filter when the change is less than 1%)
- *
- */
- protected class FPValueFilter implements ChangeFilter {
-
- private double percentage = 0.01;
-
- public FPValueFilter() {
-
- }
-
- public FPValueFilter(double percentage) {
- if (percentage < 0.0 || percentage > 1.0)
- throw new IllegalArgumentException("Percentage must be between 0.0 and 1.0.");
- this.percentage = percentage;
- }
-
- @Override
- public boolean accept(ReadGraph g, Pair<Statement, Statement> change) throws DatabaseException {
- //filter floating point values that have less than 1% difference.
- if (!g.hasValue(change.first.getObject()) || !g.hasValue(change.second.getObject()))
- return true;
- Object v1 = g.getValue(change.first.getObject());
- Object v2 = g.getValue(change.second.getObject());
-
- if (v1 instanceof Double && v2 instanceof Double) {
- double d1 = (Double)v1;
- double d2 = (Double)v2;
- if (Math.abs(d1-d2) / Math.max(Math.abs(d1), Math.abs(d2)) < percentage)
- return false;
- } else if (v1 instanceof Float && v2 instanceof Float) {
- float d1 = (Float)v1;
- float d2 = (Float)v2;
- if (Math.abs(d1-d2) / Math.max(Math.abs(d1), Math.abs(d2)) < percentage)
- return false;
- }
-
- return true;
- }
- }
-
-
- private class FilterChangesRead implements Read<GraphChanges> {
- private GraphChanges changes;
- public FilterChangesRead(GraphChanges changes) {
- this.changes = changes;
- }
-
- @Override
- public GraphChanges perform(ReadGraph graph) throws DatabaseException {
- return filterChanges(graph, changes);
- }
- }
-
+ }
private class ModificationListContentProvider implements IStructuredContentProvider {
private class SelectionLabelProvider extends ColumnLabelProvider {
- Collection<?> selected;
- public SelectionLabelProvider(Collection<?> selected) {
- this.selected = selected;
+ public SelectionLabelProvider() {
+
}
@Override
public String getText(Object element) {
@Override
public Image getImage(Object element) {
- if (selected.contains(element))
+ if (update == null || !update.isInit())
+ return null;
+ PropertyChange pc = (PropertyChange)element;
+ if (pc.applied())
+ return null;
+ if (pc.selected())
return checked;
else
return unchecked;
}
+
+ @Override
+ public Color getForeground(Object element) {
+ PropertyChange pc = (PropertyChange)element;
+ if (!pc.enabled())
+ return disabledColor;
+ return null;
+ }
+ }
+
+ protected abstract class PropertyChangeLabelProvider extends ColumnLabelProvider {
+
+ public PropertyChangeLabelProvider() {
+
+ }
+
+ @Override
+ public Color getForeground(Object element) {
+ PropertyChange pc = (PropertyChange)element;
+ if (!pc.enabled())
+ return disabledColor;
+ return null;
+ }
}
private class UpdateNodeLabelProvider extends ColumnLabelProvider {
@Override
public String getText(Object element) {
final UpdateNode node = (UpdateNode)element;
- try {
- return getSession().syncRequest(new Read<String>() {
- @Override
- public String perform(ReadGraph graph) throws DatabaseException {
- return node.getLabel(graph);
- }
- });
- } catch (Exception e) {
- return e.getMessage();
- }
+ return node.getLabel();
}
@Override
@Override
public Color getBackground(Object element) {
final UpdateNode node = (UpdateNode)element;
- Status status = node.getStatus();
- if (status == Status.CONTAINS)
+ UpdateStatus status = node.getStatus();
+ if (status == UpdateStatus.CONTAINS)
return containsColor;
- if (status == Status.DELETED)
+ if (status == UpdateStatus.DELETED)
return deletedColor;
- if (status == Status.NEW)
+ if (status == UpdateStatus.NEW)
return addedColor;
return null;
}
+
+ @Override
+ public Color getForeground(Object element) {
+ final UpdateNode node = (UpdateNode)element;
+ if (node.getOp() != null && !node.getOp().enabled())
+ return disabledColor;
+ return null;
+ }
}
private class SelectionEditingSupport extends EditingSupport {
- @SuppressWarnings("rawtypes")
- Collection selected;
-
- @SuppressWarnings("rawtypes")
- public SelectionEditingSupport(ColumnViewer viewer, Collection selected) {
+ public SelectionEditingSupport(ColumnViewer viewer) {
super(viewer);
- this.selected = selected;
-
}
@Override
@Override
protected Object getValue(Object element) {
- return selected.contains(element);
+ if (update == null || !update.isInit())
+ return false;
+ PropertyChange pc = (PropertyChange)element;
+ return pc.selected();
}
- @SuppressWarnings("unchecked")
@Override
protected void setValue(Object element, Object value) {
+ if (update == null || !update.isInit())
+ return;
+ PropertyChange pc = (PropertyChange)element;
if (Boolean.TRUE.equals(value))
- selected.add(element);
+ pc.select(true);
else
- selected.remove(element);
+ pc.select(false);
getViewer().refresh(element);
}