1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.ui;
14 import java.util.HashMap;
15 import java.util.HashSet;
18 import java.util.concurrent.atomic.AtomicBoolean;
20 import org.eclipse.ui.IWindowListener;
21 import org.eclipse.ui.IWorkbench;
22 import org.eclipse.ui.IWorkbenchWindow;
23 import org.simantics.db.management.ISessionContext;
24 import org.simantics.db.management.ISessionContextProvider;
25 import org.simantics.db.management.ISessionContextProviderSource;
26 import org.simantics.db.management.SessionContextProvider;
27 import org.simantics.ui.internal.SessionUtils;
32 public class WorkbenchWindowSessionContextProviderSource implements ISessionContextProviderSource, IWindowListener {
34 private static final boolean DEBUG = false;
36 ISessionContextProvider[] ZERO = new ISessionContextProvider[0];
38 Object temporaryContext = new Object() {
40 public String toString() {
41 return "Temporary Context Object";
46 * The set of providers associated through
47 * {@link #put(Object, ISessionContextProvider)} for knowing which
48 * associations can be removed with {@link #remove(Object)}.
50 Set<Object> manualProviders = new HashSet<Object>();
52 Map<Object, ISessionContextProvider> providers = new HashMap<Object, ISessionContextProvider>();
54 ISessionContextProvider[] allProviders = ZERO;
56 IWorkbenchWindow activeWindow = null;
58 ISessionContextProvider activeProvider = null;
60 AtomicBoolean isFirstWindow = new AtomicBoolean(true);
62 public WorkbenchWindowSessionContextProviderSource(IWorkbench workbench) {
63 workbench.addWindowListener(this);
65 // Bind the initial context provider to a temporary object.
66 // This binding will be replaced later on when a workbench
68 activeProvider = new SessionContextProvider(temporaryContext);
70 System.out.println("Initial active session context provider: " + activeProvider);
71 addProvider(temporaryContext, activeProvider);
75 public ISessionContextProvider get(Object context) {
76 synchronized (providers) {
77 return providers.get(context);
82 public ISessionContextProvider getActive() {
83 // activeWindow may be null at this time.
84 return activeProvider;
88 public ISessionContextProvider[] getAll() {
93 public void put(Object context, ISessionContextProvider provider) {
94 synchronized (providers) {
95 ISessionContextProvider prev = providers.get(context);
97 throw new IllegalArgumentException("invalid context (" + context
98 + "), a session context provider is already associated with this context: " + prev
99 + ". Attempted to associate the context with this provider: " + provider);
100 providers.put(context, provider);
101 manualProviders.add(context);
106 public ISessionContextProvider remove(Object context) {
107 synchronized (providers) {
108 if (!manualProviders.remove(context)) {
109 throw new IllegalArgumentException("specified context not found: " + context);
111 return providers.remove(context);
116 public void windowActivated(IWorkbenchWindow window) {
118 System.out.println("window activated: " + window);
120 boolean firstActiveWindow = (activeWindow == null);
121 activeWindow = window;
122 if (firstActiveWindow) {
123 // activeProvider should already be set.
124 assert activeProvider != null;
126 System.out.println(" first window activation!");
128 synchronized (providers) {
129 activeProvider = providers.get(window);
130 if (activeProvider == null) {
131 // This may be an issue, the context provider
132 // should already have been created through
133 // createContextForWindow(IWorkbenchWindow).
134 activeProvider = new SessionContextProvider(window);
135 addProvider(window, activeProvider);
142 public void windowClosed(IWorkbenchWindow window) {
144 System.out.println("window closed: " + window);
145 removeProvider(window);
149 public void windowDeactivated(IWorkbenchWindow window) {
151 System.out.println("window deactivated: " + window);
155 public void windowOpened(IWorkbenchWindow window) {
157 System.out.println("window opened: " + window + ", active window = " + activeWindow);
160 private void addProvider(Object context, ISessionContextProvider p) {
161 synchronized (providers) {
162 if (providers.put(context, p) != null) {
163 // This is a bug, should never happen.
164 throw new Error("Unexpected bug, this should never happen!");
166 allProviders = providers.values().toArray(ZERO);
170 private void removeProvider(Object context) {
171 synchronized (providers) {
172 ISessionContextProvider provider = providers.remove(context);
173 if (provider == null) {
174 // This is a bug, should never happen.
175 throw new Error("Unexpected bug, this should never happen!");
177 allProviders = providers.values().toArray(ZERO);
179 // Make sure that any session remaining in the removed context will
180 // be disposed of eventually.
181 ISessionContext ctx = provider.getSessionContext();
183 if (!SimanticsUI.isInUse(ctx)) {
184 SessionUtils.releaseUnusedSessionAfterHoldTime(ctx);
191 * This is a purely internal mechanism to allow proper creation of context
192 * providers for workbench windows as early as possible during the workbench
193 * window construction process, i.e. in the
194 * <code>WorkbenchWindowAdvisor.preWindowOpen()</code> instantiated
195 * by <code>WorkbenchAdvisor</code>.
199 public void createProviderForWindow(IWorkbenchWindow context) {
200 synchronized (providers) {
201 if (isFirstWindow.compareAndSet(true, false)) {
202 assert activeProvider != null;
204 System.out.println("[Create Context] first window: " + context);
206 SessionContextProvider v = (SessionContextProvider) providers.remove(temporaryContext);
208 v.setHandle(context);
209 providers.put(context, v);
211 System.out.println(" rebound: '" + v + "' to '" + context + "'");
215 System.out.println("[Create Context] new window: " + context);
216 // Create new session context provider
217 SessionContextProvider v = new SessionContextProvider(context);
218 ISessionContextProvider active = getActive();
220 v.setSessionContext(active.getSessionContext());
221 addProvider(context, v);