source: josm/trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractChangesetDownloadTask.java@ 10129

Last change on this file since 10129 was 10129, checked in by Don-vip, 8 years ago

refactor duplicated code

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions.downloadtasks;
3
4import java.awt.Component;
5import java.lang.reflect.InvocationTargetException;
6import java.net.URL;
7import java.util.HashSet;
8import java.util.Set;
9import java.util.concurrent.Future;
10
11import javax.swing.SwingUtilities;
12
13import org.openstreetmap.josm.Main;
14import org.openstreetmap.josm.data.Bounds;
15import org.openstreetmap.josm.data.osm.Changeset;
16import org.openstreetmap.josm.data.osm.ChangesetCache;
17import org.openstreetmap.josm.gui.PleaseWaitRunnable;
18import org.openstreetmap.josm.gui.progress.ProgressMonitor;
19import org.openstreetmap.josm.io.OsmServerChangesetReader;
20import org.openstreetmap.josm.tools.ExceptionUtil;
21import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;
22
23/**
24 * Common abstract implementation of other changeset download tasks.
25 * @since 10124
26 */
27public abstract class AbstractChangesetDownloadTask extends AbstractDownloadTask<Set<Changeset>> {
28
29 abstract class RunnableDownloadTask extends PleaseWaitRunnable {
30 /** the reader object used to read changesets from the API */
31 protected final OsmServerChangesetReader reader = new OsmServerChangesetReader();
32 /** the set of downloaded changesets */
33 protected final Set<Changeset> downloadedChangesets = new HashSet<>();
34 /** keeps the last exception thrown in the task, if any */
35 protected Exception lastException;
36
37 RunnableDownloadTask(Component parent, String title) {
38 super(parent, title, false /* don't ignore exceptions */);
39 }
40
41 @Override
42 protected void cancel() {
43 setCanceled(true);
44 synchronized (this) {
45 if (reader != null) {
46 reader.cancel();
47 }
48 }
49 }
50
51 protected final void rememberLastException(Exception e) {
52 lastException = e;
53 setFailed(true);
54 }
55
56 protected final void updateChangesets() {
57 // update the global changeset cache with the downloaded changesets.
58 // this will trigger change events which views are listening to. They
59 // will update their views accordingly.
60 //
61 // Run on the EDT because UI updates are triggered.
62 //
63 Runnable r = new Runnable() {
64 @Override public void run() {
65 ChangesetCache.getInstance().update(downloadedChangesets);
66 }
67 };
68 if (SwingUtilities.isEventDispatchThread()) {
69 r.run();
70 } else {
71 try {
72 SwingUtilities.invokeAndWait(r);
73 } catch (InterruptedException e) {
74 Main.warn("InterruptedException in "+getClass().getSimpleName()+" while updating changeset cache");
75 } catch (InvocationTargetException e) {
76 Throwable t = e.getTargetException();
77 if (t instanceof RuntimeException) {
78 BugReportExceptionHandler.handleException(t);
79 } else if (t instanceof Exception) {
80 ExceptionUtil.explainException(e);
81 } else {
82 BugReportExceptionHandler.handleException(t);
83 }
84 }
85 }
86 }
87 }
88
89 private RunnableDownloadTask downloadTaskRunnable;
90
91 protected final void setDownloadTask(RunnableDownloadTask downloadTask) {
92 this.downloadTaskRunnable = downloadTask;
93 }
94
95 @Override
96 public final Future<?> download(boolean newLayer, Bounds downloadArea, ProgressMonitor progressMonitor) {
97 return download();
98 }
99
100 /**
101 * Asynchronously launches the changeset download task. This is equivalent to {@code download(false, null, null)}.
102 *
103 * You can wait for the asynchronous download task to finish by synchronizing on the returned
104 * {@link Future}, but make sure not to freeze up JOSM. Example:
105 * <pre>
106 * Future&lt;?&gt; future = task.download();
107 * // DON'T run this on the Swing EDT or JOSM will freeze
108 * future.get(); // waits for the dowload task to complete
109 * </pre>
110 *
111 * The following example uses a pattern which is better suited if a task is launched from the Swing EDT:
112 * <pre>
113 * final Future&lt;?&gt; future = task.download();
114 * Runnable runAfterTask = new Runnable() {
115 * public void run() {
116 * // this is not strictly necessary because of the type of executor service
117 * // Main.worker is initialized with, but it doesn't harm either
118 * //
119 * future.get(); // wait for the download task to complete
120 * doSomethingAfterTheTaskCompleted();
121 * }
122 * }
123 * Main.worker.submit(runAfterTask);
124 * </pre>
125 *
126 * @return the future representing the asynchronous task
127 */
128 public final Future<?> download() {
129 return Main.worker.submit(downloadTaskRunnable);
130 }
131
132 @Override
133 public final Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor) {
134 return Main.worker.submit(downloadTaskRunnable);
135 }
136
137 @Override
138 public final void cancel() {
139 downloadTaskRunnable.cancel();
140 }
141
142 @Override
143 public String getConfirmationMessage(URL url) {
144 return null;
145 }
146}
Note: See TracBrowser for help on using the repository browser.