// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.gui.history; import static org.openstreetmap.josm.tools.I18n.marktr; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.Component; import java.io.IOException; import java.text.MessageFormat; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.openstreetmap.josm.data.osm.Changeset; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.OsmPrimitiveType; import org.openstreetmap.josm.data.osm.PrimitiveId; import org.openstreetmap.josm.data.osm.SimplePrimitiveId; import org.openstreetmap.josm.data.osm.history.History; import org.openstreetmap.josm.data.osm.history.HistoryDataSet; import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive; import org.openstreetmap.josm.gui.ExceptionDialogUtil; import org.openstreetmap.josm.gui.PleaseWaitRunnable; import org.openstreetmap.josm.io.ChangesetQuery; import org.openstreetmap.josm.io.OsmServerChangesetReader; import org.openstreetmap.josm.io.OsmServerHistoryReader; import org.openstreetmap.josm.io.OsmTransferException; import org.openstreetmap.josm.tools.CheckParameterUtil; import org.xml.sax.SAXException; /** * Loads the object history of an collection of objects from the * server. * * It provides a fluent API for configuration. * * Sample usage: * *
* HistoryLoadTask task = new HistoryLoadTask() * .add(1, OsmPrimitiveType.NODE) * .add(1233, OsmPrimitiveType.WAY) * .add(37234, OsmPrimitveType.RELATION) * .add(aHistoryItem); * * Main.worker.execute(task); * **/ public class HistoryLoadTask extends PleaseWaitRunnable { private boolean canceled = false; private Exception lastException = null; private Set
null
.
* @throws IllegalArgumentException if parent is null
*/
public HistoryLoadTask(Component parent) {
super(parent, tr("Load history"), true);
CheckParameterUtil.ensureParameterNotNull(parent, "parent");
toLoad = new HashSet<>();
}
/**
* Adds an object whose history is to be loaded.
*
* @param id the object id
* @param type the object type
* @return this task
*/
public HistoryLoadTask add(long id, OsmPrimitiveType type) {
if (id <= 0)
throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' > 0 expected. Got {1}.", "id", id));
CheckParameterUtil.ensureParameterNotNull(type, "type");
SimplePrimitiveId pid = new SimplePrimitiveId(id, type);
toLoad.add(pid);
return this;
}
/**
* Adds an object whose history is to be loaded.
*
* @param pid the primitive id. Must not be null. Id > 0 required.
* @return this task
*/
public HistoryLoadTask add(PrimitiveId pid) {
CheckParameterUtil.ensureValidPrimitiveId(pid, "pid");
toLoad.add(pid);
return this;
}
/**
* Adds an object to be loaded, the object is specified by a history item.
*
* @param primitive the history item
* @return this task
* @throws IllegalArgumentException if primitive is null
*/
public HistoryLoadTask add(HistoryOsmPrimitive primitive) {
CheckParameterUtil.ensureParameterNotNull(primitive, "primitive");
toLoad.add(primitive.getPrimitiveId());
return this;
}
/**
* Adds an object to be loaded, the object is specified by an already loaded object history.
*
* @param history the history. Must not be null.
* @return this task
* @throws IllegalArgumentException if history is null
*/
public HistoryLoadTask add(History history) {
CheckParameterUtil.ensureParameterNotNull(history, "history");
toLoad.add(history.getPrimitiveId());
return this;
}
/**
* Adds an object to be loaded, the object is specified by an OSM primitive.
*
* @param primitive the OSM primitive. Must not be null. primitive.getId() > 0 required.
* @return this task
* @throws IllegalArgumentException if the primitive is null
* @throws IllegalArgumentException if primitive.getId() <= 0
*/
public HistoryLoadTask add(OsmPrimitive primitive) {
CheckParameterUtil.ensureValidPrimitiveId(primitive, "primitive");
toLoad.add(primitive.getPrimitiveId());
return this;
}
/**
* Adds a collection of objects to loaded, specified by a collection of OSM primitives.
*
* @param primitives the OSM primitives. Must not be null
.
* primitive.getId() > 0
required.
* @return this task
* @throws IllegalArgumentException if primitives is null
* @throws IllegalArgumentException if one of the ids in the collection <= 0
*/
public HistoryLoadTask add(Collection extends OsmPrimitive> primitives) {
CheckParameterUtil.ensureParameterNotNull(primitives, "primitives");
for (OsmPrimitive primitive: primitives) {
if (primitive == null) {
continue;
}
add(primitive);
}
return this;
}
@Override
protected void cancel() {
if (reader != null) {
reader.cancel();
}
canceled = true;
}
@Override
protected void finish() {
if (isCanceled())
return;
if (lastException != null) {
ExceptionDialogUtil.explainException(lastException);
return;
}
HistoryDataSet.getInstance().mergeInto(loadedData);
}
@Override
protected void realRun() throws SAXException, IOException, OsmTransferException {
loadedData = new HistoryDataSet();
try {
progressMonitor.setTicksCount(toLoad.size());
for(PrimitiveId pid: toLoad) {
if (canceled) {
break;
}
String msg = "";
switch(pid.getType()) {
case NODE: msg = marktr("Loading history for node {0}"); break;
case WAY: msg = marktr("Loading history for way {0}"); break;
case RELATION: msg = marktr("Loading history for relation {0}"); break;
}
progressMonitor.indeterminateSubTask(tr(msg,
Long.toString(pid.getUniqueId())));
reader = null;
HistoryDataSet ds = null;
try {
reader = new OsmServerHistoryReader(pid.getType(), pid.getUniqueId());
ds = reader.parseHistory(progressMonitor.createSubTaskMonitor(1, false));
// load corresponding changesets (mostly for changeset comment)
for (final Changeset i : new OsmServerChangesetReader().queryChangesets(
new ChangesetQuery().forChangesetIds(ds.getChangesetIds()), progressMonitor.createSubTaskMonitor(1, false))) {
ds.putChangeset(i);
}
} catch(OsmTransferException e) {
if (canceled)
return;
throw e;
}
loadedData.mergeInto(ds);
}
} catch(OsmTransferException e) {
lastException = e;
return;
}
}
public boolean isCanceled() {
return canceled;
}
public Exception getLastException() {
return lastException;
}
}