| package org.eclipse.wst.server.ui.internal.actions; |
| /********************************************************************** |
| * Copyright (c) 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| **********************************************************************/ |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.jface.wizard.WizardDialog; |
| import org.eclipse.wst.server.core.*; |
| import org.eclipse.wst.server.core.model.*; |
| import org.eclipse.wst.server.ui.ServerUIUtil; |
| import org.eclipse.wst.server.ui.internal.*; |
| import org.eclipse.wst.server.ui.internal.wizard.*; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.IWorkbenchWindowActionDelegate; |
| |
| /** |
| * Support for starting/stopping server and clients for resources running on a server. |
| */ |
| public class RunOnServerActionDelegate implements IWorkbenchWindowActionDelegate { |
| protected static final String[] launchModes = { |
| ILaunchManager.RUN_MODE, ILaunchManager.DEBUG_MODE, ILaunchManager.PROFILE_MODE }; |
| |
| protected Object selection; |
| |
| protected IWorkbenchWindow window; |
| |
| protected static boolean initialized = false; |
| |
| protected static Object globalSelection; |
| |
| protected static Map globalLaunchMode; |
| |
| private static transient List propertyListeners; |
| |
| /** |
| * RunOnServerActionDelegate constructor comment. |
| */ |
| public RunOnServerActionDelegate() { |
| super(); |
| } |
| |
| /** |
| * Disposes this action delegate. The implementor should unhook any references |
| * to itself so that garbage collection can occur. |
| */ |
| public void dispose() { |
| window = null; |
| } |
| |
| /** |
| * Initializes this action delegate with the workbench window it will work in. |
| * |
| * @param window the window that provides the context for this delegate |
| */ |
| public void init(IWorkbenchWindow newWindow) { |
| window = newWindow; |
| } |
| |
| /** |
| * Add a property change listener to this server. |
| * |
| * @param listener java.beans.PropertyChangeListener |
| */ |
| public static void addPropertyChangeListener(PropertyChangeListener listener) { |
| if (propertyListeners == null) |
| propertyListeners = new ArrayList(); |
| propertyListeners.add(listener); |
| } |
| |
| /** |
| * Remove a property change listener from this server. |
| * |
| * @param listener java.beans.PropertyChangeListener |
| */ |
| public static void removePropertyChangeListener(PropertyChangeListener listener) { |
| if (propertyListeners != null) |
| propertyListeners.remove(listener); |
| } |
| |
| /** |
| * Fire a property change event. |
| */ |
| protected void firePropertyChangeEvent(String propertyName, Object oldValue, Object newValue) { |
| if (propertyListeners == null) |
| return; |
| |
| PropertyChangeEvent event = new PropertyChangeEvent(this, propertyName, oldValue, newValue); |
| try { |
| Iterator iterator = propertyListeners.iterator(); |
| while (iterator.hasNext()) { |
| try { |
| PropertyChangeListener listener = (PropertyChangeListener) iterator.next(); |
| listener.propertyChange(event); |
| } catch (Exception e) { |
| Trace.trace("Error firing property change event", e); |
| } |
| } |
| } catch (Exception e) { |
| Trace.trace("Error in property event", e); |
| } |
| } |
| |
| /** |
| * Run the resource on a server. |
| * |
| * @param monitor org.eclipse.core.runtime.IProgressMonitor |
| */ |
| protected void run(IProgressMonitor monitor) { |
| String launchMode = getLaunchMode(); |
| firePropertyChangeEvent("launchMode", null, launchMode); |
| |
| List moduleObjects = ServerUtil.getModuleObjects(selection); |
| |
| Shell shell; |
| if (window != null) |
| shell = window.getShell(); |
| else |
| shell = ServerUIPlugin.getInstance().getWorkbench().getActiveWorkbenchWindow().getShell(); |
| |
| if (moduleObjects == null || moduleObjects.isEmpty()) { |
| EclipseUtil.openError(ServerUIPlugin.getResource("%errorNoModules")); |
| Trace.trace(Trace.FINEST, "No modules"); |
| return; |
| } |
| IModule module = ((IModuleObject) moduleObjects.get(0)).getModule(); |
| if (moduleObjects.size() > 1) { |
| // check if the modules are all in the same module |
| int size = moduleObjects.size(); |
| for (int i = 0; i < size; i++) { |
| IModule module2 = ((IModuleObject) moduleObjects.get(i)).getModule(); |
| if (!module.equals(module2)) { |
| EclipseUtil.openError("Too many module objects"); |
| Trace.trace(Trace.SEVERE, "Too many module objects! Unsupported!"); |
| return; |
| } |
| } |
| } |
| |
| // check for servers with the given start mode |
| Iterator iterator = ServerCore.getResourceManager().getServers().iterator(); |
| boolean found = false; |
| while (!found && iterator.hasNext()) { |
| IServer server = (IServer) iterator.next(); |
| if (ServerUtil.isCompatibleWithLaunchMode(server, launchMode)) { |
| try { |
| List parents = server.getParentModules(module); |
| if (parents != null && parents.size() > 0) |
| found = true; |
| } catch (Exception e) { } |
| } |
| } |
| |
| if (!found) { |
| // no existing server supports the project and start mode! |
| // check if there might be another one that can be created |
| iterator = ServerCore.getServerTypes().iterator(); |
| boolean found2 = false; |
| while (!found2 && iterator.hasNext()) { |
| IServerType type = (IServerType) iterator.next(); |
| List moduleTypes = type.getRuntimeType().getModuleTypes(); |
| if (type.supportsLaunchMode(launchMode) && ServerUtil.isSupportedModule(moduleTypes, module.getType(), module.getVersion())) { |
| found2 = true; |
| } |
| } |
| if (!found2) { |
| EclipseUtil.openError(ServerUIPlugin.getResource("%errorNoServer")); |
| Trace.trace(Trace.FINEST, "No server for start mode"); |
| return; |
| } |
| } |
| |
| if (!ServerUIUtil.saveEditors()) |
| return; |
| |
| IServer server = null; |
| if (module instanceof IProjectModule) { |
| IProjectModule dp = (IProjectModule) module; |
| server = ServerCore.getProjectProperties(dp.getProject()).getDefaultServer(); |
| } |
| |
| // ignore preference if the server doesn't support this mode. |
| if (server != null && !ServerUtil.isCompatibleWithLaunchMode(server, launchMode)) |
| server = null; |
| |
| boolean tasksRun = false; |
| if (server == null) { |
| // try the full wizard |
| SelectServerWizard wizard = new SelectServerWizard(module, launchMode); |
| ClosableWizardDialog dialog = new ClosableWizardDialog(shell, wizard); |
| if (dialog.open() == Window.CANCEL) { |
| return; |
| } |
| |
| server = wizard.getServer(); |
| boolean preferred = wizard.isPreferredServer(); |
| tasksRun = true; |
| |
| // set preferred server if requested |
| if (server != null && preferred && module instanceof IProjectModule) { |
| try { |
| IProjectModule dp = (IProjectModule) module; |
| ServerCore.getProjectProperties(dp.getProject()).setDefaultServer(server, new NullProgressMonitor()); |
| } catch (CoreException ce) { |
| String message = ServerUIPlugin.getResource("%errorCouldNotSavePreference"); |
| ErrorDialog.openError(shell, ServerUIPlugin.getResource("%errorDialogTitle"), message, ce.getStatus()); |
| } |
| } |
| } |
| Trace.trace(Trace.FINEST, "Server: " + server); |
| |
| if (server == null) { |
| EclipseUtil.openError(ServerUIPlugin.getResource("%errorNoServer")); |
| Trace.trace(Trace.SEVERE, "No server found"); |
| return; |
| } |
| |
| if (!ServerUIUtil.promptIfDirty(shell, server)) |
| return; |
| |
| if (!tasksRun) { |
| SelectTasksWizard wizard = getTasksWizard(server, module); |
| if (wizard.hasTasks() && wizard.hasOptionalTasks()) { |
| WizardDialog dialog = new WizardDialog(shell, wizard); |
| if (dialog.open() == Window.CANCEL) |
| return; |
| } else |
| wizard.performFinish(); |
| } |
| |
| ILaunchable launchable = ServerUtil.getLaunchable(server, moduleObjects); |
| List list = new ArrayList(); |
| if (launchable != null) |
| list = ServerUtil.getLaunchableClients(server, launchable, launchMode); |
| |
| Trace.trace(Trace.FINEST, "Launchable clients: " + list); |
| |
| IClient client = null; |
| if (list == null || list.isEmpty()) { |
| EclipseUtil.openError(ServerUIPlugin.getResource("%errorNoClient")); |
| Trace.trace(Trace.SEVERE, "No launchable clients!"); |
| return; |
| } else if (list.size() == 1) { |
| client = (IClient) list.get(0); |
| } else { |
| SelectClientWizard wizard = new SelectClientWizard(list); |
| ClosableWizardDialog dialog = new ClosableWizardDialog(shell, wizard); |
| dialog.open(); |
| client = wizard.getSelectedClient(); |
| if (client == null) |
| return; |
| } |
| |
| Trace.trace(Trace.FINEST, "Ready to launch"); |
| |
| final IServerPreferences preferences = ServerCore.getServerPreferences(); |
| |
| // start server if it's not already started |
| // and cue the client to start |
| byte state = server.getServerState(); |
| if (state == IServer.SERVER_STARTING) { |
| ServerStartupListener listener = new ServerStartupListener(shell, server, client, launchable, launchMode, module); |
| listener.setEnabled(true); |
| } else if (state == IServer.SERVER_STARTED || state == IServer.SERVER_STARTED_DEBUG || state == IServer.SERVER_STARTED_PROFILE) { |
| boolean restart = false; |
| if (state != IServer.SERVER_STARTED_DEBUG && ILaunchManager.DEBUG_MODE.equals(launchMode)) { |
| int result = openWarningDialog(shell, ServerUIPlugin.getResource("%dialogModeWarningDebug")); |
| if (result == 1) { |
| if (state == IServer.SERVER_STARTED) |
| launchMode = ILaunchManager.RUN_MODE; |
| else |
| launchMode = ILaunchManager.PROFILE_MODE; |
| } else if (result == 0) |
| restart = true; |
| else |
| return; |
| } else if (state != IServer.SERVER_STARTED_PROFILE && ILaunchManager.PROFILE_MODE.equals(launchMode)) { |
| int result = openWarningDialog(shell, ServerUIPlugin.getResource("%dialogModeWarningProfile")); |
| if (result == 1) { |
| if (state == IServer.SERVER_STARTED) |
| launchMode = ILaunchManager.RUN_MODE; |
| else |
| launchMode = ILaunchManager.DEBUG_MODE; |
| } else if (result == 0) |
| restart = true; |
| else |
| return; |
| } |
| if (restart) { |
| server.synchronousStop(); |
| |
| ServerStartupListener listener = new ServerStartupListener(shell, server, client, launchable, launchMode, module); |
| if (preferences.isAutoPublishing() && !autoPublish(server)) |
| return; |
| |
| try { |
| EclipseUtil.startServer(shell, server, launchMode, listener); |
| } catch (CoreException e) { } |
| } else { |
| if (preferences.isAutoPublishing() && !autoPublish(server)) |
| return; |
| |
| // open client |
| ServerStartupListener.launchClientUtil(server, module, launchable, launchMode, client); |
| } |
| } else if (state != IServer.SERVER_STOPPING) { |
| ServerStartupListener listener = new ServerStartupListener(shell, server, client, launchable, launchMode, module); |
| if (preferences.isAutoPublishing() && !autoPublish(server)) |
| return; |
| |
| try { |
| EclipseUtil.startServer(shell, server, launchMode, listener); |
| } catch (CoreException e) { } |
| } |
| } |
| |
| private SelectTasksWizard getTasksWizard(IServer server, IModule module) { |
| // ---- temp |
| class Helper { |
| List parentList = new ArrayList(); |
| List moduleList = new ArrayList(); |
| } |
| final Helper help = new Helper(); |
| ServerUtil.visit(server, new IModuleVisitor() { |
| public boolean visit(List parents, IModule module2) { |
| help.parentList.add(parents); |
| help.moduleList.add(module2); |
| return true; |
| } |
| }); |
| if (!help.moduleList.contains(module)) { |
| help.parentList.add(new ArrayList()); // FIX-ME |
| help.moduleList.add(module); |
| } |
| int size = help.parentList.size(); |
| List[] parents = new List[size]; |
| help.parentList.toArray(parents); |
| IModule[] modules = new IModule[size]; |
| help.moduleList.toArray(modules); |
| // ---- temp |
| |
| return new SelectTasksWizard(server, server.getServerConfiguration(), parents, modules); |
| } |
| |
| /** |
| * Automatically publish to the given server. |
| * |
| * @param server |
| * @return boolean - false if the current operation should be stopped |
| */ |
| protected boolean autoPublish(IServer server) { |
| // publish first |
| if (server.shouldPublish()) { |
| IStatus publishStatus = ServerUIUtil.publishWithDialog(server, false); |
| |
| if (publishStatus == null || publishStatus.getSeverity() == IStatus.ERROR) |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Open a message dialog. |
| * |
| * @param shell |
| * @param message |
| * @return |
| */ |
| protected int openWarningDialog(Shell shell, String message) { |
| MessageDialog dialog = new MessageDialog(shell, ServerUIPlugin.getResource("%errorDialogTitle"), null, |
| message, MessageDialog.WARNING, new String[] {ServerUIPlugin.getResource("%dialogModeWarningRestart"), |
| ServerUIPlugin.getResource("%dialogModeWarningContinue"), IDialogConstants.CANCEL_LABEL}, 0); |
| return dialog.open(); |
| } |
| |
| /** |
| * The delegating action has been performed. Implement |
| * this method to do the actual work. |
| * |
| * @param action action proxy that handles the presentation |
| * portion of the plugin action |
| */ |
| public void run(IAction action) { |
| Trace.trace(Trace.FINEST, "Running on Server..."); |
| if (!initialized) { |
| initialized = true; |
| |
| Iterator iterator = ServerCore.getModuleFactories().iterator(); |
| while (iterator.hasNext()) { |
| IModuleFactory factory = (IModuleFactory) iterator.next(); |
| factory.getModules(); |
| } |
| |
| try { |
| IModule module = ServerUtil.getModule(globalSelection, true); |
| findGlobalLaunchModes(module); |
| action.setEnabled(isEnabled()); |
| } catch (Exception e) { } |
| if (!isEnabled()) { |
| EclipseUtil.openError(ServerUIPlugin.getResource("%errorNoServer")); |
| Trace.trace(Trace.FINEST, "Uninitialized"); |
| return; |
| } |
| } |
| |
| try { |
| run(new NullProgressMonitor()); |
| } catch (Exception e) { |
| Trace.trace(Trace.SEVERE, "Run on Server Error", e); |
| } |
| } |
| |
| protected boolean isEnabled() { |
| try { |
| Boolean b = (Boolean) globalLaunchMode.get(getLaunchMode()); |
| return b.booleanValue(); |
| } catch (Exception e) { } |
| return false; |
| } |
| |
| /** |
| * Returns the start mode that the server should use. |
| */ |
| protected String getLaunchMode() { |
| return ILaunchManager.RUN_MODE; |
| } |
| |
| /** |
| * Determine which clients can act on the current selection. |
| * |
| * @param action action proxy that handles presentation |
| * portion of the plugin action |
| * @param selection current selection in the desktop |
| */ |
| public void selectionChanged(IAction action, ISelection sel) { |
| Trace.trace(Trace.FINEST, "> selectionChanged"); |
| selection = null; |
| long time = System.currentTimeMillis(); |
| if (sel == null || sel.isEmpty() || !(sel instanceof IStructuredSelection)) { |
| action.setEnabled(false); |
| globalSelection = null; |
| return; |
| } |
| |
| IStructuredSelection select = (IStructuredSelection) sel; |
| Iterator iterator = select.iterator(); |
| selection = iterator.next(); |
| if (iterator.hasNext()) { // more than one selection (should never happen) |
| action.setEnabled(false); |
| selection = null; |
| globalSelection = null; |
| return; |
| } |
| |
| if (selection != globalSelection || !initialized) { |
| Trace.trace(Trace.FINEST, "Selection: " + selection); |
| if (selection != null) |
| Trace.trace(Trace.FINEST, "Selection type: " + selection.getClass().getName()); |
| globalSelection = selection; |
| globalLaunchMode = new HashMap(); |
| try { |
| Trace.trace(Trace.FINEST, "calling getModule() " + initialized); |
| IModule module = ServerUtil.getModule(globalSelection, initialized); |
| Trace.trace(Trace.FINEST, "module: " + module); |
| findGlobalLaunchModes(module); |
| } catch (Exception e) { |
| Trace.trace(Trace.FINEST, "not initialized"); |
| globalLaunchMode.put(ILaunchManager.RUN_MODE, new Boolean(true)); |
| globalLaunchMode.put(ILaunchManager.DEBUG_MODE, new Boolean(true)); |
| globalLaunchMode.put(ILaunchManager.PROFILE_MODE, new Boolean(true)); |
| } |
| } |
| |
| action.setEnabled(isEnabled()); |
| Trace.trace(Trace.FINEST, "< selectionChanged " + (System.currentTimeMillis() - time)); |
| } |
| |
| /** |
| * Determines whether there is a server factory available for the given module |
| * and the various start modes. |
| */ |
| protected boolean findGlobalLaunchModes(IModule module) { |
| Iterator iterator = ServerCore.getServerTypes().iterator(); |
| while (iterator.hasNext()) { |
| IServerType type = (IServerType) iterator.next(); |
| if (isValidServerType(type, module)) { |
| for (byte b = 0; b < launchModes.length; b++) { |
| if (type.supportsLaunchMode(launchModes[b])) { |
| globalLaunchMode.put(launchModes[b], new Boolean(true)); |
| } |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Returns true if the given server type can launch the module. |
| */ |
| protected boolean isValidServerType(IServerType type, IModule module) { |
| try { |
| IRuntimeType runtimeType = type.getRuntimeType(); |
| ServerUtil.isSupportedModule(runtimeType.getModuleTypes(), module.getType(), module.getVersion()); |
| } catch (Exception e) { |
| return false; |
| } |
| return true; |
| } |
| |
| protected boolean supportsLaunchMode(IServer server, String launchMode) { |
| return server.getServerType().supportsLaunchMode(launchMode); |
| } |
| } |