// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.data.osm.history; import static org.openstreetmap.josm.tools.I18n.tr; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.openstreetmap.josm.data.osm.OsmPrimitiveType; import org.openstreetmap.josm.data.osm.PrimitiveId; import org.openstreetmap.josm.data.osm.SimplePrimitiveId; /** * Represents an immutable OSM primitive in the context of a historical view on * OSM data. * */ public abstract class HistoryOsmPrimitive implements Comparable { private long id; private boolean visible; private String user; private long uid; private long changesetId; private Date timestamp; private long version; private HashMap tags; protected void ensurePositiveLong(long value, String name) { if (value <= 0) throw new IllegalArgumentException(tr("Parameter ''{0}'' > 0 expected. Got ''{1}''.", name, value)); } protected void ensureNotNull(Object obj, String name) { if (obj == null) throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", name)); } /** * constructor * * @param id the id (>0 required) * @param version the version (> 0 required) * @param visible whether the primitive is still visible * @param user the user (! null required) * @param uid the user id (> 0 required) * @param changesetId the changeset id (may be null if the changeset isn't known) * @param timestamp the timestamp (! null required) * * @throws IllegalArgumentException thrown if preconditions are violated */ public HistoryOsmPrimitive(long id, long version, boolean visible, String user, long uid, long changesetId, Date timestamp) throws IllegalArgumentException { ensurePositiveLong(id, "id"); ensurePositiveLong(version, "version"); if(uid != -1) { ensurePositiveLong(uid, "uid"); } ensureNotNull(user, "user"); ensureNotNull(timestamp, "timestamp"); this.id = id; this.version = version; this.visible = visible; this.user = user; this.uid = uid; // FIXME: restrict to IDs > 0 as soon as OsmPrimitive holds the // changeset id too this.changesetId = changesetId; this.timestamp = timestamp; tags = new HashMap(); } public long getId() { return id; } public PrimitiveId getPrimitiveId() { return new SimplePrimitiveId(id, getType()); } public boolean isVisible() { return visible; } public String getUser() { return user; } public long getUid() { return uid; } public long getChangesetId() { return changesetId; } public Date getTimestamp() { return timestamp; } public long getVersion() { return version; } public boolean matches(long id, long version) { return this.id == id && this.version == version; } public boolean matches(long id) { return this.id == id; } public abstract OsmPrimitiveType getType(); public int compareTo(HistoryOsmPrimitive o) { if (this.id != o.id) throw new ClassCastException(tr("Can''t compare primitive with ID ''{0}'' to primitive with ID ''{1}''.", o.id, this.id)); return Long.valueOf(this.version).compareTo(o.version); } public void put(String key, String value) { tags.put(key, value); } public String get(String key) { return tags.get(key); } public boolean hasTag(String key) { return tags.get(key) != null; } public Map getTags() { return Collections.unmodifiableMap(tags); } /** * Sets the tags for this history primitive. Removes all * tags if tags is null. * * @param tags the tags. May be null. */ public void setTags(Map tags) { if (tags == null) { this.tags = new HashMap(); } else { this.tags = new HashMap(tags); } } /** * Replies the name of this primitive. The default implementation replies the value * of the tag name or null, if this tag is not present. * * @return the name of this primitive */ public String getName() { if (get("name") != null) return get("name"); return null; } /** * Replies the display name of a primitive formatted by formatter * * @return the display name */ public abstract String getDisplayName(HistoryNameFormatter formatter); /** * Replies the a localized name for this primitive given by the value of the tags (in this order) *
    *
  • name:lang_COUNTRY_Variant of the current locale
  • *
  • name:lang_COUNTRY of the current locale
  • *
  • name:lang of the current locale
  • *
  • name of the current locale
  • *
* * null, if no such tag exists * * @return the name of this primitive */ public String getLocalName() { String key = "name:" + Locale.getDefault().toString(); if (get(key) != null) return get(key); key = "name:" + Locale.getDefault().getLanguage() + "_" + Locale.getDefault().getCountry(); if (get(key) != null) return get(key); key = "name:" + Locale.getDefault().getLanguage(); if (get(key) != null) return get(key); return getName(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (id ^ (id >>> 32)); result = prime * result + (int) (version ^ (version >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof HistoryOsmPrimitive)) return false; // equal semantics is valid for subclasses like {@see HistoryOsmNode} etc. too. // So, don't enforce equality of class. // // if (getClass() != obj.getClass()) // return false; HistoryOsmPrimitive other = (HistoryOsmPrimitive) obj; if (id != other.id) return false; if (version != other.version) return false; return true; } }