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

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

sonar - squid:S2142 - "InterruptedException" should not be ignored

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