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

Last change on this file since 2512 was 2512, checked in by stoecker, 14 years ago

i18n updated, fixed files to reduce problems when applying patches, fix #4017

File size: 7.1 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.DataSource;
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.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.main.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.isCancelled() || task.hasError())
41 * return;
42 * List<Relation> 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 cancelled;
54 private Exception lastException;
55 private DataSet referrers;
56 private boolean full;
57 private OsmDataLayer layer;
58 private Relation child;
59 private ArrayList<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 > 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 * @exception IllegalArgumentException thrown if child is null
71 * @exception IllegalArgumentException thrown if layer is null
72 * @exception IllegalArgumentException thrown 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 if (child == null)
77 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", "child"));
78 if (layer == null)
79 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", "layer"));
80 if (child.isNew())
81 throw new IllegalArgumentException(tr("Value of child.getId() > 0 expected. Got {1}.", child.getId()));
82 referrers = null;
83 this.layer = layer;
84 parents = new ArrayList<Relation>();
85 this.child = child;
86 }
87
88 /**
89 * Set a continuation which is called upon the job finished.
90 *
91 * @param continuation the continuation
92 */
93 public void setContinuation(Runnable continuation) {
94 this.continuation = continuation;
95 }
96
97 /**
98 * Replies true if this has been cancelled by the user.
99 *
100 * @return true if this has been cancelled by the user.
101 */
102 public boolean isCancelled() {
103 return cancelled;
104 }
105
106 /**
107 * Replies true if an exception has been caught during the execution of this task.
108 *
109 * @return true if an exception has been caught during the execution of this task.
110 */
111 public boolean hasError() {
112 return lastException != null;
113 }
114
115 protected OsmDataLayer getLayer() {
116 return layer;
117 }
118
119 public List<Relation> getParents() {
120 return parents;
121 }
122
123 @Override
124 protected void cancel() {
125 cancelled = true;
126 OsmApi.getOsmApi().cancel();
127 }
128
129 protected void showLastException() {
130 String msg = lastException.getMessage();
131 if (msg == null) {
132 msg = lastException.toString();
133 }
134 JOptionPane.showMessageDialog(
135 Main.parent,
136 msg,
137 tr("Error"),
138 JOptionPane.ERROR_MESSAGE
139 );
140 }
141
142 @Override
143 protected void finish() {
144 if (cancelled) return;
145 if (lastException != null) {
146 showLastException();
147 return;
148 }
149 parents.clear();
150 for (Relation parent : referrers.getRelations()) {
151 parents.add((Relation) getLayer().data.getPrimitiveById(parent));
152 }
153 if (continuation != null) {
154 continuation.run();
155 }
156 }
157
158 @Override
159 protected void realRun() throws SAXException, IOException, OsmTransferException {
160 try {
161 progressMonitor.indeterminateSubTask(null);
162 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(child, full);
163 referrers = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
164 if (referrers != null) {
165 final DataSetMerger visitor = new DataSetMerger(getLayer().data, referrers);
166 visitor.merge();
167
168 // copy the merged layer's data source info
169 for (DataSource src : referrers.dataSources) {
170 getLayer().data.dataSources.add(src);
171 }
172 // FIXME: this is necessary because there are dialogs listening
173 // for DataChangeEvents which manipulate Swing components on this
174 // thread.
175 //
176 SwingUtilities.invokeLater(
177 new Runnable() {
178 public void run() {
179 getLayer().fireDataChange();
180 getLayer().onPostDownloadFromServer();
181 }
182 }
183 );
184
185 if (visitor.getConflicts().isEmpty())
186 return;
187 getLayer().getConflicts().add(visitor.getConflicts());
188 JOptionPane.showMessageDialog(
189 Main.parent,
190 tr("There were {0} conflicts during import.",
191 visitor.getConflicts().size()),
192 tr("Warning"),
193 JOptionPane.WARNING_MESSAGE
194 );
195 }
196 } catch(Exception e) {
197 if (cancelled) {
198 System.out.println(tr("Warning: Ignoring exception because task is cancelled. Exception: {0}", e.toString()));
199 return;
200 }
201 lastException = e;
202 }
203 }
204}
Note: See TracBrowser for help on using the repository browser.