/* * Copyright (c) 2012 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.server.progress.impl; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.UUID; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.core.runtime.jobs.ProgressProvider; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import eu.esdihumboldt.hale.server.progress.JobProgressListener; import eu.esdihumboldt.hale.server.progress.Progress; import eu.esdihumboldt.hale.server.progress.ProgressService; /** * Progress manager to replace the progress provider available in Eclipse in a * context without Eclipse UI. * * @author Simon Templer */ public class ProgressManager extends ProgressProvider implements ProgressService { private final Map<Job, ProgressMonitor> monitors = new HashMap<Job, ProgressMonitor>(); private final Multimap<Job, JobProgressListener> listeners = HashMultimap.create(); /** * Default constructor */ public ProgressManager() { super(); // add listener to job manager to remove finished jobs Job.getJobManager().addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { synchronized (monitors) { monitors.remove(event.getJob()); } synchronized (listeners) { Collection<JobProgressListener> jobListeners = listeners.get(event.getJob()); Iterator<JobProgressListener> it = jobListeners.iterator(); while (it.hasNext()) { // inform about completed job it.next().jobCompleted(event.getJob()); // also remove listener it.remove(); } } } }); // register the progress manager Job.getJobManager().setProgressProvider(this); } /** * @see ProgressProvider#createMonitor(Job) */ @Override public IProgressMonitor createMonitor(final Job job) { // derive ID from job or generate ID for job // the toString method uses the intern job number // XXX this is unreliable (e.g. if toString is overridden) // final String id = job.toString(); // use generated ID final String id = UUID.randomUUID().toString(); ProgressMonitor monitor = new ProgressMonitor(id) { @Override public void beginTask(String name, int totalWork) { super.beginTask(name, totalWork); notifyProgressChanged(job, this); } @Override public void setCanceled(boolean value) { super.setCanceled(value); notifyProgressChanged(job, this); } @Override public void setTaskName(String name) { super.setTaskName(name); notifyProgressChanged(job, this); } @Override public void subTask(String name) { super.subTask(name); notifyProgressChanged(job, this); } @Override public void worked(int work) { super.worked(work); notifyProgressChanged(job, this); } @Override public void cancel() { super.cancel(); notifyProgressChanged(job, this); } }; synchronized (monitors) { monitors.put(job, monitor); } return monitor; } /** * Notify on a job progress change. * * @param job the job * @param progress the progress */ protected void notifyProgressChanged(Job job, Progress progress) { synchronized (listeners) { for (JobProgressListener listener : listeners.get(job)) { listener.progressChanged(job, progress); } } } /** * @see ProgressService#getJobProgress(Job) */ @Override public Progress getJobProgress(Job job) { ProgressMonitor monitor; synchronized (monitors) { monitor = monitors.get(job); } return monitor; } @Override public void addProgressListener(Job job, JobProgressListener listener) { synchronized (listeners) { listeners.put(job, listener); } } @Override public void removeProgressListener(Job job, JobProgressListener listener) { synchronized (listeners) { listeners.remove(job, listener); } } }