1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-04 07:35:24 +02:00

[190231] Prepare API for UI/Non-UI Splitting

This commit is contained in:
Martin Oberhuber 2008-04-12 01:25:35 +00:00
parent 28d57bdd8d
commit 9db0e7c00a
5 changed files with 425 additions and 51 deletions

View file

@ -0,0 +1,121 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 Wind River Systems, Inc. and others.
* 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:
* Martin Oberhuber (Wind River) - [190231] initial API and implementation
* IBM Corporation - Javadoc for runInDefaultContext() method
*******************************************************************************/
package org.eclipse.rse.core;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.rse.services.clientserver.messages.SystemMessage;
/**
* Interaction Provider Interface.
*
* Classes implementing this interface provide a means for RSE to communicate
* with the outside world: via progress monitors, events and messages. A UI
* implementation of this interface would typically use UI components for user
* interaction; although this can be changed also intermittently.
*
* Non-UI headless applications may log messages rather than doing interactive
* messages, and may use different Threads for sending messages.
*
* @since org.eclipse.rse.core 3.0
*/
public interface IRSEInteractionProvider {
/**
* Return a default progress monitor for the context that's currently
* active.
*
* Usually, long-running operations should always be created from the client
* with a progress monitor that they can use. Historically, however, this
* has not always been done and is especially problematic in operations that
* are performed as the result of Callbacks.
*
* For such situations, this method returns a default progress monitor in a
* context that we guess. We try to use one default progress use one for all
* phases of a single operation, such as connecting and resolving.
*
* @return a default progress monitor
*/
public IProgressMonitor getDefaultProgressMonitor();
/**
* <p>
* Runs the given <code>IRSERunnableWithProgress</code> in the default
* context available to this interaction provider, that provides a progress
* monitor. For example, if the default context is a
* <code>ProgressMonitorDialog</code> then the runnable is run using the
* dialog's progress monitor. This method is derived from
* <code>IRunnableContext#run()</code>.
* </p>
* <p>
* If <code>fork</code> is <code>false</code>, the current thread is
* used to run the runnable. Note that if <code>fork</code> is
* <code>true</code>, it is unspecified whether or not this method blocks
* until the runnable has been run. Implementers should document whether the
* runnable is run synchronously (blocking) or asynchronously
* (non-blocking), or if no assumption can be made about the blocking
* behaviour.
* </p>
*
* @param fork <code>true</code> if the runnable should be run in a
* separate thread, and <code>false</code> to run in the same
* thread
* @param cancellable <code>true</code> to enable the cancellation, and
* <code>false</code> to make the operation uncancellable
* @param runnable the runnable to run
*
* @exception InvocationTargetException wraps any exception or error which
* occurs while running the runnable
* @exception InterruptedException propagated by the context if the runnable
* acknowledges cancellation by throwing this exception. This
* should not be thrown if cancellable is <code>false</code>.
*/
public void runInDefaultContext(boolean fork, boolean cancellable, IRSERunnableWithProgress runnable) throws InvocationTargetException,
InterruptedException;
/**
* Asynchronously run the given runnable in a separate thread.
*
* UI implementations should have the runnable run in the dispatch thread,
* where it has access to UI components. This is used for notifications.
* Non-UI applications may choose any Thread they like, provided that two
* conditions are met:
* <ol>
* <li>All Runnables are run on the same Thread.
* <li>The ordering of Runnables remains intact.
* </ol>
*
* @param runnable the Runnable to run asynchronously
*/
public void asyncExec(Runnable runnable);
/**
* Flush the Queue of Runnables enqueued with {@link #asyncExec(Runnable)}.
*
* This needs to be done when this interaction provider is to be replaced by
* a different one, in order to ensure that the ordering of all Runnables
* remains intact.
*/
public void flushRunnableQueue();
/**
* Show the given message or log it.
*
* In an interactive environment, this pops up a dialog asking the user to
* press an OK button. The method will not return before the OK button is
* pressed.
*
* @param msg the message to show
*/
public void showMessage(SystemMessage msg);
}

