1 package org.metricshub.jawk.jrt;
2
3 import java.util.Collection;
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 import java.util.Comparator;
28 import java.util.HashMap;
29 import java.util.LinkedHashMap;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.TreeMap;
33 import org.metricshub.jawk.intermediate.UninitializedObject;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class AssocArray implements Comparator<Object>, Map<Object, Object> {
49
50 private Map<Object, Object> map;
51
52
53
54
55
56
57
58
59 public AssocArray(boolean sortedArrayKeys) {
60 if (sortedArrayKeys) {
61 map = new TreeMap<Object, Object>((Comparator<Object>) this);
62 } else {
63 map = new HashMap<Object, Object>();
64 }
65 }
66
67
68
69
70
71 public static final int MT_HASH = 2;
72
73
74
75
76 public static final int MT_LINKED = 2 << 1;
77
78
79
80
81 public static final int MT_TREE = 2 << 2;
82
83
84
85
86
87
88
89
90 public void useMapType(int mapType) {
91 assert map.isEmpty();
92 switch (mapType) {
93 case MT_HASH:
94 map = new HashMap<Object, Object>();
95 break;
96 case MT_LINKED:
97 map = new LinkedHashMap<Object, Object>();
98 break;
99 case MT_TREE:
100 map = new TreeMap<Object, Object>((Comparator<Object>) this);
101 break;
102 default:
103 throw new Error("Invalid map type : " + mapType);
104 }
105 }
106
107
108
109
110
111
112
113 public String mapString() {
114
115
116
117 StringBuilder sb = new StringBuilder().append('{');
118 int cnt = 0;
119 for (Map.Entry<Object, Object> entry : map.entrySet()) {
120 if (cnt > 0) {
121 sb.append(", ");
122 }
123 Object key = entry.getKey();
124 if (key instanceof AssocArray) {
125 sb.append(((AssocArray) key).mapString());
126 } else {
127 sb.append(key.toString());
128 }
129 sb.append('=');
130 Object value = entry.getValue();
131 if (value instanceof AssocArray) {
132 sb.append(((AssocArray) value).mapString());
133 } else {
134 sb.append(value.toString());
135 }
136 ++cnt;
137 }
138 return sb.append('}').toString();
139 }
140
141
142 private static final UninitializedObject BLANK = new UninitializedObject();
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 public boolean isIn(Object key) {
158 if (key == null || key instanceof UninitializedObject) {
159
160
161 key = "";
162 }
163
164 if (map.containsKey(key)) {
165 return true;
166 }
167
168 try {
169 long iKey = Long.parseLong(key.toString());
170 if (map.containsKey(iKey)) {
171 return true;
172 }
173 } catch (Exception e) {
174 }
175
176 return false;
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190
191 public Object get(Object key) {
192 if (key == null || key instanceof UninitializedObject) {
193
194 key = "";
195 }
196 Object result = map.get(key);
197 if (result != null) {
198 return result;
199 }
200
201
202 try {
203
204 key = Long.parseLong(key.toString());
205 result = map.get(key);
206 if (result != null) {
207 return result;
208 }
209 } catch (Exception e) {
210 }
211
212
213
214
215 result = BLANK;
216 map.put(key, result);
217
218 return result;
219 }
220
221
222
223
224
225
226
227
228 public Object put(Object key, Object value) {
229 if (key == null || key instanceof UninitializedObject) {
230 key = "";
231 }
232 try {
233
234 long iKey = Long.parseLong(key.toString());
235 return map.put(iKey, value);
236 } catch (Exception e) {
237 }
238
239 return map.put(key, value);
240 }
241
242
243
244
245
246
247
248
249 public Object put(long key, Object value) {
250 return map.put(key, value);
251 }
252
253
254
255
256
257
258
259
260 public Set<Object> keySet() {
261 return map.keySet();
262 }
263
264
265
266
267 public void clear() {
268 map.clear();
269 }
270
271
272
273
274
275
276
277 public Object remove(Object key) {
278 if (key == null || key instanceof UninitializedObject) {
279 key = "";
280 }
281 Object result = map.remove(key);
282 if (result != null) {
283 return result;
284 }
285
286 try {
287 long iKey = Long.parseLong(key.toString());
288 return map.remove(iKey);
289 } catch (Exception e) {
290 }
291
292 return null;
293 }
294
295
296
297
298
299 @Override
300 public String toString() {
301 throw new AwkRuntimeException("Cannot evaluate an unindexed array.");
302 }
303
304
305
306
307
308
309 @Override
310 public int compare(Object o1, Object o2) {
311 if (o1 instanceof String
312 || o2 instanceof String
313 || !(o1 instanceof Number && o2 instanceof Number)) {
314
315
316 String s1 = o1.toString();
317 String s2 = o2.toString();
318 return s1.compareTo(s2);
319 }
320
321
322 if (o1 instanceof Double
323 || o2 instanceof Double
324 || o1 instanceof Float
325 || o2 instanceof Float) {
326 double d1 = ((Number) o1).doubleValue();
327 double d2 = ((Number) o2).doubleValue();
328 return Double.compare(d1, d2);
329 }
330
331 long l1 = ((Number) o1).longValue();
332 long l2 = ((Number) o2).longValue();
333 return Long.compare(l1, l2);
334 }
335
336
337
338
339
340
341
342
343 public String getMapVersion() {
344 return map.getClass().getPackage().getSpecificationVersion();
345 }
346
347 @Override
348 public int size() {
349 return map.size();
350 }
351
352 @Override
353 public boolean isEmpty() {
354 return map.isEmpty();
355 }
356
357 @Override
358 public boolean containsKey(Object key) {
359 return map.containsKey(key);
360 }
361
362 @Override
363 public boolean containsValue(Object value) {
364 return map.containsValue(value);
365 }
366
367 @Override
368 public void putAll(Map<? extends Object, ? extends Object> m) {
369 for (Map.Entry<? extends Object, ? extends Object> entry : m.entrySet()) {
370 map.put(entry.getKey(), entry.getValue());
371 }
372 }
373
374 @Override
375 public Collection<Object> values() {
376 return map.values();
377 }
378
379 @Override
380 public Set<Entry<Object, Object>> entrySet() {
381 return map.entrySet();
382 }
383 }