001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.gpx;
003
004import java.util.Collection;
005import java.util.HashMap;
006import java.util.Map;
007
008/**
009 * Default implementation for IWithAttributes.
010 *
011 * Base class for various classes in the GPX model.
012 *
013 * @author Frederik Ramm
014 * @since 444
015 */
016public class WithAttributes implements IWithAttributes, GpxConstants {
017
018    /**
019     * The "attr" hash is used to store the XML payload (not only XML attributes!)
020     */
021    public Map<String, Object> attr = new HashMap<>(0);
022
023    /**
024     * Returns the Object value to which the specified key is mapped,
025     * or {@code null} if this map contains no mapping for the key.
026     *
027     * @param key the key whose associated value is to be returned
028     * @return the value
029     */
030    @Override
031    public Object get(String key) {
032        return attr.get(key);
033    }
034
035    /**
036     * Returns the String value to which the specified key is mapped,
037     * or {@code null} if this map contains no String mapping for the key.
038     *
039     * @param key the key whose associated value is to be returned
040     * @return the String value to which the specified key is mapped,
041     *         or {@code null} if this map contains no String mapping for the key
042     */
043    @Override
044    public String getString(String key) {
045        Object value = attr.get(key);
046        return (value instanceof String) ? (String) value : null;
047    }
048
049    /**
050     * Returns the Collection value to which the specified key is mapped,
051     * or {@code null} if this map contains no Collection mapping for the key.
052     *
053     * @param key the key whose associated value is to be returned
054     * @return the Collection value to which the specified key is mapped,
055     *         or {@code null} if this map contains no Collection mapping for the key
056     * @since 5502
057     */
058    @SuppressWarnings("unchecked")
059    @Override
060    public <T> Collection<T> getCollection(String key) {
061        Object value = attr.get(key);
062        return (value instanceof Collection) ? (Collection<T>) value : null;
063    }
064
065    /**
066     * Put a key / value pair as a new attribute.
067     *
068     * Overrides key / value pair with the same key (if present).
069     *
070     * @param key the key
071     * @param value the value
072     */
073    @Override
074    public void put(String key, Object value) {
075        attr.put(key, value);
076    }
077
078    /**
079     * Add a key / value pair that is not part of the GPX schema as an extension.
080     *
081     * @param key the key
082     * @param value the value
083     */
084    @Override
085    public void addExtension(String key, String value) {
086        if (!attr.containsKey(META_EXTENSIONS)) {
087            attr.put(META_EXTENSIONS, new Extensions());
088        }
089        Extensions ext = (Extensions) attr.get(META_EXTENSIONS);
090        ext.put(key, value);
091    }
092
093    @Override
094    public int hashCode() {
095        return 31 + ((attr == null) ? 0 : attr.hashCode());
096    }
097
098    @Override
099    public boolean equals(Object obj) {
100        if (this == obj)
101            return true;
102        if (obj == null)
103            return false;
104        if (getClass() != obj.getClass())
105            return false;
106        WithAttributes other = (WithAttributes) obj;
107        if (attr == null) {
108            if (other.attr != null)
109                return false;
110        } else if (!attr.equals(other.attr))
111            return false;
112        return true;
113    }
114}