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