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

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