// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.data.osm;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
import org.openstreetmap.josm.tools.CheckParameterUtil;
/**
* A ChangesetDataSet holds the content of a changeset.
*/
public class ChangesetDataSet {
/**
* Type of primitive modification.
*/
public enum ChangesetModificationType {
/** The primitive has been created */
CREATED,
/** The primitive has been updated */
UPDATED,
/** The primitive has been deleted */
DELETED
}
/**
* An entry in the changeset dataset.
*/
public interface ChangesetDataSetEntry {
/**
* Returns the type of modification.
* @return the type of modification
*/
ChangesetModificationType getModificationType();
/**
* Returns the affected history primitive.
* @return the affected history primitive
*/
HistoryOsmPrimitive getPrimitive();
}
private final Map<PrimitiveId, HistoryOsmPrimitive> primitives = new HashMap<>();
private final Map<PrimitiveId, ChangesetModificationType> modificationTypes = new HashMap<>();
/**
* Remembers a history primitive with the given modification type
*
* @param primitive the primitive. Must not be null.
* @param cmt the modification type. Must not be null.
* @throws IllegalArgumentException if primitive is null
* @throws IllegalArgumentException if cmt is null
*/
public void put(HistoryOsmPrimitive primitive, ChangesetModificationType cmt) {
CheckParameterUtil.ensureParameterNotNull(primitive, "primitive");
CheckParameterUtil.ensureParameterNotNull(cmt, "cmt");
primitives.put(primitive.getPrimitiveId(), primitive);
modificationTypes.put(primitive.getPrimitiveId(), cmt);
}
/**
* Replies true if the changeset content contains the object with primitive <code>id</code>.
* @param id the id.
* @return true if the changeset content contains the object with primitive <code>id</code>
*/
public boolean contains(PrimitiveId id) {
if (id == null) return false;
return primitives.containsKey(id);
}
/**
* Replies the modification type for the object with id <code>id</code>. Replies null, if id is null or
* if the object with id <code>id</code> isn't in the changeset content.
*
* @param id the id
* @return the modification type
*/
public ChangesetModificationType getModificationType(PrimitiveId id) {
if (!contains(id)) return null;
return modificationTypes.get(id);
}
/**
* Replies true if the primitive with id <code>id</code> was created in this
* changeset. Replies false, if id is null.
*
* @param id the id
* @return true if the primitive with id <code>id</code> was created in this
* changeset.
*/
public boolean isCreated(PrimitiveId id) {
if (!contains(id)) return false;
return ChangesetModificationType.CREATED.equals(getModificationType(id));
}
/**
* Replies true if the primitive with id <code>id</code> was updated in this
* changeset. Replies false, if id is null.
*
* @param id the id
* @return true if the primitive with id <code>id</code> was updated in this
* changeset.
*/
public boolean isUpdated(PrimitiveId id) {
if (!contains(id)) return false;
return ChangesetModificationType.UPDATED.equals(getModificationType(id));
}
/**
* Replies true if the primitive with id <code>id</code> was deleted in this
* changeset. Replies false, if id is null.
*
* @param id the id
* @return true if the primitive with id <code>id</code> was deleted in this
* changeset.
*/
public boolean isDeleted(PrimitiveId id) {
if (!contains(id)) return false;
return ChangesetModificationType.DELETED.equals(getModificationType(id));
}
/**
* Replies the set of primitives with a specific modification type
*
* @param cmt the modification type. Must not be null.
* @return the set of primitives
* @throws IllegalArgumentException if cmt is null
*/
public Set<HistoryOsmPrimitive> getPrimitivesByModificationType(ChangesetModificationType cmt) {
CheckParameterUtil.ensureParameterNotNull(cmt, "cmt");
return modificationTypes.entrySet().stream()
.filter(entry -> entry.getValue().equals(cmt))
.map(entry -> primitives.get(entry.getKey()))
.collect(Collectors.toSet());
}
/**
* Replies the number of objects in the dataset
*
* @return the number of objects in the dataset
*/
public int size() {
return primitives.size();
}
/**
* Replies the {@link HistoryOsmPrimitive} with id <code>id</code> from this dataset.
* null, if there is no such primitive in the data set.
*
* @param id the id
* @return the {@link HistoryOsmPrimitive} with id <code>id</code> from this dataset
*/
public HistoryOsmPrimitive getPrimitive(PrimitiveId id) {
if (id == null) return null;
return primitives.get(id);
}
/**
* Returns an iterator over dataset entries.
* @return an iterator over dataset entries
*/
public Iterator<ChangesetDataSetEntry> iterator() {
return new DefaultIterator();
}
private static class DefaultChangesetDataSetEntry implements ChangesetDataSetEntry {
private final ChangesetModificationType modificationType;
private final HistoryOsmPrimitive primitive;
DefaultChangesetDataSetEntry(ChangesetModificationType modificationType, HistoryOsmPrimitive primitive) {
this.modificationType = modificationType;
this.primitive = primitive;
}
@Override
public ChangesetModificationType getModificationType() {
return modificationType;
}
@Override
public HistoryOsmPrimitive getPrimitive() {
return primitive;
}
}
private class DefaultIterator implements Iterator<ChangesetDataSetEntry> {
private final Iterator<Entry<PrimitiveId, ChangesetModificationType>> typeIterator;
DefaultIterator() {
typeIterator = modificationTypes.entrySet().iterator();
}
@Override
public boolean hasNext() {
return typeIterator.hasNext();
}
@Override
public ChangesetDataSetEntry next() {
Entry<PrimitiveId, ChangesetModificationType> next = typeIterator.next();
return new DefaultChangesetDataSetEntry(next.getValue(), primitives.get(next.getKey()));
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}