source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/relation/ParentRelationLoadingTask.java@ 12634

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

see #15182 - deprecate Main.worker, replace it by gui.MainApplication.worker + code refactoring to make sure only editor packages use it

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.relation;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.IOException;
7import java.util.ArrayList;
8import java.util.List;
9import java.util.Optional;
10
11import javax.swing.JOptionPane;
12import javax.swing.SwingUtilities;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.data.osm.DataSet;
16import org.openstreetmap.josm.data.osm.DataSetMerger;
17import org.openstreetmap.josm.data.osm.Relation;
18import org.openstreetmap.josm.gui.PleaseWaitRunnable;
19import org.openstreetmap.josm.gui.layer.OsmDataLayer;
20import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
21import org.openstreetmap.josm.io.OsmApi;
22import org.openstreetmap.josm.io.OsmServerBackreferenceReader;
23import org.openstreetmap.josm.io.OsmTransferException;
24import org.openstreetmap.josm.tools.CheckParameterUtil;
25import org.openstreetmap.josm.tools.Logging;
26import org.xml.sax.SAXException;
27
28/**
29 * This is an asynchronous task for loading the parents of a given relation.
30 *
31 * Typical usage:
32 * <pre>
33 * final ParentRelationLoadingTask task = new ParentRelationLoadingTask(
34 * child, // the child relation
35 * Main.getLayerManager().getEditLayer(), // the edit layer
36 * true, // load fully
37 * new PleaseWaitProgressMonitor() // a progress monitor
38 * );
39 * task.setContinuation(
40 * new Runnable() {
41 * public void run() {
42 * if (task.isCanceled() || task.hasError())
43 * return;
44 * List&lt;Relation&gt; parents = task.getParents();
45 * // do something with the parent relations
46 * }
47 * );
48 *
49 * // start the task
50 * MainApplication.worker.submit(task);
51 * </pre>
52 *
53 */
54public class ParentRelationLoadingTask extends PleaseWaitRunnable {
55 private boolean canceled;
56 private Exception lastException;
57 private DataSet referrers;
58 private final boolean full;
59 private final OsmDataLayer layer;
60 private final Relation child;
61 private final List<Relation> parents;
62 private Runnable continuation;
63
64 /**
65 * Creates a new task for asynchronously downloading the parents of a child relation.
66 *
67 * @param child the child relation. Must not be null. Must have an id &gt; 0.
68 * @param layer the OSM data layer. Must not be null.
69 * @param full if true, parent relations are fully downloaded (i.e. with their members)
70 * @param monitor the progress monitor to be used
71 *
72 * @throws IllegalArgumentException if child is null
73 * @throws IllegalArgumentException if layer is null
74 * @throws IllegalArgumentException if child.getId() == 0
75 */
76 public ParentRelationLoadingTask(Relation child, OsmDataLayer layer, boolean full, PleaseWaitProgressMonitor monitor) {
77 super(tr("Download referring relations"), monitor, false /* don't ignore exception */);
78 CheckParameterUtil.ensureValidPrimitiveId(child, "child");
79 CheckParameterUtil.ensureParameterNotNull(layer, "layer");
80 referrers = null;
81 this.layer = layer;
82 parents = new ArrayList<>();
83 this.child = child;
84 this.full = full;
85 }
86
87 /**
88 * Set a continuation which is called upon the job finished.
89 *
90 * @param continuation the continuation
91 */
92 public void setContinuation(Runnable continuation) {
93 this.continuation = continuation;
94 }
95
96 /**
97 * Replies true if this has been canceled by the user.
98 *
99 * @return true if this has been canceled by the user.
100 */
101 public boolean isCanceled() {
102 return canceled;
103 }
104
105 /**
106 * Replies true if an exception has been caught during the execution of this task.
107 *
108 * @return true if an exception has been caught during the execution of this task.
109 */
110 public boolean hasError() {
111 return lastException != null;
112 }
113
114 protected OsmDataLayer getLayer() {
115 return layer;
116 }
117
118 public List<Relation> getParents() {
119 return parents;
120 }
121
122 @Override
123 protected void cancel() {
124 canceled = true;
125 OsmApi.getOsmApi().cancel();
126 }
127
128 protected void showLastException() {
129 JOptionPane.showMessageDialog(
130 Main.parent,
131 Optional.ofNullable(lastException.getMessage()).orElseGet(lastException::toString),
132 tr("Error"),
133 JOptionPane.ERROR_MESSAGE
134 );
135 }
136
137 @Override
138 protected void finish() {
139 if (canceled) return;
140 if (lastException != null) {
141 showLastException();
142 return;
143 }
144 parents.clear();
145 for (Relation parent : referrers.getRelations()) {
146 parents.add((Relation) getLayer().data.getPrimitiveById(parent));
147 }
148 if (continuation != null) {
149 continuation.run();
150 }
151 }
152
153 @Override
154 protected void realRun() throws SAXException, IOException, OsmTransferException {
155 try {
156 progressMonitor.indeterminateSubTask(null);
157 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(child, full);
158 referrers = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
159 if (referrers != null) {
160 final DataSetMerger visitor = new DataSetMerger(getLayer().data, referrers);
161 visitor.merge();
162
163 // copy the merged layer's data source info
164 getLayer().data.addDataSources(referrers.getDataSources());
165 // FIXME: this is necessary because there are dialogs listening
166 // for DataChangeEvents which manipulate Swing components on this thread.
167 SwingUtilities.invokeLater(getLayer()::onPostDownloadFromServer);
168
169 if (visitor.getConflicts().isEmpty())
170 return;
171 getLayer().getConflicts().add(visitor.getConflicts());
172 JOptionPane.showMessageDialog(
173 Main.parent,
174 tr("There were {0} conflicts during import.",
175 visitor.getConflicts().size()),
176 tr("Warning"),
177 JOptionPane.WARNING_MESSAGE
178 );
179 }
180 } catch (OsmTransferException e) {
181 if (canceled) {
182 Logging.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
183 return;
184 }
185 lastException = e;
186 }
187 }
188}
Note: See TracBrowser for help on using the repository browser.