| /******************************************************************************* |
| * Copyright (c) 2003, 2011 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 |
| *******************************************************************************/ |
| package org.eclipse.wst.server.ui.internal; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IResourceRuleFactory; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.ISchedulingRule; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.core.runtime.jobs.MultiRule; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.wst.server.core.IServer; |
| import org.eclipse.wst.server.core.IServer.IOperationListener; |
| /** |
| * Dialog that prompts a user to delete server(s) and/or server configuration(s). |
| */ |
| public class DeleteServerDialog extends MessageDialog { |
| protected IServer[] servers; |
| protected IFolder[] configs; |
| |
| protected List<IServer> runningServersList; |
| protected boolean runningServerCanStop; |
| |
| protected Button checkDeleteConfigs; |
| protected Button checkDeleteRunning; |
| protected Button checkDeleteRunningStop; |
| |
| /** |
| * DeleteServerDialog constructor comment. |
| * |
| * @param parentShell a shell |
| * @param servers an array of servers |
| * @param configs an array of server configurations |
| */ |
| public DeleteServerDialog(Shell parentShell, IServer[] servers, IFolder[] configs) { |
| super(parentShell, Messages.deleteServerDialogTitle, null, null, QUESTION, |
| new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0); |
| |
| if (servers == null || configs == null) |
| throw new IllegalArgumentException(); |
| |
| this.servers = servers; |
| this.configs = configs; |
| |
| runningServersList = new ArrayList<IServer>(); |
| for (int i = 0 ; i < servers.length ; ++i) { |
| if (servers[i].getServerState() != IServer.STATE_STOPPED) |
| runningServersList.add(servers[i]); |
| |
| if (servers[i].canStop().isOK()) |
| runningServerCanStop = true; |
| } |
| |
| if (servers.length == 1) |
| message = NLS.bind(Messages.deleteServerDialogMessage, servers[0].getName()); |
| else |
| message = NLS.bind(Messages.deleteServerDialogMessageMany, servers.length + ""); |
| } |
| |
| /** |
| * |
| */ |
| protected Control createCustomArea(Composite parent) { |
| // create a composite with standard margins and spacing |
| Composite composite = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); |
| layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); |
| layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
| layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| composite.setLayout(layout); |
| composite.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| composite.setFont(parent.getFont()); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, ContextIds.DELETE_SERVER_DIALOG); |
| |
| if (configs.length > 0) { |
| checkDeleteConfigs = new Button(composite, SWT.CHECK); |
| checkDeleteConfigs.setText(NLS.bind(Messages.deleteServerDialogLooseConfigurations, configs[0].getName())); |
| checkDeleteConfigs.setSelection(true); |
| } |
| |
| // prompt for stopping running servers |
| int size = runningServersList.size(); |
| if (size > 0) { |
| if (servers.length > 1) { |
| checkDeleteRunning = new Button(composite, SWT.CHECK); |
| checkDeleteRunning.setText(Messages.deleteServerDialogRunningServer); |
| checkDeleteRunning.setSelection(true); |
| } |
| |
| if (runningServerCanStop) { |
| checkDeleteRunningStop = new Button(composite, SWT.CHECK); |
| checkDeleteRunningStop.setText(Messages.deleteServerDialogRunningServerStop); |
| checkDeleteRunningStop.setSelection(true); |
| GridData data = new GridData(); |
| if (checkDeleteRunning != null) { |
| // Only indent the checkbox if the delete running servers checkbox is available. |
| data.horizontalIndent = 15; |
| checkDeleteRunning.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| checkDeleteRunningStop.setEnabled(checkDeleteRunning.getSelection()); |
| } |
| }); |
| } |
| checkDeleteRunningStop.setLayoutData(data); |
| } |
| } |
| |
| Dialog.applyDialogFont(composite); |
| |
| return composite; |
| } |
| |
| protected void buttonPressed(int buttonId) { |
| if (buttonId == OK) { |
| final boolean checked = (checkDeleteConfigs != null && checkDeleteConfigs.getSelection()); |
| final boolean deleteRunning = (checkDeleteRunning == null || checkDeleteRunning.getSelection()); |
| final boolean deleteRunningStop = (checkDeleteRunningStop != null && checkDeleteRunningStop.getSelection()); |
| |
| Thread t = new Thread("Delete servers") { |
| public void run() { |
| if (runningServersList.size() > 0) { |
| // stop servers and/or updates servers' list |
| prepareForDeletion(deleteRunning, deleteRunningStop); |
| } |
| |
| Job job = new Job(Messages.deleteServerTask) { |
| protected IStatus run(IProgressMonitor monitor) { |
| if (servers.length == 0) { |
| // all servers have been deleted from list |
| return Status.OK_STATUS; |
| } |
| try { |
| if (monitor.isCanceled()) |
| return Status.CANCEL_STATUS; |
| |
| int size = servers.length; |
| for (int i = 0; i < size; i++) |
| servers[i].delete(); |
| |
| if (monitor.isCanceled()) |
| return Status.CANCEL_STATUS; |
| |
| if (checked) { |
| size = configs.length; |
| for (int i = 0; i < size; i++) |
| configs[i].delete(true, true, monitor); |
| } |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, "Error while deleting resources", e); |
| } |
| return new Status(IStatus.ERROR, ServerUIPlugin.PLUGIN_ID, 0, e.getMessage(), e); |
| } |
| |
| return Status.OK_STATUS; |
| } |
| }; |
| |
| // set rule for workspace and servers |
| int size = servers.length; |
| ISchedulingRule[] rules = new ISchedulingRule[size+1]; |
| for (int i = 0; i < size; i++) |
| rules[i] = servers[i]; |
| IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory(); |
| rules[size] = ruleFactory.createRule(ResourcesPlugin.getWorkspace().getRoot()); |
| job.setRule(MultiRule.combine(rules)); |
| job.setPriority(Job.BUILD); |
| |
| job.schedule(); |
| } |
| }; |
| t.setDaemon(true); |
| t.start(); |
| } |
| super.buttonPressed(buttonId); |
| } |
| |
| /** |
| * Updates servers' & configs' lists. If <code>deleteRunning</code> is <code>true</code> |
| * and a server can't be stopped, it isn't removed. |
| * @param deleteRunning if <code>true</code> running servers will be stopped |
| * before being deleted, if <code>false</code> running servers will be removed |
| * from deletion list. |
| */ |
| protected void prepareForDeletion(boolean deleteRunning, boolean stopRunning) { |
| // converts servers & configs to list to facilitate removal |
| List<IServer> serversList = new LinkedList<IServer>(Arrays.asList(servers)); |
| List<IFolder> configsList = new LinkedList<IFolder>(Arrays.asList(configs)); |
| if (!deleteRunning) { |
| // don't delete servers or configurations |
| int size = runningServersList.size(); |
| for (int i = 0; i < size; i++) { |
| IServer server = runningServersList.get(i); |
| serversList.remove(server); |
| if (server.getServerConfiguration() != null) |
| configsList.remove(server.getServerConfiguration()); |
| } |
| } else { |
| if (stopRunning) { |
| // stop running servers and wait for them (stop is asynchronous) |
| IServer s; |
| MultiServerStopListener listener = new MultiServerStopListener(); |
| int expected = 0; |
| Iterator iter = runningServersList.iterator(); |
| while (iter.hasNext()) { |
| s = (IServer) iter.next(); |
| if (s.canStop().isOK()) { |
| ++expected; |
| s.stop(false, listener); |
| } else { |
| // server can't be stopped, don't delete it |
| serversList.remove(s); |
| configsList.remove(s.getServerConfiguration()); |
| } |
| } |
| try { |
| while (expected != listener.getNumberStopped()) { |
| Thread.sleep(200); |
| } |
| } catch (InterruptedException e) { |
| if (Trace.WARNING) { |
| Trace.trace(Trace.STRING_WARNING, "Interrupted while waiting for servers stop"); |
| } |
| } |
| } |
| } |
| servers = new IServer[serversList.size()]; |
| serversList.toArray(servers); |
| configs = new IFolder[configsList.size()]; |
| configsList.toArray(configs); |
| } |
| |
| /** |
| * Class used to wait all servers stop. Use one instance |
| * for a group of servers and loop to see if the number stopped |
| * equals the number of servers waiting to stop. |
| */ |
| class MultiServerStopListener implements IOperationListener { |
| protected int num; |
| |
| public void done(IStatus result) { |
| num++; |
| } |
| |
| public int getNumberStopped() { |
| return num; |
| } |
| } |
| } |