/******************************************************************************* * 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 ornull
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 ornull
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 ornull
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