001: package org.eclipse.ui.examples.jobs.views;
002:
003: import java.lang.reflect.InvocationTargetException;
004:
005: import org.eclipse.core.resources.IWorkspaceRunnable;
006: import org.eclipse.core.resources.ResourcesPlugin;
007: import org.eclipse.core.runtime.*;
008: import org.eclipse.core.runtime.jobs.Job;
009: import org.eclipse.jface.action.Action;
010: import org.eclipse.jface.dialogs.IDialogConstants;
011: import org.eclipse.jface.dialogs.MessageDialog;
012: import org.eclipse.jface.operation.IRunnableWithProgress;
013: import org.eclipse.swt.SWT;
014: import org.eclipse.swt.events.SelectionAdapter;
015: import org.eclipse.swt.events.SelectionEvent;
016: import org.eclipse.swt.layout.GridData;
017: import org.eclipse.swt.layout.GridLayout;
018: import org.eclipse.swt.widgets.*;
019: import org.eclipse.ui.PlatformUI;
020: import org.eclipse.ui.actions.WorkspaceModifyOperation;
021: import org.eclipse.ui.examples.jobs.TestJob;
022: import org.eclipse.ui.examples.jobs.TestJobRule;
023: import org.eclipse.ui.examples.jobs.UITestJob;
024: import org.eclipse.ui.part.ViewPart;
025: import org.eclipse.ui.progress.IProgressConstants;
026: import org.eclipse.ui.progress.IProgressService;
027:
028: /**
029: * A view that allows a user to create jobs of various types, and interact with
030: * and test other job-related APIs.
031: */
032: public class JobsView extends ViewPart {
033: private Combo durationField;
034: private Button lockField, failureField, threadField, systemField,
035: userField, groupField, rescheduleField, keepField,
036: keepOneField, unknownField, gotoActionField;
037: private Text quantityField, delayField, rescheduleDelay;
038: private Button schedulingRuleField;
039: private Button noPromptField;
040:
041: protected void busyCursorWhile() {
042: try {
043: final long duration = getDuration();
044: final boolean shouldLock = lockField.getSelection();
045: PlatformUI.getWorkbench().getProgressService()
046: .busyCursorWhile(new IRunnableWithProgress() {
047: public void run(IProgressMonitor monitor) {
048: if (shouldLock)
049: doRunInWorkspace(duration, monitor);
050: else
051: doRun(duration, monitor);
052: }
053:
054: });
055: } catch (InvocationTargetException e) {
056: e.printStackTrace();
057: } catch (InterruptedException e) {
058: // ignore - interrupt means cancel in this context
059: }
060: }
061:
062: protected void createJobs() {
063: int jobCount = Integer.parseInt(quantityField.getText());
064: boolean ui = threadField.getSelection();
065: long duration = getDuration();
066: boolean lock = lockField.getSelection();
067: boolean failure = failureField.getSelection();
068: boolean noPrompt = noPromptField.getSelection();
069: boolean system = systemField.getSelection();
070: boolean useGroup = groupField.getSelection();
071: boolean unknown = unknownField.getSelection();
072: boolean user = userField.getSelection();
073: boolean reschedule = rescheduleField.getSelection();
074: final long rescheduleWait = Long.parseLong(rescheduleDelay
075: .getText());
076: boolean keep = keepField.getSelection();
077: boolean keepOne = keepOneField.getSelection();
078: boolean gotoAction = gotoActionField.getSelection();
079: boolean schedulingRule = schedulingRuleField.getSelection();
080:
081: int groupIncrement = IProgressMonitor.UNKNOWN;
082: IProgressMonitor group = new NullProgressMonitor();
083: int total = IProgressMonitor.UNKNOWN;
084:
085: if (jobCount > 1) {
086: total = 100;
087: groupIncrement = 100 / jobCount;
088: }
089:
090: if (useGroup) {
091: group = Platform.getJobManager().createProgressGroup();
092: group.beginTask("Group", total); //$NON-NLS-1$
093: }
094:
095: long delay = Integer.parseInt(delayField.getText());
096: for (int i = 0; i < jobCount; i++) {
097: Job result;
098: if (ui)
099: result = new UITestJob(duration, lock, failure, unknown);
100: else
101: result = new TestJob(duration, lock, failure, unknown,
102: reschedule, rescheduleWait);
103:
104: result.setProperty(IProgressConstants.KEEP_PROPERTY,
105: Boolean.valueOf(keep));
106: result.setProperty(IProgressConstants.KEEPONE_PROPERTY,
107: Boolean.valueOf(keepOne));
108: result
109: .setProperty(
110: IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY,
111: Boolean.valueOf(noPrompt));
112: if (gotoAction)
113: result.setProperty(IProgressConstants.ACTION_PROPERTY,
114: new Action("Pop up a dialog") { //$NON-NLS-1$
115: public void run() {
116: MessageDialog
117: .openInformation(
118: getSite().getShell(),
119: "Goto Action", "The job can have an action associated with it"); //$NON-NLS-1$ //$NON-NLS-2$
120: }
121: });
122:
123: result.setProgressGroup(group, groupIncrement);
124: result.setSystem(system);
125: result.setUser(user);
126:
127: if (schedulingRule)
128: result.setRule(new TestJobRule(i));
129: result.schedule(delay);
130: }
131: }
132:
133: /**
134: * @see ViewPart#createPartControl(Composite)
135: */
136: public void createPartControl(Composite parent) {
137: Composite body = new Composite(parent, SWT.NONE);
138: GridLayout layout = new GridLayout();
139: layout.numColumns = 2;
140: layout.makeColumnsEqualWidth = false;
141: body.setLayout(layout);
142:
143: createEntryFieldGroup(body);
144: createPushButtonGroup(body);
145: createCheckboxGroup(body);
146: }
147:
148: /**
149: * Create all push button parts for the jobs view.
150: *
151: * @param parent
152: */
153: private void createPushButtonGroup(Composite parent) {
154: Composite group = new Composite(parent, SWT.NONE);
155: GridLayout layout = new GridLayout();
156: layout.numColumns = 1;
157: group.setLayout(layout);
158: group.setLayoutData(new GridData(GridData.FILL_BOTH));
159:
160: // create jobs
161: Button create = new Button(group, SWT.PUSH);
162: create.setText("Create jobs"); //$NON-NLS-1$
163: create
164: .setToolTipText("Creates and schedules jobs according to above parameters"); //$NON-NLS-1$
165: create.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
166: create.addSelectionListener(new SelectionAdapter() {
167: public void widgetSelected(SelectionEvent e) {
168: createJobs();
169: }
170: });
171:
172: // touch workspace
173: Button touch = new Button(group, SWT.PUSH);
174: touch.setText("Touch workspace"); //$NON-NLS-1$
175: touch.setToolTipText("Modifies the workspace in the UI thread"); //$NON-NLS-1$
176: touch.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
177: touch.addSelectionListener(new SelectionAdapter() {
178: public void widgetSelected(SelectionEvent e) {
179: touchWorkspace();
180: }
181: });
182: // busy cursor while
183: Button busyWhile = new Button(group, SWT.PUSH);
184: busyWhile.setText("busyCursorWhile"); //$NON-NLS-1$
185: busyWhile
186: .setToolTipText("Uses IProgressService.busyCursorWhile"); //$NON-NLS-1$
187: busyWhile.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
188: busyWhile.addSelectionListener(new SelectionAdapter() {
189: public void widgetSelected(SelectionEvent e) {
190: busyCursorWhile();
191: }
192: });
193: // progress monitor dialog with fork=false
194: Button noFork = new Button(group, SWT.PUSH);
195: noFork.setText("runInUI"); //$NON-NLS-1$
196: noFork.setToolTipText("Uses IProgressService.runInUI"); //$NON-NLS-1$
197: noFork.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
198: noFork.addSelectionListener(new SelectionAdapter() {
199: public void widgetSelected(SelectionEvent e) {
200: progressNoFork();
201: }
202: });
203:
204: // progress monitor dialog with fork=false
205: Button exception = new Button(group, SWT.PUSH);
206: exception.setText("Runtime Exception"); //$NON-NLS-1$
207: exception.setToolTipText("NullPointerException when running"); //$NON-NLS-1$
208: exception.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
209: exception.addSelectionListener(new SelectionAdapter() {
210: public void widgetSelected(SelectionEvent e) {
211: jobWithRuntimeException();
212: }
213: });
214:
215: // join the running test jobs
216: Button join = new Button(group, SWT.PUSH);
217: join.setText("Join Test Jobs"); //$NON-NLS-1$
218: join.setToolTipText("IJobManager.join() on test jobs"); //$NON-NLS-1$
219: join.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
220: join.addSelectionListener(new SelectionAdapter() {
221: public void widgetSelected(SelectionEvent e) {
222: joinTestJobs();
223: }
224: });
225:
226: // join the running test jobs
227: Button window = new Button(group, SWT.PUSH);
228: window.setText("Runnable in Window"); //$NON-NLS-1$
229: window
230: .setToolTipText("Using a runnable context in the workbench window"); //$NON-NLS-1$
231: window.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
232: window.addSelectionListener(new SelectionAdapter() {
233: public void widgetSelected(SelectionEvent e) {
234: runnableInWindow();
235: }
236: });
237:
238: // join the running test jobs
239: Button sleep = new Button(group, SWT.PUSH);
240: sleep.setText("Sleep"); //$NON-NLS-1$
241: sleep.setToolTipText("Calls sleep() on all TestJobs"); //$NON-NLS-1$
242: sleep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
243: sleep.addSelectionListener(new SelectionAdapter() {
244: public void widgetSelected(SelectionEvent e) {
245: doSleep();
246: }
247: });
248:
249: // join the running test jobs
250: Button wake = new Button(group, SWT.PUSH);
251: wake.setText("WakeUp"); //$NON-NLS-1$
252: wake.setToolTipText("Calls wakeUp() on all TestJobs"); //$NON-NLS-1$
253: wake.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
254: wake.addSelectionListener(new SelectionAdapter() {
255:
256: public void widgetSelected(SelectionEvent e) {
257: doWakeUp();
258: }
259: });
260:
261: // show in dialog
262: Button showInDialog = new Button(group, SWT.PUSH);
263: showInDialog.setText("showInDialog"); //$NON-NLS-1$
264: showInDialog
265: .setToolTipText("Uses IProgressService.showInDialog"); //$NON-NLS-1$
266: showInDialog.setLayoutData(new GridData(
267: GridData.FILL_HORIZONTAL));
268: showInDialog.addSelectionListener(new SelectionAdapter() {
269: public void widgetSelected(SelectionEvent e) {
270: showInDialog();
271: }
272: });
273:
274: }
275:
276: /**
277: * Test the showInDialog API
278: *
279: */
280: protected void showInDialog() {
281:
282: Job showJob = new Job("Show In Dialog") {//$NON-NLS-1$
283: protected IStatus run(IProgressMonitor monitor) {
284: monitor.beginTask("Run in dialog", 100);//$NON-NLS-1$
285:
286: for (int i = 0; i < 100; i++) {
287: if (monitor.isCanceled())
288: return Status.CANCEL_STATUS;
289: try {
290: Thread.sleep(100);
291: } catch (InterruptedException e) {
292: return Status.CANCEL_STATUS;
293: }
294: monitor.worked(1);
295:
296: }
297: return Status.OK_STATUS;
298:
299: }
300: };
301: showJob.schedule();
302: PlatformUI.getWorkbench().getProgressService().showInDialog(
303: getSite().getShell(), showJob);
304:
305: }
306:
307: /**
308: * Wakes up all sleeping test jobs.
309: */
310: protected void doWakeUp() {
311: Platform.getJobManager().wakeUp(TestJob.FAMILY_TEST_JOB);
312: }
313:
314: /**
315: * Puts to sleep all waiting test jobs.
316: */
317: protected void doSleep() {
318: Platform.getJobManager().sleep(TestJob.FAMILY_TEST_JOB);
319: }
320:
321: /**
322: * @param body
323: */
324: private void createEntryFieldGroup(Composite body) {
325: // duration
326: Label label = new Label(body, SWT.NONE);
327: label.setText("Duration:"); //$NON-NLS-1$
328: durationField = new Combo(body, SWT.DROP_DOWN | SWT.READ_ONLY);
329: GridData data = new GridData(GridData.FILL_HORIZONTAL);
330: data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
331: durationField.setLayoutData(data);
332: durationField.add("0"); //$NON-NLS-1$
333: durationField.add("1 millisecond"); //$NON-NLS-1$
334: durationField.add("1 second"); //$NON-NLS-1$
335: durationField.add("10 seconds"); //$NON-NLS-1$
336: durationField.add("1 minute"); //$NON-NLS-1$
337: durationField.add("10 minutes"); //$NON-NLS-1$
338: durationField.select(4);
339:
340: // delay
341: label = new Label(body, SWT.NONE);
342: label.setText("Start delay (ms):"); //$NON-NLS-1$
343: delayField = new Text(body, SWT.BORDER);
344: data = new GridData(GridData.FILL_HORIZONTAL);
345: data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
346: delayField.setLayoutData(data);
347: delayField.setText("0"); //$NON-NLS-1$
348:
349: // quantity
350: label = new Label(body, SWT.NONE);
351: label.setText("Quantity:"); //$NON-NLS-1$
352: quantityField = new Text(body, SWT.BORDER);
353: data = new GridData(GridData.FILL_HORIZONTAL);
354: data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
355: quantityField.setLayoutData(data);
356: quantityField.setText("1"); //$NON-NLS-1$
357:
358: // reschedule delay
359: label = new Label(body, SWT.NONE);
360: label.setText("Reschedule Delay (ms):"); //$NON-NLS-1$
361: rescheduleDelay = new Text(body, SWT.BORDER);
362: data = new GridData(GridData.FILL_HORIZONTAL);
363: data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
364: rescheduleDelay.setLayoutData(data);
365: rescheduleDelay.setText("1000"); //$NON-NLS-1$
366: }
367:
368: /**
369: * Creates all of the checkbox buttons.
370: */
371: private void createCheckboxGroup(Composite parent) {
372: Composite group = new Composite(parent, SWT.NONE);
373: GridLayout layout = new GridLayout();
374: layout.numColumns = 1;
375: group.setLayout(layout);
376: group.setLayoutData(new GridData(GridData.FILL_BOTH));
377:
378: // lock
379: lockField = new Button(group, SWT.CHECK);
380: lockField.setText("Lock the workspace"); //$NON-NLS-1$
381: GridData data = new GridData(GridData.FILL_HORIZONTAL);
382: lockField.setLayoutData(data);
383:
384: // system
385: systemField = new Button(group, SWT.CHECK);
386: systemField.setText("System job"); //$NON-NLS-1$
387: data = new GridData(GridData.FILL_HORIZONTAL);
388: systemField.setLayoutData(data);
389:
390: // thread
391: threadField = new Button(group, SWT.CHECK);
392: threadField.setText("Run in UI thread"); //$NON-NLS-1$
393: data = new GridData(GridData.FILL_HORIZONTAL);
394: threadField.setLayoutData(data);
395:
396: // groups
397: groupField = new Button(group, SWT.CHECK);
398: groupField.setText("Run in Group"); //$NON-NLS-1$
399: data = new GridData(GridData.FILL_HORIZONTAL);
400: groupField.setLayoutData(data);
401:
402: // reschedule
403: rescheduleField = new Button(group, SWT.CHECK);
404: rescheduleField.setText("Reschedule"); //$NON-NLS-1$
405: data = new GridData(GridData.FILL_HORIZONTAL);
406: rescheduleField.setLayoutData(data);
407:
408: // keep
409: keepField = new Button(group, SWT.CHECK);
410: keepField.setText("Keep"); //$NON-NLS-1$
411: data = new GridData(GridData.FILL_HORIZONTAL);
412: keepField.setLayoutData(data);
413:
414: // keep one
415: keepOneField = new Button(group, SWT.CHECK);
416: keepOneField.setText("KeepOne"); //$NON-NLS-1$
417: data = new GridData(GridData.FILL_HORIZONTAL);
418: keepOneField.setLayoutData(data);
419:
420: // IProgressMonitor.UNKNOWN
421: unknownField = new Button(group, SWT.CHECK);
422: unknownField.setText("Indeterminate Progress"); //$NON-NLS-1$
423: data = new GridData(GridData.FILL_HORIZONTAL);
424: unknownField.setLayoutData(data);
425:
426: // whether the job is a user job
427: userField = new Button(group, SWT.CHECK);
428: userField.setText("User job"); //$NON-NLS-1$
429: data = new GridData(GridData.FILL_HORIZONTAL);
430: userField.setLayoutData(data);
431:
432: // whether the job has a goto action
433: gotoActionField = new Button(group, SWT.CHECK);
434: gotoActionField.setText("Goto action"); //$NON-NLS-1$
435: data = new GridData(GridData.FILL_HORIZONTAL);
436: gotoActionField.setLayoutData(data);
437:
438: // whether the job should use a scheduling rule
439: schedulingRuleField = new Button(group, SWT.CHECK);
440: schedulingRuleField.setText("Schedule sequentially"); //$NON-NLS-1$
441: schedulingRuleField.setLayoutData(new GridData(
442: GridData.FILL_HORIZONTAL));
443:
444: // failure
445: failureField = new Button(group, SWT.CHECK);
446: failureField.setText("Fail"); //$NON-NLS-1$
447: failureField.setLayoutData(new GridData(
448: GridData.FILL_HORIZONTAL));
449:
450: // failure
451: noPromptField = new Button(group, SWT.CHECK);
452: noPromptField.setText("No Prompt"); //$NON-NLS-1$
453: noPromptField
454: .setToolTipText("Set the IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY to true");
455: noPromptField.setLayoutData(new GridData(
456: GridData.FILL_HORIZONTAL));
457: }
458:
459: protected void doRun(long duration, IProgressMonitor monitor) {
460: final long sleep = 10;
461: int ticks = (int) (duration / sleep);
462: monitor
463: .beginTask(
464: "Spinning inside IProgressService.busyCursorWhile", ticks); //$NON-NLS-1$
465: monitor
466: .setTaskName("Spinning inside IProgressService.busyCursorWhile"); //$NON-NLS-1$
467: for (int i = 0; i < ticks; i++) {
468: monitor.subTask("Processing tick #" + i); //$NON-NLS-1$
469: if (monitor.isCanceled())
470: return;
471: try {
472: Thread.sleep(sleep);
473: } catch (InterruptedException e) {
474: // ignore
475: }
476: monitor.worked(1);
477: }
478: }
479:
480: protected void doRunInWorkspace(final long duration,
481: IProgressMonitor monitor) {
482: try {
483: ResourcesPlugin.getWorkspace().run(
484: new IWorkspaceRunnable() {
485: public void run(IProgressMonitor monitor)
486: throws CoreException {
487: doRun(duration, monitor);
488: }
489: }, monitor);
490: } catch (CoreException e) {
491: e.printStackTrace();
492: }
493: }
494:
495: protected long getDuration() {
496: switch (durationField.getSelectionIndex()) {
497: case 0:
498: return 0;
499: case 1:
500: return 1;
501: case 2:
502: return 1000;
503: case 3:
504: return 10000;
505: case 4:
506: return 60000;
507: case 5:
508: default:
509: return 600000;
510: }
511: }
512:
513: protected void jobWithRuntimeException() {
514: Job runtimeExceptionJob = new Job("Job with Runtime exception") { //$NON-NLS-1$
515: /*
516: * (non-Javadoc)
517: *
518: * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
519: */
520: protected IStatus run(IProgressMonitor monitor) {
521: throw new NullPointerException();
522: }
523: };
524: runtimeExceptionJob.schedule();
525: }
526:
527: /**
528: * Example usage of the IJobManager.join method.
529: */
530: protected void joinTestJobs() {
531: try {
532: // note that when a null progress monitor is used when in the UI
533: // thread, the workbench will create a default progress monitor
534: // that reports progress in a modal dialog with details area
535: PlatformUI.getWorkbench().getProgressService()
536: .busyCursorWhile(new IRunnableWithProgress() {
537: public void run(IProgressMonitor monitor)
538: throws InterruptedException {
539: Job.getJobManager().join(
540: TestJob.FAMILY_TEST_JOB, monitor);
541: }
542: });
543: } catch (InterruptedException e) {
544: // thrown if the user interrupts the join by canceling the progress
545: // monitor
546: // A UI component should swallow the exception and finish the action
547: // or operation. A lower level component should just propagate the
548: // exception
549: e.printStackTrace();
550: } catch (InvocationTargetException e) {
551: // Thrown when the operation running within busyCursorWhile throws
552: // an
553: // exception. This should either be propagated or displayed to the
554: // user
555: e.printStackTrace();
556: }
557: }
558:
559: protected void progressNoFork() {
560: try {
561: final long duration = getDuration();
562: final boolean shouldLock = lockField.getSelection();
563: IProgressService progressService = PlatformUI
564: .getWorkbench().getProgressService();
565: progressService.runInUI(progressService,
566: new IRunnableWithProgress() {
567: public void run(IProgressMonitor monitor)
568: throws InterruptedException {
569: if (shouldLock)
570: doRunInWorkspace(duration, monitor);
571: else
572: doRun(duration, monitor);
573: }
574: }, ResourcesPlugin.getWorkspace().getRoot());
575: } catch (InvocationTargetException e) {
576: e.printStackTrace();
577: } catch (InterruptedException e) {
578: e.printStackTrace();
579: }
580: }
581:
582: /**
583: * @see ViewPart#setFocus()
584: */
585: public void setFocus() {
586: if (durationField != null && !durationField.isDisposed())
587: durationField.setFocus();
588: }
589:
590: protected void touchWorkspace() {
591: // create an asyncExec to touch the workspace the specific number of
592: // times
593: int jobCount = Integer.parseInt(quantityField.getText());
594: for (int i = 0; i < jobCount; i++) {
595: getSite().getShell().getDisplay().asyncExec(new Runnable() {
596: public void run() {
597: try {
598: ResourcesPlugin.getWorkspace().run(
599: new IWorkspaceRunnable() {
600: public void run(
601: IProgressMonitor monitor) {
602: // no-op
603: }
604: }, null);
605: } catch (OperationCanceledException e) {
606: // ignore
607: } catch (CoreException e) {
608: e.printStackTrace();
609: }
610: }
611: });
612: }
613: }
614:
615: /**
616: * Run a workspace runnable in the application window.
617: *
618: */
619:
620: public void runnableInWindow() {
621:
622: final long time = getDuration();
623: final long sleep = 10;
624: IRunnableWithProgress runnableTest = new WorkspaceModifyOperation() {
625:
626: /*
627: * (non-Javadoc)
628: *
629: * @see org.eclipse.ui.actions.WorkspaceModifyOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
630: */
631: protected void execute(IProgressMonitor monitor)
632: throws CoreException, InvocationTargetException,
633: InterruptedException {
634: int ticks = (int) (time / sleep);
635: monitor
636: .beginTask(
637: "Spinning inside ApplicationWindow.run()", ticks); //$NON-NLS-1$
638: monitor
639: .setTaskName("Spinning inside ApplicationWindow.run()"); //$NON-NLS-1$
640: for (int i = 0; i < ticks; i++) {
641: monitor.subTask("Processing tick #" + i); //$NON-NLS-1$
642: if (monitor.isCanceled())
643: return;
644: try {
645: Thread.sleep(sleep);
646: } catch (InterruptedException e) {
647: // ignore
648: }
649: monitor.worked(1);
650: }
651: }
652:
653: };
654: try {
655: PlatformUI.getWorkbench().getActiveWorkbenchWindow().run(
656: true, true, runnableTest);
657:
658: } catch (Exception e) {
659: e.printStackTrace();
660: }
661:
662: }
663: }
|