001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm; 003 004import java.util.Arrays; 005import java.util.Collection; 006import java.util.Map; 007import java.util.Objects; 008 009/** 010 * Objects implement Tagged if they provide a map of key/value pairs. 011 * 012 * @since 2115 013 */ 014// FIXME: better naming? setTags(), getTags(), getKeys() instead of keySet() ? 015// 016public interface Tagged { 017 018 /** 019 * The maximum tag length allowed by OSM API 020 * @since 13414 021 */ 022 int MAX_TAG_LENGTH = 255; 023 024 /** 025 * Sets the map of key/value pairs 026 * 027 * @param keys the map of key value pairs. If null, reset to the empty map. 028 */ 029 void setKeys(Map<String, String> keys); 030 031 /** 032 * Replies the map of key/value pairs. Never null, but may be the empty map. 033 * 034 * @return the map of key/value pairs 035 */ 036 Map<String, String> getKeys(); 037 038 /** 039 * Calls the visitor for every key/value pair. 040 * 041 * @param visitor The visitor to call. 042 * @see #getKeys() 043 * @since 13668 044 */ 045 default void visitKeys(KeyValueVisitor visitor) { 046 getKeys().forEach((k, v) -> visitor.visitKeyValue(this, k, v)); 047 } 048 049 /** 050 * Sets a key/value pairs 051 * 052 * @param key the key 053 * @param value the value. If null, removes the key/value pair. 054 */ 055 void put(String key, String value); 056 057 /** 058 * Sets a key/value pairs 059 * 060 * @param tag The tag to set. 061 * @since 10736 062 */ 063 default void put(Tag tag) { 064 put(tag.getKey(), tag.getValue()); 065 } 066 067 /** 068 * Replies the value of the given key; null, if there is no value for this key 069 * 070 * @param key the key 071 * @return the value 072 */ 073 String get(String key); 074 075 /** 076 * Removes a given key/value pair 077 * 078 * @param key the key 079 */ 080 void remove(String key); 081 082 /** 083 * Replies true, if there is at least one key/value pair; false, otherwise 084 * 085 * @return true, if there is at least one key/value pair; false, otherwise 086 */ 087 boolean hasKeys(); 088 089 /** 090 * Replies true if there is a tag with key <code>key</code>. 091 * The value could however be empty. See {@link #hasTag(String)} to check for non-empty tags. 092 * 093 * @param key the key 094 * @return true, if there is a tag with key <code>key</code> 095 * @see #hasTag(String) 096 * @since 11608 097 */ 098 default boolean hasKey(String key) { 099 return get(key) != null; 100 } 101 102 /** 103 * Replies true if there is a non-empty tag with key <code>key</code>. 104 * 105 * @param key the key 106 * @return true, if there is a non-empty tag with key <code>key</code> 107 * @see Tagged#hasKey(String) 108 * @since 13430 109 */ 110 default boolean hasTag(String key) { 111 String v = get(key); 112 return v != null && !v.isEmpty(); 113 } 114 115 /** 116 * Tests whether this primitive contains a tag consisting of {@code key} and {@code value}. 117 * @param key the key forming the tag. 118 * @param value value forming the tag. 119 * @return true if primitive contains a tag consisting of {@code key} and {@code value}. 120 * @since 13668 121 */ 122 default boolean hasTag(String key, String value) { 123 return Objects.equals(value, get(key)); 124 } 125 126 /** 127 * Tests whether this primitive contains a tag consisting of {@code key} and any of {@code values}. 128 * @param key the key forming the tag. 129 * @param values one or many values forming the tag. 130 * @return true if primitive contains a tag consisting of {@code key} and any of {@code values}. 131 * @since 13668 132 */ 133 default boolean hasTag(String key, String... values) { 134 return hasTag(key, Arrays.asList(values)); 135 } 136 137 /** 138 * Tests whether this primitive contains a tag consisting of {@code key} and any of {@code values}. 139 * @param key the key forming the tag. 140 * @param values one or many values forming the tag. 141 * @return true if primitive contains a tag consisting of {@code key} and any of {@code values}. 142 * @since 13668 143 */ 144 default boolean hasTag(String key, Collection<String> values) { 145 String v = get(key); 146 return v != null && values.contains(v); 147 } 148 149 /** 150 * Tests whether this primitive contains a tag consisting of {@code key} and a value different from {@code value}. 151 * @param key the key forming the tag. 152 * @param value value not forming the tag. 153 * @return true if primitive contains a tag consisting of {@code key} and a value different from {@code value}. 154 * @since 13668 155 */ 156 default boolean hasTagDifferent(String key, String value) { 157 String v = get(key); 158 return v != null && !v.equals(value); 159 } 160 161 /** 162 * Tests whether this primitive contains a tag consisting of {@code key} and none of {@code values}. 163 * @param key the key forming the tag. 164 * @param values one or many values forming the tag. 165 * @return true if primitive contains a tag consisting of {@code key} and none of {@code values}. 166 * @since 13668 167 */ 168 default boolean hasTagDifferent(String key, String... values) { 169 return hasTagDifferent(key, Arrays.asList(values)); 170 } 171 172 /** 173 * Tests whether this primitive contains a tag consisting of {@code key} and none of {@code values}. 174 * @param key the key forming the tag. 175 * @param values one or many values forming the tag. 176 * @return true if primitive contains a tag consisting of {@code key} and none of {@code values}. 177 * @since 13668 178 */ 179 default boolean hasTagDifferent(String key, Collection<String> values) { 180 String v = get(key); 181 return v != null && !values.contains(v); 182 } 183 184 /** 185 * Replies the set of keys 186 * 187 * @return the set of keys 188 */ 189 Collection<String> keySet(); 190 191 /** 192 * Gets the number of keys 193 * @return The number of keys set for this tagged object. 194 * @since 13625 195 */ 196 int getNumKeys(); 197 198 /** 199 * Removes all tags 200 */ 201 void removeAll(); 202 203 /** 204 * Returns true if the {@code key} corresponds to an OSM true value. 205 * @param key OSM key 206 * @return {@code true} if the {@code key} corresponds to an OSM true value 207 * @see OsmUtils#isTrue(String) 208 */ 209 default boolean isKeyTrue(String key) { 210 return OsmUtils.isTrue(get(key)); 211 } 212 213 /** 214 * Returns true if the {@code key} corresponds to an OSM false value. 215 * @param key OSM key 216 * @return {@code true} if the {@code key} corresponds to an OSM false value 217 * @see OsmUtils#isFalse(String) 218 */ 219 default boolean isKeyFalse(String key) { 220 return OsmUtils.isFalse(get(key)); 221 } 222}