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

Last change on this file since 2273 was 2273, checked in by jttt, 15 years ago

Replace testing for id <= 0 with isNew() method

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