source: josm/trunk/src/org/openstreetmap/josm/gui/history/HistoryLoadTask.java@ 11366

Last change on this file since 11366 was 11087, checked in by Don-vip, 8 years ago

sonar - squid:S1141 - Try-catch blocks should not be nested

  • Property svn:eol-style set to native
File size: 8.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.history;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.Component;
8import java.io.IOException;
9import java.util.ArrayList;
10import java.util.Collection;
11import java.util.HashSet;
12import java.util.List;
13import java.util.Set;
14
15import org.openstreetmap.josm.data.osm.Changeset;
16import org.openstreetmap.josm.data.osm.OsmPrimitive;
17import org.openstreetmap.josm.data.osm.PrimitiveId;
18import org.openstreetmap.josm.data.osm.history.History;
19import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
20import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
21import org.openstreetmap.josm.gui.ExceptionDialogUtil;
22import org.openstreetmap.josm.gui.PleaseWaitRunnable;
23import org.openstreetmap.josm.gui.progress.ProgressMonitor;
24import org.openstreetmap.josm.io.ChangesetQuery;
25import org.openstreetmap.josm.io.OsmServerChangesetReader;
26import org.openstreetmap.josm.io.OsmServerHistoryReader;
27import org.openstreetmap.josm.io.OsmTransferException;
28import org.openstreetmap.josm.tools.CheckParameterUtil;
29import org.xml.sax.SAXException;
30
31/**
32 * Loads the object history of a collection of objects from the server.
33 *
34 * It provides a fluent API for configuration.
35 *
36 * Sample usage:
37 *
38 * <pre>
39 * HistoryLoadTask task = new HistoryLoadTask()
40 * .add(node)
41 * .add(way)
42 * .add(relation)
43 * .add(aHistoryItem);
44 *
45 * Main.worker.execute(task);
46 * </pre>
47 */
48public class HistoryLoadTask extends PleaseWaitRunnable {
49
50 private boolean canceled;
51 private Exception lastException;
52 private final Set<PrimitiveId> toLoad = new HashSet<>();
53 private HistoryDataSet loadedData;
54 private OsmServerHistoryReader reader;
55
56 /**
57 * Constructs a new {@code HistoryLoadTask}.
58 */
59 public HistoryLoadTask() {
60 super(tr("Load history"), true);
61 }
62
63 /**
64 * Constructs a new {@code HistoryLoadTask}.
65 *
66 * @param parent the component to be used as reference to find the
67 * parent for {@link org.openstreetmap.josm.gui.PleaseWaitDialog}.
68 * Must not be <code>null</code>.
69 * @throws IllegalArgumentException if parent is <code>null</code>
70 */
71 public HistoryLoadTask(Component parent) {
72 super(parent, tr("Load history"), true);
73 CheckParameterUtil.ensureParameterNotNull(parent, "parent");
74 }
75
76 /**
77 * Adds an object whose history is to be loaded.
78 *
79 * @param pid the primitive id. Must not be null. Id &gt; 0 required.
80 * @return this task
81 */
82 public HistoryLoadTask add(PrimitiveId pid) {
83 CheckParameterUtil.ensureValidPrimitiveId(pid, "pid");
84 toLoad.add(pid);
85 return this;
86 }
87
88 /**
89 * Adds an object to be loaded, the object is specified by a history item.
90 *
91 * @param primitive the history item
92 * @return this task
93 * @throws IllegalArgumentException if primitive is null
94 */
95 public HistoryLoadTask add(HistoryOsmPrimitive primitive) {
96 CheckParameterUtil.ensureParameterNotNull(primitive, "primitive");
97 return add(primitive.getPrimitiveId());
98 }
99
100 /**
101 * Adds an object to be loaded, the object is specified by an already loaded object history.
102 *
103 * @param history the history. Must not be null.
104 * @return this task
105 * @throws IllegalArgumentException if history is null
106 */
107 public HistoryLoadTask add(History history) {
108 CheckParameterUtil.ensureParameterNotNull(history, "history");
109 return add(history.getPrimitiveId());
110 }
111
112 /**
113 * Adds an object to be loaded, the object is specified by an OSM primitive.
114 *
115 * @param primitive the OSM primitive. Must not be null. primitive.getId() &gt; 0 required.
116 * @return this task
117 * @throws IllegalArgumentException if the primitive is null
118 * @throws IllegalArgumentException if primitive.getId() &lt;= 0
119 */
120 public HistoryLoadTask add(OsmPrimitive primitive) {
121 CheckParameterUtil.ensureValidPrimitiveId(primitive, "primitive");
122 return add(primitive.getPrimitiveId());
123 }
124
125 /**
126 * Adds a collection of objects to loaded, specified by a collection of OSM primitives.
127 *
128 * @param primitives the OSM primitives. Must not be <code>null</code>.
129 * <code>primitive.getId() &gt; 0</code> required.
130 * @return this task
131 * @throws IllegalArgumentException if primitives is <code>null</code>
132 * @throws IllegalArgumentException if one of the ids in the collection &lt;= 0
133 */
134 public HistoryLoadTask add(Collection<? extends OsmPrimitive> primitives) {
135 CheckParameterUtil.ensureParameterNotNull(primitives, "primitives");
136 for (OsmPrimitive primitive: primitives) {
137 if (primitive == null) {
138 continue;
139 }
140 add(primitive);
141 }
142 return this;
143 }
144
145 @Override
146 protected void cancel() {
147 if (reader != null) {
148 reader.cancel();
149 }
150 canceled = true;
151 }
152
153 @Override
154 protected void finish() {
155 if (isCanceled())
156 return;
157 if (lastException != null) {
158 ExceptionDialogUtil.explainException(lastException);
159 return;
160 }
161 HistoryDataSet.getInstance().mergeInto(loadedData);
162 }
163
164 @Override
165 protected void realRun() throws SAXException, IOException, OsmTransferException {
166 loadedData = new HistoryDataSet();
167 try {
168 progressMonitor.setTicksCount(toLoad.size());
169 for (PrimitiveId pid: toLoad) {
170 if (canceled) {
171 break;
172 }
173 loadHistory(pid);
174 }
175 } catch (OsmTransferException e) {
176 lastException = e;
177 return;
178 }
179 }
180
181 private void loadHistory(PrimitiveId pid) throws OsmTransferException {
182 String msg = getLoadingMessage(pid);
183 progressMonitor.indeterminateSubTask(tr(msg, Long.toString(pid.getUniqueId())));
184 reader = null;
185 HistoryDataSet ds;
186 try {
187 reader = new OsmServerHistoryReader(pid.getType(), pid.getUniqueId());
188 ds = loadHistory(reader, progressMonitor);
189 } catch (OsmTransferException e) {
190 if (canceled)
191 return;
192 throw e;
193 }
194 loadedData.mergeInto(ds);
195 }
196
197 protected static HistoryDataSet loadHistory(OsmServerHistoryReader reader, ProgressMonitor progressMonitor) throws OsmTransferException {
198 HistoryDataSet ds = reader.parseHistory(progressMonitor.createSubTaskMonitor(1, false));
199 if (ds != null) {
200 // load corresponding changesets (mostly for changeset comment)
201 OsmServerChangesetReader changesetReader = new OsmServerChangesetReader();
202 List<Long> changesetIds = new ArrayList<>(ds.getChangesetIds());
203
204 // query changesets 100 by 100 (OSM API limit)
205 int n = ChangesetQuery.MAX_CHANGESETS_NUMBER;
206 for (int i = 0; i < changesetIds.size(); i += n) {
207 for (Changeset c : changesetReader.queryChangesets(
208 new ChangesetQuery().forChangesetIds(changesetIds.subList(i, Math.min(i + n, changesetIds.size()))),
209 progressMonitor.createSubTaskMonitor(1, false))) {
210 ds.putChangeset(c);
211 }
212 }
213 }
214 return ds;
215 }
216
217 protected static String getLoadingMessage(PrimitiveId pid) {
218 switch (pid.getType()) {
219 case NODE:
220 return marktr("Loading history for node {0}");
221 case WAY:
222 return marktr("Loading history for way {0}");
223 case RELATION:
224 return marktr("Loading history for relation {0}");
225 default:
226 return "";
227 }
228 }
229
230 /**
231 * Determines if this task has ben canceled.
232 * @return {@code true} if this task has ben canceled
233 */
234 public boolean isCanceled() {
235 return canceled;
236 }
237
238 /**
239 * Returns the last exception that occured during loading, if any.
240 * @return the last exception that occured during loading, or {@code null}
241 */
242 public Exception getLastException() {
243 return lastException;
244 }
245}
Note: See TracBrowser for help on using the repository browser.