/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ package de.cismet.tools.gui.downloadmanager; import java.util.Collection; import javax.swing.SwingWorker; /** * BackgroundTaskMultipleDownload extends MultipleDownload, the difference is that the BackgroundTaskMultipleDownload * does not need to know how many downloads it contains when it is started. Its encapsulated downloads are created in a * background task provided to it by an instance of FetchDownloadsTask. This tasks runs in a SwingWorker and returns a * List of Downloads. After the task has finished the created downloads are added to the BackgroundTaskMultipleDownload. * * <p>Note: the FetchDownloadsTask will not run in the EDT.</p> * * @author Gilles Baatz * @version $Revision$, $Date$ */ public class BackgroundTaskMultipleDownload extends MultipleDownload { //~ Instance fields -------------------------------------------------------- private FetchDownloadsTask fetchDownloadTask; private SwingWorker<Collection<? extends Download>, Void> worker; private Exception caughtException; //~ Constructors ----------------------------------------------------------- /** * Creates a new BackgroundTaskMultipleDownload object. * * @param downloads DOCUMENT ME! * @param title DOCUMENT ME! * @param fetchDownloadsTask DOCUMENT ME! */ public BackgroundTaskMultipleDownload(final Collection<? extends Download> downloads, final String title, final FetchDownloadsTask fetchDownloadsTask) { super(downloads, title); this.fetchDownloadTask = fetchDownloadsTask; } //~ Methods ---------------------------------------------------------------- @Override public void startDownload() { worker = new SwingWorker<Collection<? extends Download>, Void>() { @Override protected Collection<? extends Download> doInBackground() throws Exception { return fetchDownloadTask.fetchDownloads(); } @Override protected void done() { try { addDownloadsSubsequently(get()); setStatus(State.RUNNING); } catch (Exception ex) { caughtException = ex; setStatus(State.COMPLETED_WITH_ERROR); } } }; worker.execute(); } @Override public Exception getCaughtException() { return caughtException; } /** * DOCUMENT ME! * * @param <D> DOCUMENT ME! * @param newDownloads DOCUMENT ME! */ private <D extends Download> void addDownloadsSubsequently(final Collection<D> newDownloads) { final Collection<D> existentDownloads = (Collection<D>)getDownloads(); for (final D download : newDownloads) { existentDownloads.add(download); } DownloadManager.instance().addDownloadsSubsequently(this); } @Override public int hashCode() { int hash = 5; hash = (47 * hash) + ((this.fetchDownloadTask != null) ? this.fetchDownloadTask.hashCode() : 0); return hash; } @Override public boolean equals(final Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final BackgroundTaskMultipleDownload other = (BackgroundTaskMultipleDownload)obj; if ((this.fetchDownloadTask != other.fetchDownloadTask) && ((this.fetchDownloadTask == null) || !this.fetchDownloadTask.equals(other.fetchDownloadTask))) { return false; } return true; } //~ Inner Interfaces ------------------------------------------------------- /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ public interface FetchDownloadsTask { //~ Methods ------------------------------------------------------------ /** * A task, which is executed during the startDownload()-method of BackgroundTaskMultipleDownload. Every * exception thrown in this method, will later on be caught by the BackgroundTaskMultipleDownload and shown in * the DownloadManager. * * <p>Note: Do not forget to close, eventually opened, system resources e.g. FileOutputStream. This can be done * with a try-finally block.</p> * * @return DOCUMENT ME! * * @throws Exception the Exceptions will be caught by BackgroundTaskMultipleDownload */ Collection<? extends Download> fetchDownloads() throws Exception; } }