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 011/** 012 * OSM primitive type. 013 * @since 1670 014 */ 015public enum OsmPrimitiveType { 016 017 /** Node type */ 018 NODE(marktr(/* ICON(data/) */"node"), Node.class, NodeData.class, Node.idGenerator), 019 /** Way type */ 020 WAY(marktr(/* ICON(data/) */"way"), Way.class, WayData.class, Way.idGenerator), 021 /** Relation type */ 022 RELATION(marktr(/* ICON(data/) */"relation"), Relation.class, RelationData.class, Relation.idGenerator), 023 024 /** Closed way: only for display, no real type */ 025 CLOSEDWAY(marktr(/* ICON(data/) */"closedway"), null, WayData.class, Way.idGenerator), 026 /** Multipolygon: only for display, no real type */ 027 MULTIPOLYGON(marktr(/* ICON(data/) */"multipolygon"), null, RelationData.class, Relation.idGenerator); 028 029 private static final Collection<OsmPrimitiveType> DATA_VALUES = Arrays.asList(NODE, WAY, RELATION); 030 031 private final String apiTypeName; 032 private final Class<? extends OsmPrimitive> osmClass; 033 private final Class<? extends PrimitiveData> dataClass; 034 @SuppressWarnings("ImmutableEnumChecker") 035 private final UniqueIdGenerator idGenerator; 036 037 OsmPrimitiveType(String apiTypeName, Class<? extends OsmPrimitive> osmClass, Class<? extends PrimitiveData> dataClass, 038 UniqueIdGenerator idGenerator) { 039 this.apiTypeName = apiTypeName; 040 this.osmClass = osmClass; 041 this.dataClass = dataClass; 042 this.idGenerator = idGenerator; 043 } 044 045 /** 046 * Returns the API type name / JOSM display name. 047 * @return the API type name / JOSM display name 048 */ 049 public String getAPIName() { 050 return apiTypeName; 051 } 052 053 /** 054 * Returns the OSM class for data values, or null. 055 * @return the OSM class for data values, or null 056 */ 057 public Class<? extends OsmPrimitive> getOsmClass() { 058 return osmClass; 059 } 060 061 /** 062 * Returns the data class. 063 * @return the data class 064 */ 065 public Class<? extends PrimitiveData> getDataClass() { 066 return dataClass; 067 } 068 069 /** 070 * Returns enum value from API type name / JOSM display name, case sensitive. 071 * @param typeName API type name / JOSM display name, case sensitive 072 * @return matching enum value 073 * @throws IllegalArgumentException if the type name does not match any valid type 074 * @see #from(String) 075 */ 076 public static OsmPrimitiveType fromApiTypeName(String typeName) { 077 for (OsmPrimitiveType type : OsmPrimitiveType.values()) { 078 if (type.getAPIName().equals(typeName)) return type; 079 } 080 throw new IllegalArgumentException(MessageFormat.format( 081 "Parameter ''{0}'' is not a valid type name. Got ''{1}''.", "typeName", typeName)); 082 } 083 084 /** 085 * Determines the OSM primitive type of the given object. 086 * @param obj the OSM object to inspect 087 * @return the OSM primitive type of {@code obj} 088 * @throws IllegalArgumentException if {@code obj} is null or of unknown type 089 */ 090 public static OsmPrimitiveType from(IPrimitive obj) { 091 if (obj instanceof INode) return NODE; 092 if (obj instanceof IWay) return WAY; 093 if (obj instanceof IRelation) return RELATION; 094 throw new IllegalArgumentException("Unknown type: "+obj); 095 } 096 097 /** 098 * Returns enum value from API type name / JOSM display name, case insensitive. 099 * @param value API type name / JOSM display name, case insensitive 100 * @return matching enum value or null 101 * @see #fromApiTypeName 102 */ 103 public static OsmPrimitiveType from(String value) { 104 return Arrays.stream(values()) 105 .filter(type -> type.getAPIName().equalsIgnoreCase(value)) 106 .findFirst().orElse(null); 107 } 108 109 /** 110 * Returns the values matching real OSM API data types (node, way, relation). 111 * @return the values matching real OSM API data types (node, way, relation) 112 */ 113 public static Collection<OsmPrimitiveType> dataValues() { 114 return DATA_VALUES; 115 } 116 117 /** 118 * Constructs a new primitive instance (node, way or relation) without version. 119 * @param uniqueId the unique id 120 * @param allowNegative {@code true} to allow negative id 121 * @return a new primitive instance (node, way or relation) 122 * @throws IllegalArgumentException if uniqueId < 0 and allowNegative is false 123 */ 124 public OsmPrimitive newInstance(long uniqueId, boolean allowNegative) { 125 switch (this) { 126 case NODE: 127 return new Node(uniqueId, allowNegative); 128 case WAY: 129 return new Way(uniqueId, allowNegative); 130 case RELATION: 131 return new Relation(uniqueId, allowNegative); 132 default: 133 throw new AssertionError(); 134 } 135 } 136 137 /** 138 * Constructs a new primitive instance (node, way or relation) with given version. 139 * @param id The id. Must be >= 0 140 * @param version The version 141 * @return a new primitive instance (node, way or relation) with given version 142 * @throws IllegalArgumentException if id < 0 143 * @since 12018 144 */ 145 public OsmPrimitive newVersionedInstance(long id, int version) { 146 switch (this) { 147 case NODE: 148 return new Node(id, version); 149 case WAY: 150 return new Way(id, version); 151 case RELATION: 152 return new Relation(id, version); 153 default: 154 throw new AssertionError(); 155 } 156 } 157 158 /** 159 * Returns the unique identifier generator. 160 * @return the unique identifier generator 161 * @since 15820 162 */ 163 public final UniqueIdGenerator getIdGenerator() { 164 return idGenerator; 165 } 166 167 @Override 168 public String toString() { 169 return tr(getAPIName()); 170 } 171}