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

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

More uses of OsmDataLayer.getDataSet()

  • Property svn:eol-style set to native
File size: 6.7 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.swing.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 * MainApplication.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.ensure(child, "child", "id > 0", ch -> ch.getUniqueId() > 0);
79 CheckParameterUtil.ensureParameterNotNull(layer, "layer");
80 if (!layer.isDownloadable()) {
81 throw new IllegalArgumentException("Non-downloadable layer: " + layer);
82 }
83 referrers = null;
84 this.layer = layer;
85 parents = new ArrayList<>();
86 this.child = child;
87 this.full = full;
88 }
89
90 /**
91 * Set a continuation which is called upon the job finished.
92 *
93 * @param continuation the continuation
94 */
95 public void setContinuation(Runnable continuation) {
96 this.continuation = continuation;
97 }
98
99 /**
100 * Replies true if this has been canceled by the user.
101 *
102 * @return true if this has been canceled by the user.
103 */
104 public boolean isCanceled() {
105 return canceled;
106 }
107
108 /**
109 * Replies true if an exception has been caught during the execution of this task.
110 *
111 * @return true if an exception has been caught during the execution of this task.
112 */
113 public boolean hasError() {
114 return lastException != null;
115 }
116
117 protected OsmDataLayer getLayer() {
118 return layer;
119 }
120
121 public List<Relation> getParents() {
122 return parents;
123 }
124
125 @Override
126 protected void cancel() {
127 canceled = true;
128 OsmApi.getOsmApi().cancel();
129 }
130
131 protected void showLastException() {
132 JOptionPane.showMessageDialog(
133 Main.parent,
134 Optional.ofNullable(lastException.getMessage()).orElseGet(lastException::toString),
135 tr("Error"),
136 JOptionPane.ERROR_MESSAGE
137 );
138 }
139
140 @Override
141 protected void finish() {
142 if (canceled) return;
143 if (lastException != null) {
144 showLastException();
145 return;
146 }
147 parents.clear();
148 for (Relation parent : referrers.getRelations()) {
149 parents.add((Relation) getLayer().data.getPrimitiveById(parent));
150 }
151 if (continuation != null) {
152 continuation.run();
153 }
154 }
155
156 @Override
157 protected void realRun() throws SAXException, IOException, OsmTransferException {
158 try {
159 progressMonitor.indeterminateSubTask(null);
160 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(child, full);
161 referrers = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
162 if (referrers != null) {
163 final DataSetMerger visitor = new DataSetMerger(getLayer().getDataSet(), referrers);
164 visitor.merge();
165
166 // copy the merged layer's data source info
167 getLayer().getDataSet().addDataSources(referrers.getDataSources());
168 // FIXME: this is necessary because there are dialogs listening
169 // for DataChangeEvents which manipulate Swing components on this thread.
170 SwingUtilities.invokeLater(getLayer()::onPostDownloadFromServer);
171
172 if (visitor.getConflicts().isEmpty())
173 return;
174 getLayer().getConflicts().add(visitor.getConflicts());
175 JOptionPane.showMessageDialog(
176 Main.parent,
177 tr("There were {0} conflicts during import.",
178 visitor.getConflicts().size()),
179 tr("Warning"),
180 JOptionPane.WARNING_MESSAGE
181 );
182 }
183 } catch (OsmTransferException e) {
184 if (canceled) {
185 Logging.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
186 return;
187 }
188 lastException = e;
189 }
190 }
191}
Note: See TracBrowser for help on using the repository browser.