Bug 492252 - Ensure JobInfo are created with FinishedJobs instance

JobInfo instances were created with a null reference for FinishedJobs in
JobInfoFactory. This change makes the FinishedJobs reference in
ProgressManager non optional, and the JobInfoFactory takes the
ProgressManager's FinishedJobs instance for creation of JobInfos.

This required that FinishedJobs does not require a ProgressManager for
its construction. This was needed to register an
IJobProgressManagerListener to the ProgressManager. Instead of
registering itsels, the ProgressManager now registers the listener. This
resolves the circular dependency between both classes.

On shutdown ProgressManager might already be null. Being resilient for
that.

Change-Id: I7ae3c1f4386f3cf15c23296309599f3e8d5ee19b
Signed-off-by: Karsten Thoms <karsten.thoms@karakun.com>
Also-by: Andrzej Witecki <sodoww@gmail.com>
diff --git a/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/FinishedJobs.java b/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/FinishedJobs.java
index 9433a2b..fcf0adc 100644
--- a/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/FinishedJobs.java
+++ b/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/FinishedJobs.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2019 IBM Corporation and others.
+ * Copyright (c) 2003, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -20,15 +20,12 @@
 import java.util.LinkedHashSet;
 import java.util.Set;
 
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
 import javax.inject.Singleton;
 
 import org.eclipse.core.commands.common.EventManager;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.e4.core.di.annotations.Creatable;
-import org.eclipse.e4.ui.model.application.MApplication;
 import org.eclipse.e4.ui.progress.IDisposableAction;
 import org.eclipse.e4.ui.progress.IProgressConstants;
 
@@ -60,7 +57,7 @@
 		void removed(JobTreeElement jte);
 	}
 
-	private IJobProgressManagerListener listener;
+	final IJobProgressManagerListener listener;
 
 	private final Set<JobTreeElement> keptjobinfos = new LinkedHashSet<>();
 
@@ -68,16 +65,6 @@
 
 	private static final JobTreeElement[] EMPTY_INFOS = new JobTreeElement[0];
 
-	@Inject
-	ProgressManager progressManager;
-
-	@PostConstruct
-	void init(MApplication application) {
-		progressManager.addListener(listener);
-		// TODO E4 workaround for @creatable problem
-		application.getContext().set(FinishedJobs.class, this);
-	}
-
 	public FinishedJobs() {
 		listener = new IJobProgressManagerListener() {
 			@Override
@@ -97,10 +84,12 @@
 
 			@Override
 			public void refreshGroup(GroupInfo info) {
+				// no action
 			}
 
 			@Override
 			public void refreshAll() {
+				// no action
 			}
 
 			@Override
@@ -115,6 +104,7 @@
 
 			@Override
 			public void removeGroup(GroupInfo group) {
+				// no action
 			}
 
 			@Override
diff --git a/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/JobInfo.java b/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/JobInfo.java
index 49d97ef..c0bf8be 100644
--- a/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/JobInfo.java
+++ b/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/JobInfo.java
@@ -100,7 +100,9 @@
 		this.canceled = true;
 		this.job.cancel();
 		// Call the refresh so that this is updated immediately
-		progressManager.refreshJobInfo(this);
+		if (progressManager != null) {
+			progressManager.refreshJobInfo(this);
+		}
 	}
 
 	/**
@@ -111,7 +113,9 @@
 	}
 
 	void clearTaskInfo() {
-		finishedJobs.remove(taskInfo);
+		if (finishedJobs != null) {
+			finishedJobs.remove(taskInfo);
+		}
 		taskInfo = null;
 	}
 
diff --git a/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/JobInfoFactory.java b/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/JobInfoFactory.java
index 6dbea67..51a6b57 100644
--- a/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/JobInfoFactory.java
+++ b/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/JobInfoFactory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010, 2015 IBM Corporation and others.
+ * Copyright (c) 2010, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -27,8 +27,9 @@
 	Services services;
 
 	public JobInfo getJobInfo(Job enclosingJob) {
-		return new JobInfo(enclosingJob,
-				services.getService(ProgressManager.class),
-				services.getService(FinishedJobs.class));
+		ProgressManager progressManager = services.getService(ProgressManager.class);
+		// ProgressManager might already been disposed on shutdown
+		return new JobInfo(enclosingJob, progressManager,
+				progressManager != null ? progressManager.finishedJobs : null);
 	}
 }
diff --git a/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/ProgressManager.java b/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/ProgressManager.java
index 6bf184e..19c12b0 100644
--- a/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/ProgressManager.java
+++ b/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/ProgressManager.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2017 IBM Corporation and others.
+ * Copyright (c) 2003, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -123,7 +123,6 @@
 	@Inject
 	JobInfoFactory jobInfoFactory;
 
-	@Optional
 	@Inject
 	FinishedJobs finishedJobs;
 
@@ -137,12 +136,6 @@
 		singleton.shutdown();
 	}
 
-//	/**
-//	 * Create a new instance of the receiver.
-//	 */
-//	protected ProgressManager() {
-//	}
-
 	@PostConstruct
 	protected void init(WorkbenchDialogBlockedHandler dialogBlockedHandler) {
 		Dialog.setBlockedHandler(dialogBlockedHandler);
@@ -153,6 +146,7 @@
 
 		Job.getJobManager().setProgressProvider(this);
 		Job.getJobManager().addJobChangeListener(this.changeListener);
+		addListener(finishedJobs.listener);
 	}
 
 	private void setUpImages() {