blob: 20a9d87c622f23b73e5db44bcc2bee395c4ef288 [file] [log] [blame]
lisaacs6d017052007-01-16 03:01:58 +00001/*******************************************************************************
lisaacsd4abc342008-02-23 00:18:31 +00002 * Copyright (c) 2007, 2008 SAS Institute, Inc. and others.
lisaacs6d017052007-01-16 03:01:58 +00003 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Larry Isaacs - Initial API and implementation
10 *******************************************************************************/
11package org.eclipse.jst.server.tomcat.ui.internal;
12
13import org.eclipse.core.runtime.CoreException;
lisaacs24d02bb2007-01-21 03:06:17 +000014import org.eclipse.core.runtime.IProgressMonitor;
lisaacs6d017052007-01-16 03:01:58 +000015import org.eclipse.core.runtime.IStatus;
16import org.eclipse.core.runtime.MultiStatus;
17import org.eclipse.core.runtime.Status;
lisaacs24d02bb2007-01-21 03:06:17 +000018import org.eclipse.core.runtime.jobs.IJobChangeEvent;
19import org.eclipse.core.runtime.jobs.Job;
20import org.eclipse.core.runtime.jobs.JobChangeAdapter;
lisaacs6d017052007-01-16 03:01:58 +000021import org.eclipse.jface.dialogs.Dialog;
22import org.eclipse.jface.dialogs.IDialogConstants;
23import org.eclipse.jst.server.core.IWebModule;
24import org.eclipse.jst.server.tomcat.core.internal.ITomcatWebModule;
25import org.eclipse.jst.server.tomcat.core.internal.TomcatServerBehaviour;
26import org.eclipse.jst.server.tomcat.core.internal.WebModule;
27import org.eclipse.osgi.util.NLS;
28import org.eclipse.swt.SWT;
29import org.eclipse.swt.layout.GridData;
30import org.eclipse.swt.widgets.Button;
31import org.eclipse.swt.widgets.Composite;
32import org.eclipse.swt.widgets.Control;
33import org.eclipse.swt.widgets.Label;
34import org.eclipse.swt.widgets.Shell;
lisaacse9d08412007-01-24 23:40:28 +000035import org.eclipse.ui.PlatformUI;
lisaacs6d017052007-01-16 03:01:58 +000036import org.eclipse.wst.server.core.IModule;
37import org.eclipse.wst.server.core.IServer;
lisaacse9d08412007-01-24 23:40:28 +000038import org.eclipse.wst.server.core.ServerUtil;
lisaacs6d017052007-01-16 03:01:58 +000039import org.eclipse.wst.server.core.IServer.IOperationListener;
40
41/**
42 * Dialog to confirm deletion of the work directory for a module on a
43 * server, or the work directory for the entire server. Handling
44 * includes stopping and restarting the server if it is running at
45 * the time of the deletion.
46 *
47 */
48public class CleanWorkDirDialog extends Dialog {
lisaacs6d017052007-01-16 03:01:58 +000049 protected IServer server;
50 protected IModule module;
51 protected int state;
52 protected String mode;
lisaacs465f2c22008-02-19 21:16:58 +000053 protected IStatus completionStatus;
lisaacs6d017052007-01-16 03:01:58 +000054
55 /**
56 * Creates a dialog instance confirm deletion of the work directory for a
57 * module on a server, or the work directory for the entire server.
58 *
59 * @param parentShell the parent shell, or <code>null</code> to create a
60 * top-level shell
61 * @param server server on which to delete the work directory
62 * @param module module whose work directory is to be deleted, or <code>null</code> if
63 * if these server's entire work directory is to be deleted.
64 */
65 public CleanWorkDirDialog(Shell parentShell, IServer server, IModule module) {
66 super(parentShell);
67
68 if (server == null)
69 throw new IllegalArgumentException();
70
71 this.server = server;
72 this.module = module;
73
74 }
75
lisaacs6d017052007-01-16 03:01:58 +000076 protected void configureShell(Shell newShell) {
77 super.configureShell(newShell);
78 newShell.setText(Messages.confirmCleanWorkDirTitle);
79 }
80
81 protected Control createDialogArea(Composite parent) {
82 if (state < 0 || state == IServer.STATE_UNKNOWN)
83 captureServerState();
84
85 // create a composite with standard margins and spacing
86 Composite composite = (Composite)super.createDialogArea(parent);
lisaacse9d08412007-01-24 23:40:28 +000087 // Since there are only label widgets on this page, set the help on the parent
88 PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, ContextIds.SERVER_CLEAN_WORK_DIR);
lisaacs6d017052007-01-16 03:01:58 +000089
90 Label label = new Label(composite, SWT.WRAP);
91 if (state == IServer.STATE_STARTING || state == IServer.STATE_STOPPING || state == IServer.STATE_UNKNOWN) {
92 label.setText(NLS.bind(Messages.cleanServerStateChanging, server.getName()));
93 }
94 else {
95 if (module != null)
96 label.setText(NLS.bind(Messages.cleanModuleWorkDir, module.getName(), server.getName()));
97 else
98 label.setText(NLS.bind(Messages.cleanServerWorkDir, server.getName()));
99 GridData data = new GridData();
100 data.widthHint = 300;
101 label.setLayoutData(data);
102
103 if (state == IServer.STATE_STARTED) {
104 label = new Label(composite, SWT.WRAP);
105 label.setText(Messages.cleanServerRunning);
106 data = new GridData();
107 data.widthHint = 300;
108 label.setLayoutData(data);
109 }
110 }
111
112 applyDialogFont(composite);
113 return composite;
114 }
115
116 protected void createButtonsForButtonBar(Composite parent) {
117 super.createButtonsForButtonBar(parent);
118
119 if (state < 0 || state == IServer.STATE_UNKNOWN)
120 captureServerState();
121
122 // If server is transitioning, only allow Cancel
123 if (state == IServer.STATE_STARTING || state == IServer.STATE_STOPPING) {
124 Button button = getButton(IDialogConstants.OK_ID);
125 if (button != null)
126 button.setEnabled(false);
127 }
128 }
129
130 protected void okPressed() {
lisaacs8832d442008-04-24 01:04:51 +0000131 String jobName = NLS.bind(Messages.cleanServerTask,
132 module != null ? module.getName() : server.getName());
133 // Create job to perform the cleaning, including stopping and starting the server if necessary
134 CleanWorkDirJob job = new CleanWorkDirJob(jobName);
135 // Note: Since stop and start, if needed, will set scheduling rules in their jobs,
136 // don't set one here. Instead do the actual deletion in a child job too with the
137 // scheduling rule on that job, like stop and start.
lisaacs24d02bb2007-01-21 03:06:17 +0000138 job.schedule();
139
140 super.okPressed();
141 }
142
lisaacs8832d442008-04-24 01:04:51 +0000143 /*
144 * Job to clean the appropriate Tomcat work directory. It includes
145 * stopping and starting the server if the server is currently running.
146 * The stopping, deletion, and starting are all done with child jobs,
147 * each using the server scheduling rule. Thus, this job should
148 * not use this rule or it will block these child jobs.
149 */
150 class CleanWorkDirJob extends Job {
lisaacs24d02bb2007-01-21 03:06:17 +0000151 /**
152 * @param name name for job
153 */
lisaacs8832d442008-04-24 01:04:51 +0000154 public CleanWorkDirJob(String jobName) {
155 super(jobName);
lisaacs6d017052007-01-16 03:01:58 +0000156 }
lisaacs24d02bb2007-01-21 03:06:17 +0000157
lisaacs3e5cf8a2007-02-10 20:37:23 +0000158 /**
159 * @see Job#belongsTo(Object)
160 */
161 public boolean belongsTo(Object family) {
162 return ServerUtil.SERVER_JOB_FAMILY.equals(family);
163 }
164
lisaacs24d02bb2007-01-21 03:06:17 +0000165 protected IStatus run(IProgressMonitor monitor) {
lisaacs465f2c22008-02-19 21:16:58 +0000166 final Object mutex = new Object();
lisaacs8832d442008-04-24 01:04:51 +0000167
168 IWebModule webModule = null;
169 if (module != null) {
170 webModule = (IWebModule)module.loadAdapter(IWebModule.class, null);
171 if (webModule == null) {
172 return newErrorStatus(NLS.bind(Messages.errorCantIdentifyWebApp, module.getName()), null);
173 }
174 }
lisaacs465f2c22008-02-19 21:16:58 +0000175
lisaacs24d02bb2007-01-21 03:06:17 +0000176 // If state has changed since dialog was open, abort
177 if (server.getServerState() != state) {
lisaacs8832d442008-04-24 01:04:51 +0000178 return newErrorStatus(
179 NLS.bind(Messages.errorCouldNotCleanStateChange, server.getName()), null);
lisaacs24d02bb2007-01-21 03:06:17 +0000180 }
181
182 IOperationListener listener = new IOperationListener() {
183 public void done(IStatus result) {
lisaacs465f2c22008-02-19 21:16:58 +0000184 synchronized (mutex) {
185 completionStatus = result;
186 mutex.notifyAll();
187 }
lisaacs24d02bb2007-01-21 03:06:17 +0000188 }
189 };
lisaacs8832d442008-04-24 01:04:51 +0000190
lisaacs24d02bb2007-01-21 03:06:17 +0000191 boolean restart = false;
192 IStatus status = Status.OK_STATUS;
193 // If server isn't stopped, try to stop, clean, and restart
194 if (state != IServer.STATE_STOPPED) {
195 status = server.canStop();
196 if (!status.isOK()) {
lisaacs8832d442008-04-24 01:04:51 +0000197 return wrapErrorStatus(status,
198 NLS.bind(Messages.errorCouldNotCleanCantStop, server.getName()));
lisaacs24d02bb2007-01-21 03:06:17 +0000199 }
200
lisaacs8832d442008-04-24 01:04:51 +0000201 boolean done = false;
202 boolean force = false;
203 while (!done) {
204 // Stop the server and wait for completion
205 synchronized (mutex) {
206 server.stop(force, listener);
lisaacs24d02bb2007-01-21 03:06:17 +0000207
lisaacs8832d442008-04-24 01:04:51 +0000208 while (completionStatus == null) {
209 try {
210 mutex.wait();
211 } catch (InterruptedException e) {
212 // Ignore
213 }
lisaacs465f2c22008-02-19 21:16:58 +0000214 }
215 }
lisaacs8832d442008-04-24 01:04:51 +0000216 // If forced, or there was an error (doesn't include timeout), or we are stopped, time to exit
217 if (force || !completionStatus.isOK() || server.getServerState() == IServer.STATE_STOPPED) {
218 done = true;
219 }
220 else {
221 force = TomcatUIPlugin.queryCleanTermination(server);
222 completionStatus = null;
223 }
lisaacs465f2c22008-02-19 21:16:58 +0000224 }
lisaacs8832d442008-04-24 01:04:51 +0000225
lisaacs24d02bb2007-01-21 03:06:17 +0000226 if (!completionStatus.isOK()) {
lisaacs8832d442008-04-24 01:04:51 +0000227 // If stop job failed, assume error was displayed for that job
228 return Status.OK_STATUS;
lisaacs24d02bb2007-01-21 03:06:17 +0000229 }
230 if (server.getServerState() != IServer.STATE_STOPPED) {
lisaacs8832d442008-04-24 01:04:51 +0000231 return newErrorStatus(
232 NLS.bind(Messages.errorCouldNotCleanStopFailed, server.getName()), null);
lisaacs24d02bb2007-01-21 03:06:17 +0000233 }
234 restart = true;
lisaacs465f2c22008-02-19 21:16:58 +0000235 completionStatus = null;
lisaacs24d02bb2007-01-21 03:06:17 +0000236 }
lisaacs8832d442008-04-24 01:04:51 +0000237
238 DeleteWorkDirJob deleteJob = new DeleteWorkDirJob(getName(), webModule, restart);
239 deleteJob.setRule(ServerUtil.getServerSchedulingRule(server));
240
241 deleteJob.addJobChangeListener(new JobChangeAdapter() {
242 public void done(IJobChangeEvent event) {
243 synchronized (mutex) {
244 completionStatus = event.getResult();
245 mutex.notifyAll();
lisaacs24d02bb2007-01-21 03:06:17 +0000246 }
lisaacs8832d442008-04-24 01:04:51 +0000247
248 }
249 });
250
251 // Perform the work directory deletion job
252 synchronized (mutex) {
253 deleteJob.schedule();
254
255 while (completionStatus == null) {
256 try {
257 mutex.wait();
258 } catch (InterruptedException e) {
259 // Ignore
lisaacs24d02bb2007-01-21 03:06:17 +0000260 }
lisaacs6d017052007-01-16 03:01:58 +0000261 }
lisaacs24d02bb2007-01-21 03:06:17 +0000262 }
lisaacs8832d442008-04-24 01:04:51 +0000263 if (!completionStatus.isOK()) {
264 // If delete job failed, assume error was displayed for that job
265 return Status.OK_STATUS;
lisaacs24d02bb2007-01-21 03:06:17 +0000266 }
lisaacs8832d442008-04-24 01:04:51 +0000267 completionStatus = null;
lisaacs465f2c22008-02-19 21:16:58 +0000268
lisaacs24d02bb2007-01-21 03:06:17 +0000269 if (restart) {
270 status = server.canStart(mode);
271 if (!status.isOK()) {
lisaacs8832d442008-04-24 01:04:51 +0000272 return wrapErrorStatus(status,
273 NLS.bind(Messages.errorCleanCantRestart, server.getName()));
lisaacs24d02bb2007-01-21 03:06:17 +0000274 }
lisaacs465f2c22008-02-19 21:16:58 +0000275
276 // Restart the server and wait for completion
277 synchronized (mutex) {
278 server.start(mode, listener);
279
280 while (completionStatus == null) {
281 try {
282 mutex.wait();
283 } catch (InterruptedException e) {
284 // Ignore
285 }
286 }
287 }
288
lisaacs24d02bb2007-01-21 03:06:17 +0000289 if (!completionStatus.isOK()) {
lisaacs8832d442008-04-24 01:04:51 +0000290 // If start job failed, assume error was displayed for that job
291 return Status.OK_STATUS;
lisaacs6d017052007-01-16 03:01:58 +0000292 }
293 }
lisaacs24d02bb2007-01-21 03:06:17 +0000294 return status;
lisaacs6d017052007-01-16 03:01:58 +0000295 }
lisaacs6d017052007-01-16 03:01:58 +0000296 }
297
lisaacs8832d442008-04-24 01:04:51 +0000298 /*
299 * Job to actually delete the work directory. This is done
300 * in a separate job so it can be a "sibling" of potential
301 * stop and start jobs. This allows it to have a server
302 * scheduling rule.
303 */
304 class DeleteWorkDirJob extends Job {
305 private IWebModule webModule;
306 private boolean restart;
307
308 /**
309 * @param name name for job
310 */
311 public DeleteWorkDirJob(String jobName, IWebModule webModule, boolean restart) {
312 super(jobName);
313 this.webModule = webModule;
314 this.restart = restart;
315 }
316
317 /**
318 * @see Job#belongsTo(Object)
319 */
320 public boolean belongsTo(Object family) {
321 return ServerUtil.SERVER_JOB_FAMILY.equals(family);
322 }
323
324 protected IStatus run(IProgressMonitor monitor) {
325
326 IStatus status = Status.OK_STATUS;
327 // If server isn't stopped, abort the attempt to delete the work directory
328 if (server.getServerState() != IServer.STATE_STOPPED) {
329 return newErrorStatus(
330 NLS.bind(Messages.errorCantDeleteServerNotStopped,
331 webModule != null ? module.getName() : server.getName()), null);
332 }
333
334 // Delete the work directory
335 TomcatServerBehaviour tsb = (TomcatServerBehaviour)server.loadAdapter(
336 TomcatServerBehaviour.class, monitor);
337 try {
338 if (webModule != null) {
339 ITomcatWebModule tcWebModule = new WebModule(webModule.getContextRoot(), "", "", true);
340 status = tsb.cleanContextWorkDir(tcWebModule, null);
341 }
342 else {
343 status = tsb.cleanServerWorkDir(null);
344 }
345 } catch (CoreException ce) {
346 status = ce.getStatus();
347 }
348 if (!status.isOK()) {
349 String cleanName = module != null ? module.getName() : server.getName();
350 return wrapErrorStatus(status,
351 restart ?
352 NLS.bind(Messages.errorErrorDuringCleanWasRunning,
353 cleanName , server.getName()) :
354 NLS.bind(Messages.errorErrorDuringClean, cleanName));
355 }
356 return status;
357 }
358 }
359
lisaacs6d017052007-01-16 03:01:58 +0000360 private void captureServerState() {
361 state = server.getServerState();
362 if (state != IServer.STATE_STOPPED) {
363 mode = server.getMode();
364 }
365 }
366
lisaacs8832d442008-04-24 01:04:51 +0000367 protected IStatus newErrorStatus(String message, Throwable throwable) {
368 return new Status(IStatus.ERROR, TomcatUIPlugin.PLUGIN_ID, 0,
lisaacs6d017052007-01-16 03:01:58 +0000369 message, throwable);
370 }
371
lisaacs8832d442008-04-24 01:04:51 +0000372 protected IStatus wrapErrorStatus(IStatus status, String message) {
373 MultiStatus ms = new MultiStatus(TomcatUIPlugin.PLUGIN_ID, 0, message, null);
lisaacs24d02bb2007-01-21 03:06:17 +0000374 ms.add(status);
375 return ms;
lisaacs6d017052007-01-16 03:01:58 +0000376 }
377}