Bug 457504 - Publish a job group's final status to IJobChangeListeners
Publish a job group's final status by extending the IJobChangeEvent
with a new getJobGroupResult() method, and when the last job in a
job group has executed, have the JobManager update the IJobChangeEvent
with the job group's final status.
Change-Id: I641f2670bab15d0a9af67e928e7b78a57718878f
Signed-off-by: Terry Parker <tparker@google.com>
diff --git a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobChangeEvent.java b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobChangeEvent.java
index 9108bfa..4b19dd0 100644
--- a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobChangeEvent.java
+++ b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobChangeEvent.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2012 IBM Corporation and others.
+ * Copyright (c) 2003, 2015 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM - Initial API and implementation
+ * Terry Parker - Bug 457504, Publish a job group's final status to IJobChangeListeners
*******************************************************************************/
package org.eclipse.core.internal.jobs;
@@ -25,6 +26,12 @@
*/
IStatus result = null;
/**
+ * The result returned by the job's job group, if this event signals
+ * completion of the last job in a group, or <code>null</code> if not
+ * applicable.
+ */
+ IStatus jobGroupResult = null;
+ /**
* The amount of time to wait after scheduling the job before it should be run,
* or <code>-1</code> if not applicable for this type of event.
*/
@@ -57,4 +64,12 @@
public IStatus getResult() {
return result;
}
+
+ /* (non-Javadoc)
+ * Method declared on IJobChangeEvent
+ */
+ @Override
+ public IStatus getJobGroupResult() {
+ return jobGroupResult;
+ }
}
diff --git a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java
index dd1ef88..85a9722 100644
--- a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java
+++ b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2014 IBM Corporation and others.
+ * Copyright (c) 2003, 2015 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
@@ -13,6 +13,7 @@
* Oracle Corporation - Fix for bug 316839
* Thirumala Reddy Mutchukota - Bug 432049, JobGroup API and implementation
* Jan Koehnlein - Fix for bug 60964 (454698)
+ * Terry Parker - Bug 457504, Publish a job group's final status to IJobChangeListeners
*******************************************************************************/
package org.eclipse.core.internal.jobs;
@@ -105,6 +106,12 @@
final ImplicitJobs implicitJobs = new ImplicitJobs(this);
+ /**
+ * Listeners for the job lifecycle. It is important that the
+ * JobManager#JobGroupUpdater is the first one that is dispatched to, since
+ * it updates the JobChangeEvent#jobGroupStatus field, which other listeners
+ * may use.
+ */
private final JobListeners jobListeners = new JobListeners();
/**
@@ -1852,9 +1859,15 @@
isJobGroupCompleted = true;
}
}
- // Log the group result when the job group is completed.
- if (isJobGroupCompleted && jobGroupResult.matches(IStatus.ERROR | IStatus.WARNING))
- RuntimeLog.log(jobGroupResult);
+
+ // If the job group is completing, add the job group's status to the event
+ // and log errors and warnings.
+ if (isJobGroupCompleted) {
+ ((JobChangeEvent) event).jobGroupResult = jobGroupResult;
+ if (jobGroupResult.matches(IStatus.ERROR | IStatus.WARNING))
+ RuntimeLog.log(jobGroupResult);
+ }
+
return;
}
diff --git a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/runtime/jobs/IJobChangeEvent.java b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/runtime/jobs/IJobChangeEvent.java
index 8fa4943..b843251 100644
--- a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/runtime/jobs/IJobChangeEvent.java
+++ b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/runtime/jobs/IJobChangeEvent.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2012 IBM Corporation and others.
+ * Copyright (c) 2003, 2015 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM - Initial API and implementation
+ * Terry Parker - Bug 457504, Publish a job group's final status to IJobChangeListeners
*******************************************************************************/
package org.eclipse.core.runtime.jobs;
@@ -44,4 +45,14 @@
* @return the status for this event
*/
public IStatus getResult();
+
+ /**
+ * The result returned by the job's job group, if this event signals
+ * completion of the last job in a group, or <code>null</code> if not
+ * applicable. This value is only applicable for the <code>done</code> event.
+ *
+ * @return the job group status for this event, or <code>null</code>
+ * @since 3.7
+ */
+ public IStatus getJobGroupResult();
}
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/JobGroupTest.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/JobGroupTest.java
index 8198604..909ac04 100644
--- a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/JobGroupTest.java
+++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/JobGroupTest.java
@@ -1286,6 +1286,49 @@
waitForCompletion(jobGroup);
}
+ /**
+ * Tests that the JobManager publishes a final job group status to IJobChangeListeners.
+ */
+ public void testJobManagerPublishesJobGroupResults() {
+ final int NUM_GROUP_JOBS = 3;
+ final String GROUP_NAME = "TestJobGroup";
+ final JobGroup jobGroup = new JobGroup(GROUP_NAME, 1, NUM_GROUP_JOBS);
+
+ // Record job completion events for all jobs in this job group.
+ final List<IJobChangeEvent> events = new ArrayList<IJobChangeEvent>(NUM_GROUP_JOBS);
+ IJobChangeListener listener = new JobChangeAdapter() {
+ @Override
+ public void done(IJobChangeEvent event) {
+ if (event.getJob().getJobGroup() == jobGroup) {
+ events.add(event);
+ }
+ }
+ };
+ manager.addJobChangeListener(listener);
+
+ // Execute all jobs in the job group and validate that the last job includes the job group result.
+ try {
+ for (int i = 0; i < NUM_GROUP_JOBS; i++) {
+ TestJob testJob = new TestJob("GroupJob", 10, 1);
+ testJob.setJobGroup(jobGroup);
+ testJob.schedule();
+ }
+ waitForCompletion(jobGroup);
+
+ assertEquals("Should have seen as many job completion events as the count of jobs in the job group.", NUM_GROUP_JOBS, events.size());
+ for (int i = 0; i < NUM_GROUP_JOBS; i++) {
+ IJobChangeEvent event = events.get(i);
+ assertNotNull("All job completion events should have a job status.", event.getResult());
+ if (i < NUM_GROUP_JOBS - 1)
+ assertNull("Only the last job competion event shoud have a job group status.", event.getJobGroupResult());
+ else
+ assertNotNull("The last job competion event shoud have a job group status.", event.getJobGroupResult());
+ }
+ } finally {
+ manager.removeJobChangeListener(listener);
+ }
+ }
+
private void assertState(String msg, Job job, int expectedState) {
int actualState = job.getState();
if (actualState != expectedState)