X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.ui%2Fsrc%2Forg%2Fsimantics%2Fui%2Fworkbench%2FResourceEditorSupport.java;h=3597804d8f83164637e8f0b5e60e44c9879d25c2;hp=54a697a72422d191f601dd537ae6031ae5d78dbc;hb=e88be95edf1f80781646cfdf717ec1b663264179;hpb=0ae2b770234dfc3cbb18bd38f324125cf0faca07 diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorSupport.java b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorSupport.java index 54a697a72..3597804d8 100644 --- a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorSupport.java +++ b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorSupport.java @@ -17,23 +17,24 @@ import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; +import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Session; import org.simantics.db.common.procedure.adapter.ListenerAdapter; import org.simantics.db.common.request.ParametrizedRead; -import org.simantics.db.common.request.UnaryRead; +import org.simantics.db.common.request.UniqueRead; import org.simantics.db.event.ChangeEvent; import org.simantics.db.event.ChangeListener; import org.simantics.db.exception.DatabaseException; import org.simantics.db.management.ISessionContext; import org.simantics.db.management.ISessionContextProvider; -import org.simantics.db.request.Read; import org.simantics.db.service.GraphChangeListenerSupport; -import org.simantics.ui.SimanticsUI; import org.simantics.utils.datastructures.map.Tuple; import org.simantics.utils.ui.ExceptionUtils; import org.simantics.utils.ui.SWTUtils; import org.simantics.utils.ui.workbench.WorkbenchUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A helper class for easing the attachment of a Simantics database session to @@ -50,6 +51,9 @@ import org.simantics.utils.ui.workbench.WorkbenchUtils; */ public class ResourceEditorSupport implements IAdaptable, ChangeListener { + private static final Logger LOGGER = LoggerFactory.getLogger(ResourceEditorSupport.class); + private static final boolean DEBUG = false; + private IEditorPart editorPart; private ChangeListener editorPartChangeListener; @@ -87,7 +91,7 @@ public class ResourceEditorSupport implements IAdaptable, ChangeListener { private ISessionContext initSession() throws PartInitException { if (sessionContext == null) { - ISessionContextProvider provider = SimanticsUI.getSessionContextProvider(); + ISessionContextProvider provider = Simantics.getSessionContextProvider(); ISessionContext sc = provider.getSessionContext(); if (sc == null) throw new PartInitException("active database session context is null"); @@ -152,7 +156,7 @@ public class ResourceEditorSupport implements IAdaptable, ChangeListener { return; inputListener = new InputListener(); - getSession().asyncRequest(validationRequest(editorPart), inputListener); + getSession().asyncRequest(new ValidationRequest(), inputListener); } public synchronized void deactivateValidation() { @@ -161,6 +165,7 @@ public class ResourceEditorSupport implements IAdaptable, ChangeListener { if (inputListener == null) return; inputListener.dispose(); + inputListener = null; } public ISessionContext getSessionContext() { @@ -175,19 +180,18 @@ public class ResourceEditorSupport implements IAdaptable, ChangeListener { return session; } - @SuppressWarnings("rawtypes") + @SuppressWarnings("unchecked") @Override - public Object getAdapter(Class adapter) { + public T getAdapter(Class adapter) { if (adapter == ISessionContext.class) - return getSessionContext(); + return (T) getSessionContext(); if (adapter == Session.class) - return getSession(); + return (T) getSession(); return null; } @Override public void graphChanged(ChangeEvent e) throws DatabaseException { - //System.out.println(this + ": graph change: " + e); // Only forward the update to the editor if the input is still valid and // the editor implements ChangeListener if (editorPart instanceof ChangeListener) @@ -225,44 +229,55 @@ public class ResourceEditorSupport implements IAdaptable, ChangeListener { } /** - * @param input - * @return a read request that returns true for valid inputs - * and false for non-existent or invalid inputs. + * A read request that returns an {@link Evaluation} of the current state of + * editorPart. + * + *

+ * This request class is not static but has no parameters that could get + * stuck in the database client caches. UniqueRead does not need arguments + * and without custom hashCode/equals implementations, each instance of this + * request is a different one. This is exactly the behaviour we want in this + * case. */ - private Read validationRequest(IEditorPart editorPart) { - return new UnaryRead(editorPart) { - @Override - public Evaluation perform(ReadGraph graph) throws DatabaseException { - IEditorInput input = parameter.getEditorInput(); - IResourceEditorInput resourceInput = getResourceInput(parameter); - - //System.out.println(ResourceEditorSupport.this + ": checking input " + input); - - boolean exists = true; - boolean valid = true; - if (resourceInput != null) { - exists = resourceInput.exists(graph); - if (exists && inputValidator != null) { - valid = graph.syncRequest(inputValidator.get(resourceInput)); - } - } else { - exists = input.exists(); + private class ValidationRequest extends UniqueRead { + @Override + public Evaluation perform(ReadGraph graph) throws DatabaseException { + IEditorPart part = editorPart; + if (part == null) + return new Evaluation(null, null, InputState.INVALID, "", ""); + + IEditorInput input = part.getEditorInput(); + IResourceEditorInput resourceInput = getResourceInput(part); + + if (DEBUG) + LOGGER.trace("ValidationRequest: checking input " + input); + + boolean exists = true; + boolean valid = true; + if (resourceInput != null) { + exists = resourceInput.exists(graph); + if (exists && inputValidator != null) { + valid = graph.syncRequest(inputValidator.get(resourceInput)); } + } else { + exists = input.exists(); + } - InputState state = InputState.parse(exists, valid); - if (state == InputState.VALID) { - // Make sure any cached data in the editor input is up-to-date. + InputState state = InputState.parse(exists, valid); + if (state == InputState.VALID) { + // Make sure any cached data in the editor input is up-to-date. + if (resourceInput != null) resourceInput.update(graph); - } - - Evaluation eval = new Evaluation(parameter, input, state, input.getName(), input.getToolTipText()); - //System.out.println(ResourceEditorSupport.this + ": validation evaluation: " + eval); - return eval; } - }; + + Evaluation eval = new Evaluation(part, input, state, input.getName(), input.getToolTipText()); + if (DEBUG) + LOGGER.trace("ValidationRequest: evaluation result: " + eval); + return eval; + } } - private class InputListener extends ListenerAdapter { + private static class InputListener extends ListenerAdapter { private boolean disposed = false; @@ -272,11 +287,11 @@ public class ResourceEditorSupport implements IAdaptable, ChangeListener { @Override public void execute(Evaluation evaluation) { - //System.out.println("InputListener: " + evaluation); + if (DEBUG) + LOGGER.trace("InputListener: " + evaluation); switch (evaluation.getInputState()) { case VALID: break; - case INVALID: case NON_EXISTENT: scheduleEditorClose(evaluation.getEditorPart()); @@ -291,18 +306,17 @@ public class ResourceEditorSupport implements IAdaptable, ChangeListener { @Override public boolean isDisposed() { - return disposed || ResourceEditorSupport.this.isDisposed(); + return disposed; } } - private void scheduleEditorClose(final IEditorPart editorPart) { - SWTUtils.asyncExec(editorPart.getSite().getShell(), new Runnable() { - @Override - public void run() { - // Don't have to check isDisposed since closeEditor - // will ignore already closed editor parts. - WorkbenchUtils.closeEditor(editorPart, false); - } + private static void scheduleEditorClose(IEditorPart editorPart) { + if (editorPart == null) + return; + SWTUtils.asyncExec(editorPart.getSite().getWorkbenchWindow().getShell(), () -> { + // Don't have to check isDisposed since closeEditor + // will ignore already closed editor parts. + WorkbenchUtils.closeEditor(editorPart, false); }); }