]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.ui/src/org/simantics/ui/workbench/e4/E4ResourceEditorSupport.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.ui / src / org / simantics / ui / workbench / e4 / E4ResourceEditorSupport.java
diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/e4/E4ResourceEditorSupport.java b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/e4/E4ResourceEditorSupport.java
new file mode 100644 (file)
index 0000000..77716f9
--- /dev/null
@@ -0,0 +1,170 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2013 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *     Semantum Oy - issue #4384\r
+ *******************************************************************************/\r
+package org.simantics.ui.workbench.e4;\r
+\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.procedure.adapter.ListenerAdapter;\r
+import org.simantics.db.common.request.ParametrizedRead;\r
+import org.simantics.db.common.request.TernaryRead;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.ui.workbench.IResourceEditorInput;\r
+import org.simantics.utils.datastructures.map.Tuple;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+import org.simantics.utils.ui.SWTUtils;\r
+\r
+/**\r
+ * A helper class for adding input validation and reaction to input invalidation\r
+ * to an E4 (editor) part that uses Simantics database {@link Resource}s as its\r
+ * input.\r
+ * \r
+ * <p>\r
+ * Only useful with E4ResourceEditorBase extending part implementations.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class E4ResourceEditorSupport {\r
+\r
+    private E4ResourceEditorBase editor;\r
+\r
+    private ParametrizedRead<IResourceEditorInput, Boolean> inputValidator;\r
+\r
+    private InputListener inputListener;\r
+\r
+    public E4ResourceEditorSupport(E4ResourceEditorBase editor) {\r
+        this(editor, null);\r
+    }\r
+\r
+    public E4ResourceEditorSupport(E4ResourceEditorBase editor, ParametrizedRead<IResourceEditorInput, Boolean> inputValidator) {\r
+        this.editor = editor;\r
+        this.inputValidator = inputValidator;\r
+    }\r
+\r
+    public void dispose() {\r
+        deactivateValidation();\r
+        inputValidator = null;\r
+        editor = null;\r
+    }\r
+\r
+    protected boolean isDisposed() {\r
+        return editor == null;\r
+    }\r
+\r
+    public synchronized void activateValidation() {\r
+        if (isDisposed())\r
+            throw new IllegalStateException(this + " is disposed");\r
+        if (inputListener != null)\r
+            return;\r
+\r
+        E4ResourceEditorBase e = editor;\r
+        inputListener = new InputListener();\r
+        Simantics.getSession().asyncRequest(new InputEvaluator(e.getPart().getElementId(), e.getResourceInput(), inputValidator), inputListener);\r
+    }\r
+\r
+    public synchronized void deactivateValidation() {\r
+        if (isDisposed())\r
+            throw new IllegalStateException(this + " is disposed");\r
+        if (inputListener == null)\r
+            return;\r
+        inputListener.dispose();\r
+    }\r
+\r
+    static enum InputState {\r
+        VALID,\r
+        INVALID,\r
+        NON_EXISTENT;\r
+\r
+        public static InputState parse(boolean exists, boolean valid) {\r
+            if (!exists)\r
+                return NON_EXISTENT;\r
+            return valid ? VALID : INVALID;\r
+        }\r
+    }\r
+\r
+    static class Evaluation extends Tuple {\r
+        public Evaluation(String editorElementId, InputState state) {\r
+            super(editorElementId, state);\r
+        }\r
+\r
+        public String getEditorElementId() {\r
+            return (String) getField(0);\r
+        }\r
+\r
+        public InputState getInputState() {\r
+            return (InputState) getField(1);\r
+        }\r
+    }\r
+\r
+    public static class InputEvaluator extends TernaryRead<String, IResourceEditorInput, ParametrizedRead<IResourceEditorInput, Boolean>, Evaluation> {\r
+\r
+        public InputEvaluator(String editorElementId, IResourceEditorInput input, ParametrizedRead<IResourceEditorInput, Boolean> inputValidator) {\r
+            super(editorElementId, input, inputValidator);\r
+        }\r
+\r
+        @Override\r
+        public Evaluation perform(ReadGraph graph) throws DatabaseException {\r
+            //System.out.println(this + ": checking input " + parameter + ", " + parameter2);\r
+            IResourceEditorInput i = parameter2;\r
+            boolean exists = i.exists(graph);\r
+            boolean valid = exists && parameter3 != null\r
+                    ? graph.syncRequest(parameter3.get(i))\r
+                    : exists;\r
+            InputState state = InputState.parse(exists, valid);\r
+            Evaluation eval = new Evaluation(parameter, state);\r
+            //System.out.println(this + ": validation evaluation: " + eval);\r
+            return eval;\r
+        }\r
+    }\r
+\r
+    private static class InputListener extends ListenerAdapter<Evaluation> {\r
+\r
+        private boolean disposed = false;\r
+\r
+        public void dispose() {\r
+            disposed = true;\r
+        }\r
+\r
+        @Override\r
+        public void execute(Evaluation evaluation) {\r
+            //System.out.println("InputListener: " + evaluation);\r
+            switch (evaluation.getInputState()) {\r
+                case VALID:\r
+                    break;\r
+\r
+                case INVALID:\r
+                case NON_EXISTENT:\r
+                    scheduleEditorClose(evaluation.getEditorElementId());\r
+                    break;\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void exception(Throwable t) {\r
+            ExceptionUtils.logError("E4ResourceEditorSupport.InputListener received an unexpected exception.", t);\r
+        }\r
+\r
+        @Override\r
+        public boolean isDisposed() {\r
+            return disposed;\r
+        }\r
+    }\r
+\r
+    private static void scheduleEditorClose(String editorElementId) {\r
+        SWTUtils.asyncExec(PlatformUI.getWorkbench().getDisplay(), () -> {\r
+            E4WorkbenchUtils.closeEditor(editorElementId);\r
+        });\r
+    }\r
+\r
+}\r