source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java@ 3865

Last change on this file since 3865 was 3865, checked in by bastiK, 13 years ago

mapcss: basic support for node shapes and some fine tuning

  • Property svn:eol-style set to native
File size: 5.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint;
3
4import java.awt.Color;
5import java.util.Arrays;
6import java.util.HashMap;
7import java.util.List;
8import java.util.Map;
9
10import org.openstreetmap.josm.gui.mappaint.mapcss.CSSColors;
11
12/**
13 * Simple map of properties with dynamic typing.
14 */
15public class Cascade implements Cloneable {
16
17 public static final Cascade EMPTY_CASCADE = new Cascade(false);
18
19 protected Map<String, Object> prop = new HashMap<String, Object>();
20
21 /**
22 * constructor
23 * @param isModifier Everything that is not on the default layer is assumed to
24 * be a modifier. Can be overridden in style definition.
25 */
26 public Cascade(boolean isModifier) {
27 if (isModifier) {
28 put("modifier", true);
29 }
30 }
31
32 private Cascade() {
33 }
34
35 public <T> T get(String key, T def, Class<T> klass) {
36 return get(key, def, klass, false);
37 }
38
39 /**
40 * Get value for the given key
41 * @param key the key
42 * @param def default value, can be null
43 * @param klass the same as T
44 * @param suppressWarnings show or don't show a warning when some value is
45 * found, but cannot be converted to the requested type
46 * @return if a value with class klass has been mapped to key, returns this
47 * value, def otherwise
48 */
49 public <T> T get(String key, T def, Class<T> klass, boolean suppressWarnings) {
50 if (def != null && !klass.isInstance(def))
51 throw new IllegalArgumentException();
52 Object o = prop.get(key);
53 if (o == null)
54 return def;
55 T res = convertTo(o, klass);
56 if (res == null) {
57 if (!suppressWarnings) {
58 System.err.println(String.format("Warning: unable to convert property %s to type %s: found %s of type %s!", key, klass, o, o.getClass()));
59 }
60 return def;
61 } else
62 return res;
63 }
64
65 public Object get(String key) {
66 return prop.get(key);
67 }
68
69 @SuppressWarnings("unchecked")
70 public static <T> T convertTo(Object o, Class<T> klass) {
71 if (o == null)
72 return null;
73 if (klass.isInstance(o))
74 return (T) o;
75
76 if (klass == float.class || klass == Float.class)
77 return (T) toFloat(o);
78
79 if (klass == double.class || klass == Double.class) {
80 o = toFloat(o);
81 if (o != null) {
82 o = new Double((Float) o);
83 }
84 return (T) o;
85 }
86
87 if (klass == boolean.class || klass == Boolean.class)
88 return (T) toBool(o);
89
90 if (klass == float[].class) {
91 return (T) toFloatArray(o);
92 }
93
94 if (klass == Color.class) {
95 return (T) toColor(o);
96 }
97 return null;
98 }
99
100 private static Float toFloat(Object o) {
101 if (o instanceof Float)
102 return (Float) o;
103 if (o instanceof Double)
104 return new Float((Double) o);
105 if (o instanceof Integer)
106 return new Float((Integer) o);
107 if (o instanceof String) {
108 try {
109 float f = Float.parseFloat((String) o);
110 return f;
111 } catch (NumberFormatException e) {
112 }
113 }
114 return null;
115 }
116
117 private static Boolean toBool(Object o) {
118 if (o instanceof Boolean)
119 return (Boolean) o;
120 if (o instanceof String)
121 return Boolean.parseBoolean((String) o);
122 return null;
123 }
124
125 private static float[] toFloatArray(Object o) {
126 if (o instanceof float[])
127 return (float[]) o;
128 if (o instanceof List) {
129 List l = (List) o;
130 float[] a = new float[l.size()];
131 for (int i=0; i<l.size(); ++i) {
132 Float f = toFloat(l.get(i));
133 if (f == null)
134 return null;
135 else
136 a[i] = f;
137 }
138 return a;
139 }
140 return null;
141 }
142
143 public static Color toColor(Object o) {
144 if (o instanceof Color)
145 return (Color) o;
146 if (o instanceof String)
147 return CSSColors.get((String) o);
148 return null;
149 }
150
151 public void put(String key, Object val) {
152 prop.put(key, val);
153 }
154
155 public void putOrClear(String key, Object val) {
156 if (val != null) {
157 prop.put(key, val);
158 } else {
159 prop.remove(key);
160 }
161 }
162
163 public void remove(String key) {
164 prop.remove(key);
165 }
166
167 @Override
168 public Cascade clone() {
169 @SuppressWarnings("unchecked")
170 HashMap<String, Object> clonedProp = (HashMap) ((HashMap) this.prop).clone();
171 Cascade c = new Cascade();
172 c.prop = clonedProp;
173 return c;
174 }
175
176 @Override
177 public String toString() {
178 StringBuilder res = new StringBuilder("Cascade{ ");
179 for (String key : prop.keySet()) {
180 res.append(key+":");
181 Object val = prop.get(key);
182 if (val instanceof float[]) {
183 res.append(Arrays.toString((float[]) val));
184 } else if (val instanceof Color) {
185 res.append(String.format("#%x", ((Color) val).getRGB()));
186 } else {
187 res.append(val+"");
188 }
189 res.append("; ");
190 }
191 return res.append("}").toString();
192 }
193
194 public boolean containsKey(String key) {
195 return prop.containsKey(key);
196 }
197}
Note: See TracBrowser for help on using the repository browser.