+package org.simantics.document.linking.ge;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+import java.util.Stack;\r
+\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.document.linking.ontology.DocumentLink;\r
+import org.simantics.document.linking.utils.SourceLinkUtil;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class FixAllReferencesAction implements ActionFactory {\r
+ \r
+ @Override\r
+ public Runnable create(final Object target) {\r
+ return new Runnable() {\r
+ \r
+ @Override\r
+ public void run() {\r
+ System.out.println(target);\r
+ try {\r
+ Pair<Collection<Resource>, Collection<Resource>> refs = Simantics.getSession().syncRequest(new FindFixable(target));\r
+ String dialogTitle = "Fix References";\r
+ String dialogMessage = "Fix " + refs.first.size() + " old references and " + refs.second.size() + " removed references?";\r
+ String dialogButtonLabels[] = new String[]{"Ok","Cancel"};\r
+ int defaultIndex = 0;\r
+ if (refs.first.size() == 0 && refs.second.size() == 0) {\r
+ dialogMessage = "Nothing to fix.";\r
+ dialogButtonLabels = new String[]{"OK"};\r
+ MessageDialog dialog = new MessageDialog(Display.getCurrent().getActiveShell(), dialogTitle, null, dialogMessage, MessageDialog.CONFIRM, dialogButtonLabels, defaultIndex);\r
+ dialog.open();\r
+ return;\r
+ }\r
+ MessageDialog dialog = new MessageDialog(Display.getCurrent().getActiveShell(), dialogTitle, null, dialogMessage, MessageDialog.CONFIRM, dialogButtonLabels, defaultIndex);\r
+ if (dialog.open() != 0)\r
+ return;\r
+ Simantics.getSession().markUndoPoint();\r
+ Simantics.getSession().syncRequest(new FixAll(refs));\r
+ } catch (DatabaseException e) {\r
+ ExceptionUtils.logAndShowError("Cannot fix references", e);\r
+ }\r
+ }\r
+ };\r
+ }\r
+ \r
+ public static class FindFixable implements Read<Pair<Collection<Resource>, Collection<Resource>>> {\r
+ \r
+ List<Resource> old;\r
+ List<Resource> removed;\r
+ Object target;\r
+ \r
+ public FindFixable(Object target) {\r
+ this.target = target;\r
+ }\r
+ \r
+ @Override\r
+ public Pair<Collection<Resource>, Collection<Resource>> perform(ReadGraph graph) throws DatabaseException {\r
+ old = new ArrayList<Resource>();\r
+ removed = new ArrayList<Resource>();\r
+ \r
+ DocumentLink sl = DocumentLink.getInstance(graph);\r
+ ModelChildRule modelChildRule = new ModelChildRule(graph, sl.ModelViewpointBrowseContext2_ChildRule);\r
+ Stack<Object> stack = new Stack<Object>();\r
+ stack.add(target);\r
+ while (!stack.isEmpty()) {\r
+ Object o = stack.pop();\r
+ @SuppressWarnings("unchecked")\r
+ Collection<Object> children = (Collection<Object>) modelChildRule.getChildren(graph, o);\r
+ \r
+ if (children.size() == 0) {\r
+ if (o instanceof Variable) {\r
+ Variable v = (Variable)o;\r
+ Resource r = v.getPossibleRepresents(graph);\r
+ process(graph, r);\r
+ } else if (o instanceof Resource) {\r
+ Resource r = (Resource)o;\r
+ process(graph, r);\r
+ }\r
+ } else {\r
+ stack.addAll(children);\r
+ }\r
+ \r
+ }\r
+ \r
+ Pair<Collection<Resource>, Collection<Resource>> result = new Pair<Collection<Resource>, Collection<Resource>>(old, removed);\r
+ old = null;\r
+ removed = null;\r
+ return result;\r
+ }\r
+ \r
+ void process(ReadGraph graph, Resource r) throws DatabaseException{\r
+ if (SourceLinkUtil.isValidSource(graph, r)) {\r
+ if (!SourceLinkUtil.isUpToDateSource(graph, r)) {\r
+ if (!old.contains(r))\r
+ old.add(r);\r
+ }\r
+ } else if (SourceLinkUtil.isSource(graph, r)){\r
+ if (!removed.contains(r))\r
+ removed.add(r);\r
+ }\r
+ }\r
+ }\r
+ \r
+ public static class FixAll extends WriteRequest {\r
+ Pair<Collection<Resource>, Collection<Resource>> refs;\r
+ \r
+ public FixAll(Pair<Collection<Resource>, Collection<Resource>> refs) {\r
+ super();\r
+ this.refs = refs;\r
+ }\r
+\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ Collection<Resource> old = refs.first;;\r
+ Collection<Resource> removed = refs.second;\r
+ \r
+ for (Resource r : old)\r
+ SourceLinkUtil.updateToLatest(graph, r);\r
+ for (Resource r : removed)\r
+ graph.deny(r);\r
+ }\r
+ }\r
+ \r
+ \r
+ public static class FixAllSilent extends WriteRequest {\r
+ Resource target;\r
+ \r
+ public FixAllSilent(Resource target) {\r
+ this.target = target;\r
+ }\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ // TODO: using ModelChildRule makes the data processing very slow.\r
+ DocumentLink sl = DocumentLink.getInstance(graph);\r
+ ModelChildRule modelChildRule = new ModelChildRule(graph, sl.ModelViewpointBrowseContext2_ChildRule);\r
+ Stack<Object> stack = new Stack<Object>();\r
+ stack.add(target);\r
+ while (!stack.isEmpty()) {\r
+ Object o = stack.pop();\r
+ @SuppressWarnings("unchecked")\r
+ Collection<Object> children = (Collection<Object>) modelChildRule.getChildren(graph, o);\r
+ \r
+ if (children.size() == 0) {\r
+ if (o instanceof Variable) {\r
+ Variable v = (Variable)o;\r
+ Resource r = v.getPossibleRepresents(graph);\r
+ process(graph, r);\r
+ } else if (o instanceof Resource) {\r
+ Resource r = (Resource)o;\r
+ process(graph, r);\r
+ }\r
+ } else {\r
+ stack.addAll(children);\r
+ }\r
+ \r
+ }\r
+ \r
+ }\r
+ \r
+ void process(WriteGraph graph, Resource r) throws DatabaseException{\r
+ if (SourceLinkUtil.isValidSource(graph, r))\r
+ SourceLinkUtil.updateToLatest(graph, r);\r
+ else\r
+ graph.deny(r);\r
+ }\r
+ }\r
+\r
+}\r