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

Last change on this file since 13014 was 12713, checked in by bastiK, 7 years ago

see #15229 - remove dependencies of CheckParameterUtil on various data classes

  • 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 * MainApplication.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.ensure(pid, "pid", "pid > 0", id -> id.getUniqueId() > 0);
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.ensure(primitive, "primitive", "id > 0", prim -> prim.getUniqueId() > 0);
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 add(primitive);
139 }
140 }
141 return this;
142 }
143
144 @Override
145 protected void cancel() {
146 if (reader != null) {
147 reader.cancel();
148 }
149 canceled = true;
150 }
151
152 @Override
153 protected void finish() {
154 if (isCanceled())
155 return;
156 if (lastException != null) {
157 ExceptionDialogUtil.explainException(lastException);
158 return;
159 }
160 HistoryDataSet.getInstance().mergeInto(loadedData);
161 }
162
163 @Override
164 protected void realRun() throws SAXException, IOException, OsmTransferException {
165 loadedData = new HistoryDataSet();
166 try {
167 progressMonitor.setTicksCount(toLoad.size());
168 for (PrimitiveId pid: toLoad) {
169 if (canceled) {
170 break;
171 }
172 loadHistory(pid);
173 }
174 } catch (OsmTransferException e) {
175 lastException = e;
176 return;
177 }
178 }
179
180 private void loadHistory(PrimitiveId pid) throws OsmTransferException {
181 String msg = getLoadingMessage(pid);
182 progressMonitor.indeterminateSubTask(tr(msg, Long.toString(pid.getUniqueId())));
183 reader = null;
184 HistoryDataSet ds;
185 try {
186 reader = new OsmServerHistoryReader(pid.getType(), pid.getUniqueId());
187 ds = loadHistory(reader, progressMonitor);
188 } catch (OsmTransferException e) {
189 if (canceled)
190 return;
191 throw e;
192 }
193 loadedData.mergeInto(ds);
194 }
195
196 protected static HistoryDataSet loadHistory(OsmServerHistoryReader reader, ProgressMonitor progressMonitor) throws OsmTransferException {
197 HistoryDataSet ds = reader.parseHistory(progressMonitor.createSubTaskMonitor(1, false));
198 if (ds != null) {
199 // load corresponding changesets (mostly for changeset comment)
200 OsmServerChangesetReader changesetReader = new OsmServerChangesetReader();
201 List<Long> changesetIds = new ArrayList<>(ds.getChangesetIds());
202
203 // query changesets 100 by 100 (OSM API limit)
204 int n = ChangesetQuery.MAX_CHANGESETS_NUMBER;
205 for (int i = 0; i < changesetIds.size(); i += n) {
206 for (Changeset c : changesetReader.queryChangesets(
207 new ChangesetQuery().forChangesetIds(changesetIds.subList(i, Math.min(i + n, changesetIds.size()))),
208 progressMonitor.createSubTaskMonitor(1, false))) {
209 ds.putChangeset(c);
210 }
211 }
212 }
213 return ds;
214 }
215
216 protected static String getLoadingMessage(PrimitiveId pid) {
217 switch (pid.getType()) {
218 case NODE:
219 return marktr("Loading history for node {0}");
220 case WAY:
221 return marktr("Loading history for way {0}");
222 case RELATION:
223 return marktr("Loading history for relation {0}");
224 default:
225 return "";
226 }
227 }
228
229 /**
230 * Determines if this task has ben canceled.
231 * @return {@code true} if this task has ben canceled
232 */
233 public boolean isCanceled() {
234 return canceled;
235 }
236
237 /**
238 * Returns the last exception that occured during loading, if any.
239 * @return the last exception that occured during loading, or {@code null}
240 */
241 public Exception getLastException() {
242 return lastException;
243 }
244}
Note: See TracBrowser for help on using the repository browser.