]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.ui/src/org/simantics/ui/WorkbenchWindowSessionContextProviderSource.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.ui / src / org / simantics / ui / WorkbenchWindowSessionContextProviderSource.java
diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/WorkbenchWindowSessionContextProviderSource.java b/bundles/org.simantics.ui/src/org/simantics/ui/WorkbenchWindowSessionContextProviderSource.java
new file mode 100644 (file)
index 0000000..94ccd29
--- /dev/null
@@ -0,0 +1,226 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 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
+ *******************************************************************************/\r
+package org.simantics.ui;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.concurrent.atomic.AtomicBoolean;\r
+\r
+import org.eclipse.ui.IWindowListener;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.IWorkbenchWindow;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.management.ISessionContextProvider;\r
+import org.simantics.db.management.ISessionContextProviderSource;\r
+import org.simantics.db.management.SessionContextProvider;\r
+import org.simantics.ui.internal.SessionUtils;\r
+\r
+/**\r
+ *\r
+ */\r
+public class WorkbenchWindowSessionContextProviderSource implements ISessionContextProviderSource, IWindowListener {\r
+\r
+    private static final boolean         DEBUG            = false;\r
+\r
+    ISessionContextProvider[]            ZERO             = new ISessionContextProvider[0];\r
+\r
+    Object                               temporaryContext = new Object() {\r
+        @Override\r
+        public String toString() {\r
+            return "Temporary Context Object";\r
+        }\r
+    };\r
+\r
+    /**\r
+     * The set of providers associated through\r
+     * {@link #put(Object, ISessionContextProvider)} for knowing which\r
+     * associations can be removed with {@link #remove(Object)}.\r
+     */\r
+    Set<Object>                          manualProviders  = new HashSet<Object>();\r
+\r
+    Map<Object, ISessionContextProvider> providers        = new HashMap<Object, ISessionContextProvider>();\r
+\r
+    ISessionContextProvider[]            allProviders     = ZERO;\r
+\r
+    IWorkbenchWindow                     activeWindow     = null;\r
+\r
+    ISessionContextProvider              activeProvider   = null;\r
+\r
+    AtomicBoolean                        isFirstWindow    = new AtomicBoolean(true);\r
+\r
+    public WorkbenchWindowSessionContextProviderSource(IWorkbench workbench) {\r
+        workbench.addWindowListener(this);\r
+\r
+        // Bind the initial context provider to a temporary object.\r
+        // This binding will be replaced later on when a workbench\r
+        // window is opened.\r
+        activeProvider = new SessionContextProvider(temporaryContext);\r
+        if (DEBUG)\r
+            System.out.println("Initial active session context provider: " + activeProvider);\r
+        addProvider(temporaryContext, activeProvider);\r
+    }\r
+\r
+    @Override\r
+    public ISessionContextProvider get(Object context) {\r
+        synchronized (providers) {\r
+            return providers.get(context);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ISessionContextProvider getActive() {\r
+        // activeWindow may be null at this time.\r
+        return activeProvider;\r
+    }\r
+\r
+    @Override\r
+    public ISessionContextProvider[] getAll() {\r
+        return allProviders;\r
+    }\r
+\r
+    @Override\r
+    public void put(Object context, ISessionContextProvider provider) {\r
+        synchronized (providers) {\r
+            ISessionContextProvider prev = providers.get(context);\r
+            if (prev != null)\r
+                throw new IllegalArgumentException("invalid context (" + context\r
+                        + "), a session context provider is already associated with this context: " + prev\r
+                        + ". Attempted to associate the context with this provider: " + provider);\r
+            providers.put(context, provider);\r
+            manualProviders.add(context);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ISessionContextProvider remove(Object context) {\r
+        synchronized (providers) {\r
+            if (!manualProviders.remove(context)) {\r
+                throw new IllegalArgumentException("specified context not found: " + context);\r
+            }\r
+            return providers.remove(context);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void windowActivated(IWorkbenchWindow window) {\r
+        if (DEBUG)\r
+            System.out.println("window activated: " + window);\r
+\r
+        boolean firstActiveWindow = (activeWindow == null);\r
+        activeWindow = window;\r
+        if (firstActiveWindow) {\r
+            // activeProvider should already be set.\r
+            assert activeProvider != null;\r
+            if (DEBUG)\r
+                System.out.println("  first window activation!");\r
+        } else {\r
+            synchronized (providers) {\r
+                activeProvider = providers.get(window);\r
+                if (activeProvider == null) {\r
+                    // This may be an issue, the context provider\r
+                    // should already have been created through\r
+                    // createContextForWindow(IWorkbenchWindow).\r
+                    activeProvider = new SessionContextProvider(window);\r
+                    addProvider(window, activeProvider);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void windowClosed(IWorkbenchWindow window) {\r
+        if (DEBUG)\r
+            System.out.println("window closed: " + window);\r
+        removeProvider(window);\r
+    }\r
+\r
+    @Override\r
+    public void windowDeactivated(IWorkbenchWindow window) {\r
+        if (DEBUG)\r
+            System.out.println("window deactivated: " + window);\r
+    }\r
+\r
+    @Override\r
+    public void windowOpened(IWorkbenchWindow window) {\r
+        if (DEBUG)\r
+            System.out.println("window opened: " + window + ", active window = " + activeWindow);\r
+    }\r
+\r
+    private void addProvider(Object context, ISessionContextProvider p) {\r
+        synchronized (providers) {\r
+            if (providers.put(context, p) != null) {\r
+                // This is a bug, should never happen.\r
+                throw new Error("Bug encountered, contact application support with stack trace.");\r
+            }\r
+            allProviders = providers.values().toArray(ZERO);\r
+        }\r
+    }\r
+\r
+    private void removeProvider(Object context) {\r
+        synchronized (providers) {\r
+            ISessionContextProvider provider = providers.remove(context);\r
+            if (provider == null) {\r
+                // This is a bug, should never happen.\r
+                throw new Error("Bug encountered, contact application support with stack trace.");\r
+            }\r
+            allProviders = providers.values().toArray(ZERO);\r
+\r
+            // Make sure that any session remaining in the removed context will\r
+            // be disposed of eventually.\r
+            ISessionContext ctx = provider.getSessionContext();\r
+            if (ctx != null) {\r
+                if (!SimanticsUI.isInUse(ctx)) {\r
+                    SessionUtils.releaseUnusedSessionAfterHoldTime(ctx);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This is a purely internal mechanism to allow proper creation of context\r
+     * providers for workbench windows as early as possible during the workbench\r
+     * window construction process, i.e. in the\r
+     * <code>WorkbenchWindowAdvisor.preWindowOpen()</code> instantiated\r
+     * by <code>WorkbenchAdvisor</code>.\r
+     * \r
+     * @param context\r
+     */\r
+    public void createProviderForWindow(IWorkbenchWindow context) {\r
+        synchronized (providers) {\r
+            if (isFirstWindow.compareAndSet(true, false)) {\r
+                assert activeProvider != null;\r
+                if (DEBUG)\r
+                    System.out.println("[Create Context] first window: " + context);\r
+\r
+                SessionContextProvider v = (SessionContextProvider) providers.remove(temporaryContext);\r
+                if (v != null) {\r
+                    v.setHandle(context);\r
+                    providers.put(context, v);\r
+                    if (DEBUG)\r
+                        System.out.println("  rebound: '" + v + "' to '" + context + "'");\r
+                }\r
+            } else {\r
+                if (DEBUG)\r
+                    System.out.println("[Create Context] new window: " + context);\r
+                // Create new session context provider\r
+                SessionContextProvider v = new SessionContextProvider(context);\r
+                ISessionContextProvider active = getActive();\r
+                if (active != null)\r
+                    v.setSessionContext(active.getSessionContext());\r
+                addProvider(context, v);\r
+            }\r
+        }\r
+    }\r
+\r
+}\r