// 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.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.openstreetmap.josm.data.osm.Changeset; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.PrimitiveId; 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.gui.progress.ProgressMonitor; 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 a collection of objects from the server. * * It provides a fluent API for configuration. * * Sample usage: * *
* HistoryLoadTask task = new HistoryLoadTask() * .add(node) * .add(way) * .add(relation) * .add(aHistoryItem); * * MainApplication.worker.execute(task); **/ public class HistoryLoadTask extends PleaseWaitRunnable { private boolean canceled; private Exception lastException; private final Set
null
.
* @throws IllegalArgumentException if parent is null
*/
public HistoryLoadTask(Component parent) {
super(parent, tr("Load history"), true);
CheckParameterUtil.ensureParameterNotNull(parent, "parent");
}
/**
* 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.ensure(pid, "pid", "pid > 0", id -> id.getUniqueId() > 0);
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");
return add(primitive.getPrimitiveId());
}
/**
* 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");
return add(history.getPrimitiveId());
}
/**
* 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.ensure(primitive, "primitive", "id > 0", prim -> prim.getUniqueId() > 0);
return add(primitive.getPrimitiveId());
}
/**
* 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) {
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;
}
loadHistory(pid);
}
} catch (OsmTransferException e) {
lastException = e;
return;
}
}
private void loadHistory(PrimitiveId pid) throws OsmTransferException {
String msg = getLoadingMessage(pid);
progressMonitor.indeterminateSubTask(tr(msg, Long.toString(pid.getUniqueId())));
reader = null;
HistoryDataSet ds;
try {
reader = new OsmServerHistoryReader(pid.getType(), pid.getUniqueId());
ds = loadHistory(reader, progressMonitor);
} catch (OsmTransferException e) {
if (canceled)
return;
throw e;
}
loadedData.mergeInto(ds);
}
protected static HistoryDataSet loadHistory(OsmServerHistoryReader reader, ProgressMonitor progressMonitor) throws OsmTransferException {
HistoryDataSet ds = reader.parseHistory(progressMonitor.createSubTaskMonitor(1, false));
if (ds != null) {
// load corresponding changesets (mostly for changeset comment)
OsmServerChangesetReader changesetReader = new OsmServerChangesetReader();
List