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

Last change on this file since 10601 was 10601, checked in by Don-vip, 3 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.