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

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

see #11390 - sonar - squid:S1604 - Java 8: Anonymous inner classes containing only one method should become lambdas

  • 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 = () -> ChangesetCache.getInstance().update(downloadedChangesets);
64 if (SwingUtilities.isEventDispatchThread()) {
65 r.run();
66 } else {
67 try {
68 SwingUtilities.invokeAndWait(r);
69 } catch (InterruptedException e) {
70 Main.warn("InterruptedException in "+getClass().getSimpleName()+" while updating changeset cache");
71 } catch (InvocationTargetException e) {
72 Throwable t = e.getTargetException();
73 if (t instanceof RuntimeException) {
74 BugReportExceptionHandler.handleException(t);
75 } else if (t instanceof Exception) {
76 ExceptionUtil.explainException(e);
77 } else {
78 BugReportExceptionHandler.handleException(t);
79 }
80 }
81 }
82 }
83 }
84
85 private RunnableDownloadTask downloadTaskRunnable;
86
87 protected final void setDownloadTask(RunnableDownloadTask downloadTask) {
88 this.downloadTaskRunnable = downloadTask;
89 }
90
91 @Override
92 public final Future<?> download(boolean newLayer, Bounds downloadArea, ProgressMonitor progressMonitor) {
93 return download();
94 }
95
96 /**
97 * Asynchronously launches the changeset download task. This is equivalent to {@code download(false, null, null)}.
98 *
99 * You can wait for the asynchronous download task to finish by synchronizing on the returned
100 * {@link Future}, but make sure not to freeze up JOSM. Example:
101 * <pre>
102 * Future&lt;?&gt; future = task.download();
103 * // DON'T run this on the Swing EDT or JOSM will freeze
104 * future.get(); // waits for the dowload task to complete
105 * </pre>
106 *
107 * The following example uses a pattern which is better suited if a task is launched from the Swing EDT:
108 * <pre>
109 * final Future&lt;?&gt; future = task.download();
110 * Runnable runAfterTask = new Runnable() {
111 * public void run() {
112 * // this is not strictly necessary because of the type of executor service
113 * // Main.worker is initialized with, but it doesn't harm either
114 * //
115 * future.get(); // wait for the download task to complete
116 * doSomethingAfterTheTaskCompleted();
117 * }
118 * }
119 * Main.worker.submit(runAfterTask);
120 * </pre>
121 *
122 * @return the future representing the asynchronous task
123 */
124 public final Future<?> download() {
125 return downloadTaskRunnable != null ? Main.worker.submit(downloadTaskRunnable) : null;
126 }
127
128 @Override
129 public final Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor) {
130 return downloadTaskRunnable != null ? Main.worker.submit(downloadTaskRunnable) : null;
131 }
132
133 @Override
134 public final void cancel() {
135 if (downloadTaskRunnable != null) {
136 downloadTaskRunnable.cancel();
137 }
138 }
139
140 @Override
141 public String getConfirmationMessage(URL url) {
142 return null;
143 }
144}
Note: See TracBrowser for help on using the repository browser.