View file

@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
* Martin Oberhuber (Wind River) - [190231] Adapted from jface.operation.IRunnableWithProgress
*******************************************************************************/
package org.eclipse.rse.core;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* The <code>IRSERunnableWithProgress</code> interface should be implemented
* by any class whose instances are intended to be executed as a long-running
* operation. Long-running operations are typically presented at the UI via a
* modal dialog showing a progress indicator and a Cancel button.
*
* This interface is derived from
* <code>org.eclipse.jface.operation.IRunnableWithProgress</code>, but
* brought into no-UI space. The class must define a <code>run</code> method
* that takes a progress monitor. The <code>run</code> method is usually not
* invoked directly, but rather by passing the
* <code>IRunnableWithProgress</code> to the <code>run</code> method of an
* <code>IRunnableContext</code>, which provides the UI for the progress
* monitor and Cancel button.
*
* @see IRSEInteractionProvider
* @since org.eclipse.rse.core 3.0
*/
public interface IRSERunnableWithProgress {
/**
* Runs this operation. Progress should be reported to the given progress
* monitor. This method is usually invoked by an
* <code>IRunnableContext</code>'s <code>run</code> method, which
* supplies the progress monitor. A request to cancel the operation should
* be honored and acknowledged by throwing <code>InterruptedException</code>.
*
* @param monitor the progress monitor to use to display progress and
* receive requests for cancellation
* @exception InvocationTargetException if the run method must propagate a
* checked exception, it should wrap it inside an
* <code>InvocationTargetException</code>; runtime
* exceptions are automatically wrapped in an
* <code>InvocationTargetException</code> by the calling
* context
* @exception InterruptedException if the operation detects a request to
* cancel, using <code>IProgressMonitor.isCanceled()</code>,
* it should exit by throwing
* <code>InterruptedException</code>
*
* @see IRSEInteractionProvider
*/
public void run(IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException;
}

View file

@ -22,6 +22,7 @@
* Martin Oberhuber (Wind River) - [215820] Move SystemRegistry implementation to Core
* David Dykstal (IBM) - [197167] adding notification and waiting for RSE model
* Martin Oberhuber (Wind River) - [cleanup] Add API "since" Javadoc tags
* Martin Oberhuber (Wind River) - [190231] Prepare API for UI/Non-UI Splitting
********************************************************************************/
package org.eclipse.rse.core;
@ -57,7 +58,7 @@ import org.osgi.framework.BundleContext;
* RSECorePlugin provides the activation for the RSE core and acts as the
* primary registry for logging, persistence, and the main RSE service
* registries.
*
*
* @noextend This class is not intended to be subclassed by clients.
* @noinstantiate This class is not intended to be instantiated by clients.
*/
@ -65,7 +66,7 @@ public class RSECorePlugin extends Plugin {
/**
* The plugin id for this plugin. Value "org.eclipse.rse.core".
*
*
* @since org.eclipse.rse.core 3.0
*/
public static final String PLUGIN_ID = "org.eclipse.rse.core"; //$NON-NLS-1$
@ -85,7 +86,7 @@ public class RSECorePlugin extends Plugin {
* {@link #isInitComplete(int)} which will return true if all phases of
* initialization are complete. Clients must not assume any particular
* ordering among phases based on the value.
*
*
* @since org.eclipse.rse.core 3.0
*/
public static final int INIT_ALL = 0;
@ -95,7 +96,7 @@ public class RSECorePlugin extends Plugin {
* {@link #isInitComplete(int)} which will return true if the model phase of
* the initialization is complete. Clients must not assume any particular
* ordering among phases based on the value.
*
*
* @since org.eclipse.rse.core 3.0
*/
public static final int INIT_MODEL = 1;
@ -105,7 +106,7 @@ public class RSECorePlugin extends Plugin {
* {@link #isInitComplete(int)} which will return true if the initializer
* phase of the initialization is complete. Clients must not assume any
* particular ordering among phases based on the value.
*
*
* @since org.eclipse.rse.core 3.0
*/
public static final int INIT_INITIALIZER = 2;
@ -115,6 +116,7 @@ public class RSECorePlugin extends Plugin {
private ISystemRegistry _systemRegistry = null;
private IRSEPersistenceManager _persistenceManager = null;
private ISubSystemConfigurationProxy[] _subsystemConfigurations = null;
private IRSEInteractionProvider _interactionProvider = null;
/**
* Returns the singleton instance of RSECorePlugin.
@ -127,7 +129,7 @@ public class RSECorePlugin extends Plugin {
/**
* Waits until the RSE model has been fully restored from its persistent
* form. Should be used before accessing pieces of the model.
*
*
* @return an IStatus indicating how the initialization ended.
* @throws InterruptedException if this wait was interrupted for some
* reason.
@ -139,7 +141,7 @@ public class RSECorePlugin extends Plugin {
/**
* Waits until the RSE has completed a specific phase of its initialization.
*
*
* @param phase the phase to wait for completion.
* @throws InterruptedException if this wait was interrupted for some
* reason.
@ -156,7 +158,7 @@ public class RSECorePlugin extends Plugin {
/**
* Check whether the initialization of the RSE model is complete for a given
* phase.
*
*
* @param phase the phase identifier.
* @return <code>true</code> if the initialization for the given phase has
* completed regardless of its status of that completion.
@ -175,7 +177,7 @@ public class RSECorePlugin extends Plugin {
* initialization phases complete. If the listener is added after the phase
* has completed it will not be invoked. If the listener is already in the
* set it will not be added again. Listeners may be notified in any order.
*
*
* @param listener the listener to be added
* @since org.eclipse.rse.core 3.0
*/
@ -186,7 +188,7 @@ public class RSECorePlugin extends Plugin {
/**
* Removes a listener to the set of listeners to be notified when phases
* complete. If the listener is not in the set this does nothing.
*
*
* @param listener the listener to be removed
* @since org.eclipse.rse.core 3.0
*/
@ -214,7 +216,7 @@ public class RSECorePlugin extends Plugin {
/**
* Return the master profile manager singleton.
*
*
* @return the RSE Profile Manager Singleton.
* @since org.eclipse.rse.core 3.0
*/
@ -226,7 +228,7 @@ public class RSECorePlugin extends Plugin {
* Check if the SystemRegistry has been instantiated already. Use this when
* you don't want to start the system registry as a side effect of
* retrieving it.
*
*
* @return <code>true</code> if the System Registry has been instantiated
* already.
* @since org.eclipse.rse.core 3.0
@ -398,6 +400,36 @@ public class RSECorePlugin extends Plugin {
getLogger().logError("Unexpected Exception", t); //$NON-NLS-1$
}
/**
* Set the default interaction provider.
*
* When RSE is run with UI, the UI plugins need to set an UI-based
* interaction provider for showing dialogs from Core operations. Non-UI
* headless operations can use an Interaction Provider that just logs its
* messages and works without other UI.
*
* @param p the interaction provider to set.
* @since org.eclipse.rse.core 3.0
*/
public void setDefaultInteractionProvider(IRSEInteractionProvider p) {
synchronized (this) {
_interactionProvider = p;
}
}
/**
* Get the default interface for interacting with the user or other outside
* world.
*
* @return the default interaction provider.
* @since org.eclipse.rse.core 3.0
*/
public IRSEInteractionProvider getDefaultInteractionProvider() {
synchronized (this) {
return _interactionProvider;
}
}
/**
* Register declared keystore providers.
*/

View file

@ -0,0 +1,163 @@
/*******************************************************************************
* Copyright (c) 2002, 2008 Wind River Systems, Inc. and others.
* 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:
* Martin Oberhuber (Wind River) - [190231] initial API and implementation
* Martin Oberhuber (Wind River) - brought in methods from SubSystem (c) IBM
*******************************************************************************/
package org.eclipse.rse.internal.ui;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.rse.core.IRSEInteractionProvider;
import org.eclipse.rse.core.IRSERunnableWithProgress;
import org.eclipse.rse.services.clientserver.messages.SystemMessage;
import org.eclipse.rse.ui.RSEUIPlugin;
import org.eclipse.rse.ui.SystemBasePlugin;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
/**
* A Default Interaction Provider that runs in the Eclipse / SWT UI.
* Meant to provide the same functionality as it was there before
* UI / Non-UI Splitting.
* @since org.eclipse.rse.ui 3.0
*/
public class DefaultUIInteractionProvider implements IRSEInteractionProvider {
private Shell shell = null;
private class NullRunnableContext implements IRunnableContext {
public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
IProgressMonitor monitor = new NullProgressMonitor();
runnable.run(monitor);
}
}
/**
* Get the progress monitor dialog for this operation. We try to use one for
* all phases of a single operation, such as connecting and resolving.
*
* @deprecated this is scheduled to be removed since we want to avoid UI
* components in SubSystem.
*/
protected IRunnableContext getRunnableContext(/* Shell rshell */) {
if (Display.getCurrent() == null) {
return new NullRunnableContext();
}
// for wizards and dialogs use the specified context that was placed in
// the registry
IRunnableContext irc = RSEUIPlugin.getTheSystemRegistryUI().getRunnableContext();
if (irc != null) {
SystemBasePlugin.logInfo("Got runnable context from system registry"); //$NON-NLS-1$
return irc;
} else {
// for other cases, use statusbar
IWorkbenchWindow win = SystemBasePlugin.getActiveWorkbenchWindow();
if (win != null) {
Shell winShell = getActiveWorkbenchShell();
if (winShell != null && !winShell.isDisposed() && winShell.isVisible()) {
SystemBasePlugin.logInfo("Using active workbench window as runnable context"); //$NON-NLS-1$
shell = winShell;
return win;
// dwd } else {
// dwd win = null;
}
}
// dwd if (shell == null || shell.isDisposed() ||
// !shell.isVisible()) {
// dwd SystemBasePlugin.logInfo("Using progress monitor dialog with
// given shell as parent");
// dwd shell = rshell;
// dwd }
// dwd IRunnableContext dlg = new ProgressMonitorDialog(rshell);
IRunnableContext dlg = new ProgressMonitorDialog(shell);
return dlg;
}
}
/**
* Helper/convenience method. Return shell of active window.
*/
public static Shell getActiveWorkbenchShell() {
Shell result = null;
if (PlatformUI.isWorkbenchRunning()) {
try {
IWorkbenchWindow window = getActiveWorkbenchWindow();
if (window != null) {
result = window.getShell();
}
} catch (Exception e) {
return null;
}
} else // workbench has not been loaded yet!
{
return null;
}
return result;
}
/**
* Helper/convenience method. Return active window
*/
public static IWorkbenchWindow getActiveWorkbenchWindow() {
return RSEUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
}
public void runInDefaultContext(boolean fork, boolean cancellable, IRSERunnableWithProgress runnable) throws InvocationTargetException,
InterruptedException {
// TODO Auto-generated method stub
}
private Display getDefaultDisplay() {
Display d = Display.getCurrent();
if (d == null) {
d = SystemBasePlugin.getActiveWorkbenchShell().getDisplay();
if (d == null) {
d = Display.getDefault();
}
}
return d;
}
public void asyncExec(Runnable runnable) {
getDefaultDisplay().asyncExec(runnable);
}
public void flushRunnableQueue() {
Display d = Display.getCurrent();
if (d == null) {
getDefaultDisplay().syncExec(new Runnable() {
public void run() {
flushRunnableQueue();
}
});
} else {
while (d.readAndDispatch()) {
// flush the event queue
}
}
}
public IProgressMonitor getDefaultProgressMonitor() {
// TODO Auto-generated method stub
return null;
}
public void showMessage(SystemMessage msg) {
// TODO Auto-generated method stub
}
}

View file

@ -36,6 +36,7 @@
* David McKnight (IBM) - [220547] [api][breaking] SimpleSystemMessage needs to specify a message id and some messages should be shared
* David Dykstal (IBM) - [225089][ssh][shells][api] Canceling connection leads to exception
* Martin Oberhuber (Wind River) - [218304] Improve deferred adapter loading
* Martin Oberhuber (Wind River) - [190231] Prepare API for UI/Non-UI Splitting
********************************************************************************/
package org.eclipse.rse.core.subsystems;
@ -62,6 +63,7 @@ import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.osgi.util.NLS;
import org.eclipse.rse.core.IRSEInteractionProvider;
import org.eclipse.rse.core.RSECorePlugin;
import org.eclipse.rse.core.RSEPreferencesManager;
import org.eclipse.rse.core.events.ISystemModelChangeEvent;
@ -101,7 +103,6 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.progress.WorkbenchJob;
@ -164,8 +165,9 @@ implements IAdaptable, ISubSystem, ISystemFilterPoolReferenceManagerProvider
protected ISubSystemConfiguration parentSubSystemConfiguration;
protected String previousUserIdKey;
private IRSEInteractionProvider _interactionProvider = null;
protected Shell shell = null;
protected boolean supportsConnecting = true;
protected boolean sortResults = true;
protected boolean runInThread = true;
@ -184,7 +186,6 @@ implements IAdaptable, ISubSystem, ISystemFilterPoolReferenceManagerProvider
protected String _name = null;
protected String _subsystemConfigurationId = null;
protected boolean _hidden = false;
private boolean _isInitialized = false;
@ -225,6 +226,37 @@ implements IAdaptable, ISubSystem, ISystemFilterPoolReferenceManagerProvider
_connectorService.registerSubSystem(this);
}
/**
* Set an Interaction Provider specific for this subsystem.
*
* @param p the new interaction provider to use, or <code>null</code> to
* fall back to the default interaction provider (from
* RSECorePlugin).
* @since 3.0
*/
public void setInteractionProvider(IRSEInteractionProvider p) {
synchronized (this) {
_interactionProvider = p;
}
}
/**
* Get the current Interaction Provider. Returns a specific one for this
* subsystem if it has been set, or falls back to the default one from
* RSECorePlugin otherwise.
*
* @return the interaction provider to use.
* @since 3.0
*/
public IRSEInteractionProvider getInteractionProvider() {
synchronized (this) {
if (_interactionProvider != null) {
return _interactionProvider;
}
}
return RSECorePlugin.getDefault().getDefaultInteractionProvider();
}
/**
* Internal method to select the appropriate command subsystem when there are multiple defined for this connection.
* The default implementation is to return the first, but child classes can refine this. Input is always an array of
@ -2908,7 +2940,7 @@ implements IAdaptable, ISubSystem, ISystemFilterPoolReferenceManagerProvider
// for other cases, use statusbar
IWorkbenchWindow win = SystemBasePlugin.getActiveWorkbenchWindow();
if (win != null) {
Shell winShell = getActiveWorkbenchShell();
Shell winShell = SystemBasePlugin.getActiveWorkbenchShell();
if (winShell != null && !winShell.isDisposed() && winShell.isVisible()) {
SystemBasePlugin.logInfo("Using active workbench window as runnable context"); //$NON-NLS-1$
shell = winShell;
@ -2935,41 +2967,6 @@ implements IAdaptable, ISubSystem, ISystemFilterPoolReferenceManagerProvider
return shell;
}
/**
* Helper/convenience method. Return shell of active window.
*/
public static Shell getActiveWorkbenchShell()
{
Shell result = null;
if (PlatformUI.isWorkbenchRunning())
{
try
{
IWorkbenchWindow window = getActiveWorkbenchWindow();
if (window != null)
{
result = window.getShell();
}
}
catch (Exception e)
{
return null;
}
}
else // workbench has not been loaded yet!
{
return null;
}
return result;
}
/**
* Helper/convenience method. Return active window
*/
public static IWorkbenchWindow getActiveWorkbenchWindow()
{
return RSEUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
}
/**
* <i><b>Private</b>. Do not override.</i>
* @generated This field/method will be replaced during code generation