source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/LabelCompositionStrategy.java@ 10300

Last change on this file since 10300 was 10300, checked in by Don-vip, 8 years ago

sonar - Performance - Method passes constant String of length 1 to character overridden method + add unit tests/javadoc

  • Property svn:eol-style set to native
File size: 9.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint.styleelement;
3
4import java.util.ArrayList;
5import java.util.Arrays;
6import java.util.Collections;
7import java.util.List;
8import java.util.Objects;
9
10import org.openstreetmap.josm.Main;
11import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
12import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.tools.LanguageInfo;
15
16/**
17 * <p>Provides an abstract parent class and three concrete sub classes for various
18 * strategies on how to compose the text label which can be rendered close to a node
19 * or within an area in an OSM map.</p>
20 *
21 * <p>The three strategies below support three rules for composing a label:
22 * <ul>
23 * <li>{@link StaticLabelCompositionStrategy} - the label is given by a static text
24 * specified in the MapCSS style file</li>
25 *
26 * <li>{@link TagLookupCompositionStrategy} - the label is given by the content of a
27 * tag whose name specified in the MapCSS style file</li>
28 *
29 * <li>{@link DeriveLabelFromNameTagsCompositionStrategy} - the label is given by the value
30 * of one
31 * of the configured "name tags". The list of relevant name tags can be configured
32 * in the JOSM preferences
33 * content of a tag whose name specified in the MapCSS style file, see the preference
34 * options <tt>mappaint.nameOrder</tt> and <tt>mappaint.nameComplementOrder</tt>.</li>
35 * </ul>
36 *
37 */
38public abstract class LabelCompositionStrategy {
39
40 /**
41 * Replies the text value to be rendered as label for the primitive {@code primitive}.
42 *
43 * @param primitive the primitive
44 *
45 * @return the text value to be rendered or null, if primitive is null or
46 * if no suitable value could be composed
47 */
48 public abstract String compose(OsmPrimitive primitive);
49
50 public static class StaticLabelCompositionStrategy extends LabelCompositionStrategy {
51 private final String defaultLabel;
52
53 public StaticLabelCompositionStrategy(String defaultLabel) {
54 this.defaultLabel = defaultLabel;
55 }
56
57 @Override
58 public String compose(OsmPrimitive primitive) {
59 return defaultLabel;
60 }
61
62 public String getDefaultLabel() {
63 return defaultLabel;
64 }
65
66 @Override
67 public String toString() {
68 return '{' + getClass().getSimpleName() + " defaultLabel=" + defaultLabel + '}';
69 }
70
71 @Override
72 public int hashCode() {
73 return Objects.hash(defaultLabel);
74 }
75
76 @Override
77 public boolean equals(Object obj) {
78 if (this == obj) return true;
79 if (obj == null || getClass() != obj.getClass()) return false;
80 StaticLabelCompositionStrategy that = (StaticLabelCompositionStrategy) obj;
81 return Objects.equals(defaultLabel, that.defaultLabel);
82 }
83 }
84
85 public static class TagLookupCompositionStrategy extends LabelCompositionStrategy {
86
87 private final String defaultLabelTag;
88
89 public TagLookupCompositionStrategy(String defaultLabelTag) {
90 if (defaultLabelTag != null) {
91 defaultLabelTag = defaultLabelTag.trim();
92 if (defaultLabelTag.isEmpty()) {
93 defaultLabelTag = null;
94 }
95 }
96 this.defaultLabelTag = defaultLabelTag;
97 }
98
99 @Override
100 public String compose(OsmPrimitive primitive) {
101 if (defaultLabelTag == null) return null;
102 if (primitive == null) return null;
103 return primitive.get(defaultLabelTag);
104 }
105
106 public String getDefaultLabelTag() {
107 return defaultLabelTag;
108 }
109
110 @Override
111 public String toString() {
112 return '{' + getClass().getSimpleName() + " defaultLabelTag=" + defaultLabelTag + '}';
113 }
114
115 @Override
116 public int hashCode() {
117 return Objects.hash(defaultLabelTag);
118 }
119
120 @Override
121 public boolean equals(Object obj) {
122 if (this == obj) return true;
123 if (obj == null || getClass() != obj.getClass()) return false;
124 TagLookupCompositionStrategy that = (TagLookupCompositionStrategy) obj;
125 return Objects.equals(defaultLabelTag, that.defaultLabelTag);
126 }
127 }
128
129 public static class DeriveLabelFromNameTagsCompositionStrategy
130 extends LabelCompositionStrategy implements PreferenceChangedListener {
131
132 /**
133 * The list of default name tags from which a label candidate is derived.
134 */
135 private static final String[] DEFAULT_NAME_TAGS = {
136 "name:" + LanguageInfo.getJOSMLocaleCode(),
137 "name",
138 "int_name",
139 "distance",
140 "ref",
141 "operator",
142 "brand",
143 "addr:housenumber"
144 };
145
146 /**
147 * The list of default name complement tags from which a label candidate is derived.
148 */
149 private static final String[] DEFAULT_NAME_COMPLEMENT_TAGS = {
150 "capacity"
151 };
152
153 private List<String> nameTags = new ArrayList<>();
154 private List<String> nameComplementTags = new ArrayList<>();
155
156 /**
157 * <p>Creates the strategy and initializes its name tags from the preferences.</p>
158 */
159 public DeriveLabelFromNameTagsCompositionStrategy() {
160 initNameTagsFromPreferences();
161 }
162
163 private static List<String> buildNameTags(List<String> nameTags) {
164 if (nameTags == null) {
165 nameTags = Collections.emptyList();
166 }
167 List<String> result = new ArrayList<>();
168 for (String tag: nameTags) {
169 if (tag == null) {
170 continue;
171 }
172 tag = tag.trim();
173 if (tag.isEmpty()) {
174 continue;
175 }
176 result.add(tag);
177 }
178 return result;
179 }
180
181 /**
182 * Sets the name tags to be looked up in order to build up the label.
183 *
184 * @param nameTags the name tags. null values are ignored.
185 */
186 public void setNameTags(List<String> nameTags) {
187 this.nameTags = buildNameTags(nameTags);
188 }
189
190 /**
191 * Sets the name complement tags to be looked up in order to build up the label.
192 *
193 * @param nameComplementTags the name complement tags. null values are ignored.
194 * @since 6541
195 */
196 public void setNameComplementTags(List<String> nameComplementTags) {
197 this.nameComplementTags = buildNameTags(nameComplementTags);
198 }
199
200 /**
201 * Replies an unmodifiable list of the name tags used to compose the label.
202 *
203 * @return the list of name tags
204 */
205 public List<String> getNameTags() {
206 return Collections.unmodifiableList(nameTags);
207 }
208
209 /**
210 * Replies an unmodifiable list of the name complement tags used to compose the label.
211 *
212 * @return the list of name complement tags
213 * @since 6541
214 */
215 public List<String> getNameComplementTags() {
216 return Collections.unmodifiableList(nameComplementTags);
217 }
218
219 /**
220 * Initializes the name tags to use from a list of default name tags (see
221 * {@link #DEFAULT_NAME_TAGS} and {@link #DEFAULT_NAME_COMPLEMENT_TAGS})
222 * and from name tags configured in the preferences using the keys
223 * <tt>mappaint.nameOrder</tt> and <tt>mappaint.nameComplementOrder</tt>.
224 */
225 public final void initNameTagsFromPreferences() {
226 if (Main.pref == null) {
227 this.nameTags = new ArrayList<>(Arrays.asList(DEFAULT_NAME_TAGS));
228 this.nameComplementTags = new ArrayList<>(Arrays.asList(DEFAULT_NAME_COMPLEMENT_TAGS));
229 } else {
230 this.nameTags = new ArrayList<>(
231 Main.pref.getCollection("mappaint.nameOrder", Arrays.asList(DEFAULT_NAME_TAGS))
232 );
233 this.nameComplementTags = new ArrayList<>(
234 Main.pref.getCollection("mappaint.nameComplementOrder", Arrays.asList(DEFAULT_NAME_COMPLEMENT_TAGS))
235 );
236 }
237 }
238
239 private String getPrimitiveName(OsmPrimitive n) {
240 StringBuilder name = new StringBuilder();
241 if (!n.hasKeys()) return null;
242 for (String rn : nameTags) {
243 String val = n.get(rn);
244 if (val != null) {
245 name.append(val);
246 break;
247 }
248 }
249 for (String rn : nameComplementTags) {
250 String comp = n.get(rn);
251 if (comp != null) {
252 if (name.length() == 0) {
253 name.append(comp);
254 } else {
255 name.append(" (").append(comp).append(')');
256 }
257 break;
258 }
259 }
260 return name.toString();
261 }
262
263 @Override
264 public String compose(OsmPrimitive primitive) {
265 if (primitive == null) return null;
266 return getPrimitiveName(primitive);
267 }
268
269 @Override
270 public String toString() {
271 return '{' + getClass().getSimpleName() + '}';
272 }
273
274 @Override
275 public void preferenceChanged(PreferenceChangeEvent e) {
276 if (e.getKey() != null && e.getKey().startsWith("mappaint.name")) {
277 initNameTagsFromPreferences();
278 }
279 }
280 }
281}
Note: See TracBrowser for help on using the repository browser.