001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.osm;
003
004import static org.openstreetmap.josm.tools.I18n.marktr;
005import static org.openstreetmap.josm.tools.I18n.tr;
006
007import java.text.MessageFormat;
008import java.util.Arrays;
009import java.util.Collection;
010
011public enum OsmPrimitiveType {
012
013    NODE (marktr(/* ICON(data/) */"node"), Node.class, NodeData.class),
014    WAY  (marktr(/* ICON(data/) */"way"), Way.class, WayData.class),
015    RELATION (marktr(/* ICON(data/) */"relation"), Relation.class, RelationData.class),
016
017    /* only for display, no real type */
018    CLOSEDWAY  (marktr(/* ICON(data/) */"closedway"), null, WayData.class),
019    MULTIPOLYGON (marktr(/* ICON(data/) */"multipolygon"), null, RelationData.class);
020
021    private static final Collection<OsmPrimitiveType> DATA_VALUES = Arrays.asList(NODE, WAY, RELATION);
022
023    private final String apiTypeName;
024    private final Class<? extends OsmPrimitive> osmClass;
025    private final Class<? extends PrimitiveData> dataClass;
026
027    OsmPrimitiveType(String apiTypeName, Class<? extends OsmPrimitive> osmClass, Class<? extends PrimitiveData> dataClass) {
028        this.apiTypeName = apiTypeName;
029        this.osmClass = osmClass;
030        this.dataClass = dataClass;
031    }
032
033    public String getAPIName() {
034        return apiTypeName;
035    }
036
037    public Class<? extends OsmPrimitive> getOsmClass() {
038        return osmClass;
039    }
040
041    public Class<? extends PrimitiveData> getDataClass() {
042        return dataClass;
043    }
044
045    public static OsmPrimitiveType fromApiTypeName(String typeName) {
046        for (OsmPrimitiveType type : OsmPrimitiveType.values()) {
047            if (type.getAPIName().equals(typeName)) return type;
048        }
049        throw new IllegalArgumentException(MessageFormat.format(
050                "Parameter ''{0}'' is not a valid type name. Got ''{1}''.", "typeName", typeName));
051    }
052
053    /**
054     * Determines the OSM primitive type of the given object.
055     * @param obj the OSM object to inspect
056     * @return the OSM primitive type of {@code obj}
057     * @throws IllegalArgumentException if {@code obj} is null or of unknown type
058     */
059    public static OsmPrimitiveType from(IPrimitive obj) {
060        if (obj instanceof INode) return NODE;
061        if (obj instanceof IWay) return WAY;
062        if (obj instanceof IRelation) return RELATION;
063        throw new IllegalArgumentException("Unknown type: "+obj);
064    }
065
066    public static OsmPrimitiveType from(String value) {
067        if (value == null) return null;
068        for (OsmPrimitiveType type: values()) {
069            if (type.getAPIName().equalsIgnoreCase(value))
070                return type;
071        }
072        return null;
073    }
074
075    public static Collection<OsmPrimitiveType> dataValues() {
076        return DATA_VALUES;
077    }
078
079    public OsmPrimitive newInstance(long uniqueId, boolean allowNegative) {
080        switch (this) {
081        case NODE:
082            return new Node(uniqueId, allowNegative);
083        case WAY:
084            return new Way(uniqueId, allowNegative);
085        case RELATION:
086            return new Relation(uniqueId, allowNegative);
087        default:
088            throw new AssertionError();
089        }
090    }
091
092    @Override
093    public String toString() {
094        return tr(getAPIName());
095    }
096}