X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.ui%2Fsrc%2Forg%2Fsimantics%2Fui%2FSimanticsUI.java;h=4b1554c864c19c0fd68477276d70c97859d2718f;hb=560d8aa2e37cb6b0249aec6d7e96e67d5a64c59f;hp=bb7e02b0b46202fa1f990765bf32935291585c13;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/SimanticsUI.java b/bundles/org.simantics.ui/src/org/simantics/ui/SimanticsUI.java index bb7e02b0b..4b1554c86 100644 --- a/bundles/org.simantics.ui/src/org/simantics/ui/SimanticsUI.java +++ b/bundles/org.simantics.ui/src/org/simantics/ui/SimanticsUI.java @@ -1,505 +1,505 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management - * in Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.ui; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Widget; -import org.eclipse.ui.PlatformUI; -import org.simantics.DatabaseJob; -import org.simantics.db.Resource; -import org.simantics.db.Session; -import org.simantics.db.common.primitiverequest.Adapter; -import org.simantics.db.common.utils.Logger; -import org.simantics.db.common.utils.RequestUtil; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.management.ISessionContext; -import org.simantics.db.management.ISessionContextProvider; -import org.simantics.db.management.ISessionContextProviderSource; -import org.simantics.project.IProject; -import org.simantics.project.ProjectKeys; -import org.simantics.utils.datastructures.Arrays; -import org.simantics.utils.ui.BundleUtils; -import org.simantics.utils.ui.ISelectionUtils; -import org.simantics.utils.ui.SWTUtils; - -/** - */ -public class SimanticsUI { - - public static final String PLUGIN_ID = "org.simantics.ui"; - - /** - * The maximum amount of time in milliseconds to wait for the execution of a - * database request to start when the request is executed synchronously in - * the UI thread. The timeout counting starts from the moment the request is - * first scheduled into the database {@link Session}. The purpose is to - * prevent synchronous UI thread database requests from locking the whole UI - * thread up. - * - *

- * The default value is 20. The default value can be customized at class - * load time by setting the system property - * simantics.ui.request.start.timeout to the desired value at - * JVM startup. - * - * @see RequestUtil - */ - public static final long UI_THREAD_REQUEST_START_TIMEOUT; - /** - * The maximum amount of time in milliseconds to wait for the execution of a - * database request to complete when the request is executed synchronously - * in the UI thread. The timeout counting starts from the moment the request - * execution is scheduled. The purpose is to prevent synchronous UI thread - * database requests from locking the whole UI thread up. - * - *

- * The default value is 50. The default value can be customized at class - * load time by setting the system property - * simantics.ui.request.execution.timeout to the desired value - * at JVM startup. - * - * @see RequestUtil - */ - public static final long UI_THREAD_REQUEST_EXECUTION_TIMEOUT; - /** - * - *

- * The default value is 100. The default value can be customized at class - * load time by setting the system property - * simantics.ui.request.execution.timeout.long to the desired - * value at JVM startup. - * - * @see RequestUtil - */ - public static final long UI_THREAD_REQUEST_EXECUTION_TIMEOUT_LONG; - - static { - UI_THREAD_REQUEST_START_TIMEOUT = parseLongProperty("simantics.ui.request.start.timeout", 500L); - UI_THREAD_REQUEST_EXECUTION_TIMEOUT = parseLongProperty("simantics.ui.request.exec.timeout", 50L); - UI_THREAD_REQUEST_EXECUTION_TIMEOUT_LONG = parseLongProperty("simantics.ui.request.exec.timeout.long", 100L); - } - - /** - * Information of the currently open database session for the Simantics UI. - * Contains just the vital information to connect to the database. Is - * null when there is no open database session. - */ - private static ISessionContextProviderSource providerSource = null; - -// /** -// * TODO: support different contexts -// * @deprecated no replacement -// */ -// @Deprecated -// public static void undo() { -// try { -// PlatformUI.getWorkbench().getOperationSupport().getOperationHistory().undo( -// IOperationHistory.GLOBAL_UNDO_CONTEXT, null, null); -// } catch (ExecutionException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// -// /** -// * TODO: support different contexts -// * @deprecated no replacement -// */ -// @Deprecated -// public static void redo() { -// try { -// PlatformUI.getWorkbench().getOperationSupport().getOperationHistory().redo( -// IOperationHistory.GLOBAL_UNDO_CONTEXT, null, null); -// } catch (ExecutionException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } - - /** - * Only for use in application startup code such as the workbench window - * advisor. Must be invoked before calling any other methods in this class. - * - * @param manager the ISessionManager to be used by the application - * @throw IllegalArgumentException if manager is null - */ - public static void setSessionContextProviderSource(ISessionContextProviderSource source) { - if (source == null) - throw new IllegalArgumentException("null provider source"); - providerSource = source; - } - - /** - * Asserts that the current context provider source has been initialized - * before allowing access to it. - * - * @return current context provider source - */ - public static ISessionContextProviderSource getProviderSource() { - if (providerSource == null) - throw new IllegalStateException( - "providerSource must be initialized by the application before using SimanticsUI"); - return providerSource; - } - - /** - * Close and remove the current session contexts of the UI. Afterwards - * getSessionContext will return null. - * - * Not for client use, only for internal purposes. - */ - public static synchronized void closeSessions() { - ISessionContextProviderSource source = providerSource; - if (source == null) - return; - for (ISessionContextProvider p : source.getAll()) { - ISessionContext ctx = p.setSessionContext(null); - if (ctx != null) { - ctx.dispose(); - } - } - } - - /** - * @return true if the session manager contains the specified - * session context - */ - public static synchronized boolean isInUse(ISessionContext ctx) { - for (ISessionContextProvider p : getProviderSource().getAll()) { - if (p.getSessionContext() == ctx) - return true; - } - return false; - } - - /** - * @param project the project to check - * @param excluding - * @return true if the session manager contains an - * ISessionContext that contains a reference to the specified - * project, disregarding the excluded ISessionContexts listed - */ - public static synchronized boolean isInUse(IProject project, ISessionContext... excluding) { - for (ISessionContextProvider p : getProviderSource().getAll()) { - ISessionContext ctx = p.getSessionContext(); - if (ctx != null) { - if (Arrays.indexOf(excluding, ctx) == -1) { - if (ctx.getHint(ProjectKeys.KEY_PROJECT) == project) - return true; - } - } - } - return false; - } - -// /** -// * Looks if there is an ISessionContextProvider within the Simantics workbench -// * that is currently using a ProCore database server at the specified -// * address. -// * -// * @param address the address to look for connections to -// * @return null if there is currently no session in use to the -// * specified address. -// */ -// public static synchronized ISessionContext findSessionTo(ServerAddress address) { -// if (address == null) -// throw new IllegalArgumentException("null address"); -// for (ISessionContextProvider provider : getProviderSource().getAll()) { -// ISessionContext ctx = provider.getSessionContext(); -// if (ctx != null) { -// ServerAddress addr = ctx.getAddress(); -// if (address.equals(addr)) -// return ctx; -// } -// } -// return null; -// } - - /** - * Returns the session context provider of the curretly active workbench - * window. This method will always return a valid session context provider. - * - * @return a valid ISessionContextProvider - */ - public static ISessionContextProvider getSessionContextProvider() { - return getProviderSource().getActive(); - } - - /** - * Returns the session context provider for the specified handle if one - * exists. Workbench windows (IWorkbenchWindow) are currently used as - * handles. - * - * @param handle the handle associated with the requested session context - * provider - * @return null if there is no session associated to the - * specified handle - */ - public static ISessionContextProvider getSessionContextProvider(Object handle) { - return getProviderSource().get(handle); - } - - /** - * Returns the database session context associated with the currently active - * workbench window. This method should be used to retrieve session contexts - * only when the client is sure that the correct workbench window has focus. - * - *

- * If the client knows the workbench window it is working with, but it isn't - * sure that the correct workbench window has focus, use - * {@link #getSessionContext(Object)} instead. - *

- * - * @return the session context associated with the currently active - * workbench window or null if the active window has no - * session context - */ - public static ISessionContext getSessionContext() { - ISessionContextProvider provider = getSessionContextProvider(); - return provider != null ? provider.getSessionContext() : null; - } - - /** - * Returns the database session context associated with the specified - * handle. Workbench windows (IWorkbenchWindow) are currently used as - * handles. This method should be used to retrieve session contexts in cases - * where the workbench window is known, but the thread of execution is such - * that the client cannot be certain that the same workbench window has - * focus. - * - * @return the session context associated with the specified handle - * (IWorkbenchWindow) - */ - public static ISessionContext getSessionContext(Object handle) { - return getSessionContextProvider(handle).getSessionContext(); - } - - /** - * Associates the specified ISessionContext with the currently active - * workbench window. To remove an ISessionContext association from the - * active workbench window, specify null as ctx. - * - *

- * After invoking this method you should be able to retrieve the same - * ISessionContext through {@link #getSessionContext()}, provided that the - * same workbench window has focus at that time. - *

- * - * @param ctx the new UI database session context or null to - * replace the current UI session with no session. - * @return The previous session context if one existed, otherwise - * null. If the specified ctx matched the - * current session context (null or - * non-null), null is also returned and nothing is - * done. - */ - public static synchronized ISessionContext setSessionContext(ISessionContext ctx) { - return getSessionContextProvider().setSessionContext(ctx); - } - - /** - * Associates the specified ISessionContext with the specified handle - * object. - * - *

- * Currently IWorkbenchWindow's are used as handles. This implies - * that each workbench window can only have one active ISessionContext bound - * to it. After invoking this method with a valid workbench window handle - * you should be able to retrieve the same ISessionContext through - * {@link #getSessionContext(Object)} with the same workbench window - * specified as the handle. - *

- * - * @param handle the handle to associate the specified ISessionContext with. - * @param ctx the new UI database session context or null to - * replace the current UI session with no session. - * @return The previous session context if one existed, otherwise - * null. If the specified ctx matched the - * current session context (null or - * non-null), null is also returned and nothing is - * done. - */ - public static synchronized ISessionContext setSessionContext(Object handle, ISessionContext ctx) { - ISessionContextProvider provider = getProviderSource().get(handle); - if (provider != null) - return provider.setSessionContext(ctx); - return null; - } - - /** - * Returns the database Session bound to the currently active workbench - * window. - * - *

- * This method should only be invoked in cases where it is certain that the - * correct workbench window has focus or it is the latest of all workbench - * windows to have had focus. Basically any invocation from the SWT UI - * thread is safe, since because in those cases the currently active - * workbench window is generally known. Instead invocations from any other - * thread should be carefully considered. The rule of thumb is that if you - * cannot be sure that the correct workbench window has focus, you should - * always get a hold of the Session to be used in some other manner. - *

- * - *

- * The method always returns a non-null Session or produces an - * IllegalStateException if a Session was not attainable. - *

- * - * @return the Session bound to the currently active workbench window - * @throws IllegalStateException if no Session was available - */ - public static Session getSession() { - ISessionContext ctx = getSessionContext(); - if (ctx == null) - throw new IllegalStateException("Session unavailable, no database session open"); - return ctx.getSession(); - } - - /** - * Returns the database Session bound to the currently active workbench - * window. Differently from {@link #getSession()}, this method returns - * null if there is no current Session available. - * - *

- * This method should only be invoked from the SWT UI thread. Check the - * explanations given in {@link #getSession()}. The same applies to this - * method also. - *

- * - * @return the Session bound to the currently active workbench window or - * null - */ - public static Session peekSession() { - ISessionContext ctx = getSessionContext(); - return ctx == null ? null : ctx.peekSession(); - } - - /** - * @return the currently open and active project as an IProject or - * null if there is no active session or project - */ - public static IProject peekProject() { - ISessionContext ctx = getSessionContext(); - return ctx == null ? null : (org.simantics.project.IProject) ctx.getHint(ProjectKeys.KEY_PROJECT); - } - - /** - * @return the currently open and active project for the specified database - * session or null if there is no current project - */ - public static IProject peekProject(ISessionContext ctx) { - if (ctx == null) - return null; - return ctx.getHint(ProjectKeys.KEY_PROJECT); - } - - /** - * @return the currently open and active project as an IProject - * @throws IllegalStateException if there is no currently active database - * session, which also means there is no active project at the - * moment - */ - public static IProject getProject() { - ISessionContext ctx = getSessionContext(); - if (ctx == null) - throw new IllegalStateException("No current database session"); - return ctx.getHint(ProjectKeys.KEY_PROJECT); - } - - /** - * TODO: refactor this out of here - * - * @param imageFilePath - * @return - */ - public static ImageDescriptor getImageDescriptor(String imageFilePath) { - return BundleUtils.getImageDescriptorFromPlugin(PLUGIN_ID, imageFilePath); - } - - /** - * TODO: [Tuukka] I'm really unsure this belongs here. - * - * @param - * @param sel - * @param assignableFrom - * @return - */ - public static T filterSingleSelection(ISelection sel, Class assignableFrom) { - - T result = ISelectionUtils.filterSingleSelection(sel, assignableFrom); - if (result != null) - return result; - - Resource resource = ISelectionUtils.filterSingleSelection(sel, Resource.class); - if(resource == null) return null; - - try { - return getSession().syncRequest(new Adapter(resource, assignableFrom)); - } catch (DatabaseException e) { - Logger.defaultLogError(e); - return null; - } - - } - - public static T filterSingleWorkbenchSelection(Class assignableFrom) { - return filterSingleSelection(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection(), assignableFrom); - } - - - public static void asyncExecSWT(final Widget widget, final Runnable runnable) { - SWTUtils.asyncExec(widget, delayedExecSWT(null, widget, runnable)); - } - - public static void asyncExecSWT(final Display display, final Runnable runnable) { - SWTUtils.asyncExec(display, delayedExecSWT(display, null, runnable)); - } - - private static Runnable delayedExecSWT(final Display display, final Widget widget, final Runnable runnable) { - if (display == null && widget == null) - throw new IllegalArgumentException("both display and widget are null"); - - return new Runnable() { - @Override - public void run() { - if (display != null && display.isDisposed()) - return; - if (widget != null && widget.isDisposed()) - return; - if (DatabaseJob.inProgress()) { - Display d = display != null ? display : widget.getDisplay(); - d.timerExec(50, this); - return; - } - runnable.run(); - } - }; - } - - private static long parseLongProperty(String propertyName, long defaultValue) { - String value = System.getProperty(propertyName, null); - try { - return value != null ? Long.parseLong(value) : defaultValue; - } catch (NumberFormatException e) { - return defaultValue; - } - } - - public static boolean isLinuxGTK() { - String ws = System.getProperty("osgi.ws"); - return ws != null && "gtk".equals(ws); - } - -} +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.ui; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.ui.PlatformUI; +import org.simantics.DatabaseJob; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.common.primitiverequest.Adapter; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.common.utils.RequestUtil; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.management.ISessionContextProvider; +import org.simantics.db.management.ISessionContextProviderSource; +import org.simantics.project.IProject; +import org.simantics.project.ProjectKeys; +import org.simantics.utils.datastructures.Arrays; +import org.simantics.utils.ui.BundleUtils; +import org.simantics.utils.ui.ISelectionUtils; +import org.simantics.utils.ui.SWTUtils; + +/** + */ +public class SimanticsUI { + + public static final String PLUGIN_ID = "org.simantics.ui"; + + /** + * The maximum amount of time in milliseconds to wait for the execution of a + * database request to start when the request is executed synchronously in + * the UI thread. The timeout counting starts from the moment the request is + * first scheduled into the database {@link Session}. The purpose is to + * prevent synchronous UI thread database requests from locking the whole UI + * thread up. + * + *

+ * The default value is 20. The default value can be customized at class + * load time by setting the system property + * simantics.ui.request.start.timeout to the desired value at + * JVM startup. + * + * @see RequestUtil + */ + public static final long UI_THREAD_REQUEST_START_TIMEOUT; + /** + * The maximum amount of time in milliseconds to wait for the execution of a + * database request to complete when the request is executed synchronously + * in the UI thread. The timeout counting starts from the moment the request + * execution is scheduled. The purpose is to prevent synchronous UI thread + * database requests from locking the whole UI thread up. + * + *

+ * The default value is 50. The default value can be customized at class + * load time by setting the system property + * simantics.ui.request.execution.timeout to the desired value + * at JVM startup. + * + * @see RequestUtil + */ + public static final long UI_THREAD_REQUEST_EXECUTION_TIMEOUT; + /** + * + *

+ * The default value is 100. The default value can be customized at class + * load time by setting the system property + * simantics.ui.request.execution.timeout.long to the desired + * value at JVM startup. + * + * @see RequestUtil + */ + public static final long UI_THREAD_REQUEST_EXECUTION_TIMEOUT_LONG; + + static { + UI_THREAD_REQUEST_START_TIMEOUT = parseLongProperty("simantics.ui.request.start.timeout", 500L); + UI_THREAD_REQUEST_EXECUTION_TIMEOUT = parseLongProperty("simantics.ui.request.exec.timeout", 50L); + UI_THREAD_REQUEST_EXECUTION_TIMEOUT_LONG = parseLongProperty("simantics.ui.request.exec.timeout.long", 100L); + } + + /** + * Information of the currently open database session for the Simantics UI. + * Contains just the vital information to connect to the database. Is + * null when there is no open database session. + */ + private static ISessionContextProviderSource providerSource = null; + +// /** +// * TODO: support different contexts +// * @deprecated no replacement +// */ +// @Deprecated +// public static void undo() { +// try { +// PlatformUI.getWorkbench().getOperationSupport().getOperationHistory().undo( +// IOperationHistory.GLOBAL_UNDO_CONTEXT, null, null); +// } catch (ExecutionException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// } +// +// /** +// * TODO: support different contexts +// * @deprecated no replacement +// */ +// @Deprecated +// public static void redo() { +// try { +// PlatformUI.getWorkbench().getOperationSupport().getOperationHistory().redo( +// IOperationHistory.GLOBAL_UNDO_CONTEXT, null, null); +// } catch (ExecutionException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// } + + /** + * Only for use in application startup code such as the workbench window + * advisor. Must be invoked before calling any other methods in this class. + * + * @param manager the ISessionManager to be used by the application + * @throw IllegalArgumentException if manager is null + */ + public static void setSessionContextProviderSource(ISessionContextProviderSource source) { + if (source == null) + throw new IllegalArgumentException("null provider source"); + providerSource = source; + } + + /** + * Asserts that the current context provider source has been initialized + * before allowing access to it. + * + * @return current context provider source + */ + public static ISessionContextProviderSource getProviderSource() { + if (providerSource == null) + throw new IllegalStateException( + "providerSource must be initialized by the application before using SimanticsUI"); + return providerSource; + } + + /** + * Close and remove the current session contexts of the UI. Afterwards + * getSessionContext will return null. + * + * Not for client use, only for internal purposes. + */ + public static synchronized void closeSessions() { + ISessionContextProviderSource source = providerSource; + if (source == null) + return; + for (ISessionContextProvider p : source.getAll()) { + ISessionContext ctx = p.setSessionContext(null); + if (ctx != null) { + ctx.dispose(); + } + } + } + + /** + * @return true if the session manager contains the specified + * session context + */ + public static synchronized boolean isInUse(ISessionContext ctx) { + for (ISessionContextProvider p : getProviderSource().getAll()) { + if (p.getSessionContext() == ctx) + return true; + } + return false; + } + + /** + * @param project the project to check + * @param excluding + * @return true if the session manager contains an + * ISessionContext that contains a reference to the specified + * project, disregarding the excluded ISessionContexts listed + */ + public static synchronized boolean isInUse(IProject project, ISessionContext... excluding) { + for (ISessionContextProvider p : getProviderSource().getAll()) { + ISessionContext ctx = p.getSessionContext(); + if (ctx != null) { + if (Arrays.indexOf(excluding, ctx) == -1) { + if (ctx.getHint(ProjectKeys.KEY_PROJECT) == project) + return true; + } + } + } + return false; + } + +// /** +// * Looks if there is an ISessionContextProvider within the Simantics workbench +// * that is currently using a ProCore database server at the specified +// * address. +// * +// * @param address the address to look for connections to +// * @return null if there is currently no session in use to the +// * specified address. +// */ +// public static synchronized ISessionContext findSessionTo(ServerAddress address) { +// if (address == null) +// throw new IllegalArgumentException("null address"); +// for (ISessionContextProvider provider : getProviderSource().getAll()) { +// ISessionContext ctx = provider.getSessionContext(); +// if (ctx != null) { +// ServerAddress addr = ctx.getAddress(); +// if (address.equals(addr)) +// return ctx; +// } +// } +// return null; +// } + + /** + * Returns the session context provider of the curretly active workbench + * window. This method will always return a valid session context provider. + * + * @return a valid ISessionContextProvider + */ + public static ISessionContextProvider getSessionContextProvider() { + return getProviderSource().getActive(); + } + + /** + * Returns the session context provider for the specified handle if one + * exists. Workbench windows (IWorkbenchWindow) are currently used as + * handles. + * + * @param handle the handle associated with the requested session context + * provider + * @return null if there is no session associated to the + * specified handle + */ + public static ISessionContextProvider getSessionContextProvider(Object handle) { + return getProviderSource().get(handle); + } + + /** + * Returns the database session context associated with the currently active + * workbench window. This method should be used to retrieve session contexts + * only when the client is sure that the correct workbench window has focus. + * + *

+ * If the client knows the workbench window it is working with, but it isn't + * sure that the correct workbench window has focus, use + * {@link #getSessionContext(Object)} instead. + *

+ * + * @return the session context associated with the currently active + * workbench window or null if the active window has no + * session context + */ + public static ISessionContext getSessionContext() { + ISessionContextProvider provider = getSessionContextProvider(); + return provider != null ? provider.getSessionContext() : null; + } + + /** + * Returns the database session context associated with the specified + * handle. Workbench windows (IWorkbenchWindow) are currently used as + * handles. This method should be used to retrieve session contexts in cases + * where the workbench window is known, but the thread of execution is such + * that the client cannot be certain that the same workbench window has + * focus. + * + * @return the session context associated with the specified handle + * (IWorkbenchWindow) + */ + public static ISessionContext getSessionContext(Object handle) { + return getSessionContextProvider(handle).getSessionContext(); + } + + /** + * Associates the specified ISessionContext with the currently active + * workbench window. To remove an ISessionContext association from the + * active workbench window, specify null as ctx. + * + *

+ * After invoking this method you should be able to retrieve the same + * ISessionContext through {@link #getSessionContext()}, provided that the + * same workbench window has focus at that time. + *

+ * + * @param ctx the new UI database session context or null to + * replace the current UI session with no session. + * @return The previous session context if one existed, otherwise + * null. If the specified ctx matched the + * current session context (null or + * non-null), null is also returned and nothing is + * done. + */ + public static synchronized ISessionContext setSessionContext(ISessionContext ctx) { + return getSessionContextProvider().setSessionContext(ctx); + } + + /** + * Associates the specified ISessionContext with the specified handle + * object. + * + *

+ * Currently IWorkbenchWindow's are used as handles. This implies + * that each workbench window can only have one active ISessionContext bound + * to it. After invoking this method with a valid workbench window handle + * you should be able to retrieve the same ISessionContext through + * {@link #getSessionContext(Object)} with the same workbench window + * specified as the handle. + *

+ * + * @param handle the handle to associate the specified ISessionContext with. + * @param ctx the new UI database session context or null to + * replace the current UI session with no session. + * @return The previous session context if one existed, otherwise + * null. If the specified ctx matched the + * current session context (null or + * non-null), null is also returned and nothing is + * done. + */ + public static synchronized ISessionContext setSessionContext(Object handle, ISessionContext ctx) { + ISessionContextProvider provider = getProviderSource().get(handle); + if (provider != null) + return provider.setSessionContext(ctx); + return null; + } + + /** + * Returns the database Session bound to the currently active workbench + * window. + * + *

+ * This method should only be invoked in cases where it is certain that the + * correct workbench window has focus or it is the latest of all workbench + * windows to have had focus. Basically any invocation from the SWT UI + * thread is safe, since because in those cases the currently active + * workbench window is generally known. Instead invocations from any other + * thread should be carefully considered. The rule of thumb is that if you + * cannot be sure that the correct workbench window has focus, you should + * always get a hold of the Session to be used in some other manner. + *

+ * + *

+ * The method always returns a non-null Session or produces an + * IllegalStateException if a Session was not attainable. + *

+ * + * @return the Session bound to the currently active workbench window + * @throws IllegalStateException if no Session was available + */ + public static Session getSession() { + ISessionContext ctx = getSessionContext(); + if (ctx == null) + throw new IllegalStateException("Session unavailable, no database session open"); + return ctx.getSession(); + } + + /** + * Returns the database Session bound to the currently active workbench + * window. Differently from {@link #getSession()}, this method returns + * null if there is no current Session available. + * + *

+ * This method should only be invoked from the SWT UI thread. Check the + * explanations given in {@link #getSession()}. The same applies to this + * method also. + *

+ * + * @return the Session bound to the currently active workbench window or + * null + */ + public static Session peekSession() { + ISessionContext ctx = getSessionContext(); + return ctx == null ? null : ctx.peekSession(); + } + + /** + * @return the currently open and active project as an IProject or + * null if there is no active session or project + */ + public static IProject peekProject() { + ISessionContext ctx = getSessionContext(); + return ctx == null ? null : (org.simantics.project.IProject) ctx.getHint(ProjectKeys.KEY_PROJECT); + } + + /** + * @return the currently open and active project for the specified database + * session or null if there is no current project + */ + public static IProject peekProject(ISessionContext ctx) { + if (ctx == null) + return null; + return ctx.getHint(ProjectKeys.KEY_PROJECT); + } + + /** + * @return the currently open and active project as an IProject + * @throws IllegalStateException if there is no currently active database + * session, which also means there is no active project at the + * moment + */ + public static IProject getProject() { + ISessionContext ctx = getSessionContext(); + if (ctx == null) + throw new IllegalStateException("No current database session"); + return ctx.getHint(ProjectKeys.KEY_PROJECT); + } + + /** + * TODO: refactor this out of here + * + * @param imageFilePath + * @return + */ + public static ImageDescriptor getImageDescriptor(String imageFilePath) { + return BundleUtils.getImageDescriptorFromPlugin(PLUGIN_ID, imageFilePath); + } + + /** + * TODO: [Tuukka] I'm really unsure this belongs here. + * + * @param + * @param sel + * @param assignableFrom + * @return + */ + public static T filterSingleSelection(ISelection sel, Class assignableFrom) { + + T result = ISelectionUtils.filterSingleSelection(sel, assignableFrom); + if (result != null) + return result; + + Resource resource = ISelectionUtils.filterSingleSelection(sel, Resource.class); + if(resource == null) return null; + + try { + return getSession().syncRequest(new Adapter(resource, assignableFrom)); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + return null; + } + + } + + public static T filterSingleWorkbenchSelection(Class assignableFrom) { + return filterSingleSelection(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection(), assignableFrom); + } + + + public static void asyncExecSWT(final Widget widget, final Runnable runnable) { + SWTUtils.asyncExec(widget, delayedExecSWT(null, widget, runnable)); + } + + public static void asyncExecSWT(final Display display, final Runnable runnable) { + SWTUtils.asyncExec(display, delayedExecSWT(display, null, runnable)); + } + + private static Runnable delayedExecSWT(final Display display, final Widget widget, final Runnable runnable) { + if (display == null && widget == null) + throw new IllegalArgumentException("both display and widget are null"); + + return new Runnable() { + @Override + public void run() { + if (display != null && display.isDisposed()) + return; + if (widget != null && widget.isDisposed()) + return; + if (DatabaseJob.inProgress()) { + Display d = display != null ? display : widget.getDisplay(); + d.timerExec(50, this); + return; + } + runnable.run(); + } + }; + } + + private static long parseLongProperty(String propertyName, long defaultValue) { + String value = System.getProperty(propertyName, null); + try { + return value != null ? Long.parseLong(value) : defaultValue; + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public static boolean isLinuxGTK() { + String ws = System.getProperty("osgi.ws"); + return ws != null && "gtk".equals(ws); + } + +}