地质所 沉降监测网建设项目
zmk
2024-05-15 9e3afc6d0fa514f986d3fea40fa23124e6fb5070
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
package com.javaweb.common.json;
 
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.javaweb.common.utils.StringUtils;
 
/**
 * 通用消息对象,基于Map实现的可嵌套数据结构。 支持JSON数据结构。
 * 
 * @author ruoyi
 */
public class JSONObject extends LinkedHashMap<String, Object>
{
    private static final long serialVersionUID = 1L;
    private static final Pattern arrayNamePattern = Pattern.compile("(\\w+)((\\[\\d+\\])+)");
    private static final ObjectMapper objectMapper = new ObjectMapper();
 
    /**
     * 数组结构。
     */
    public static class JSONArray extends ArrayList<Object>
    {
        private static final long serialVersionUID = 1L;
 
        public JSONArray()
        {
            super();
        }
 
        public JSONArray(int size)
        {
            super(size);
        }
 
        @Override
        public String toString()
        {
            try
            {
                return JSON.marshal(this);
            }
            catch (Exception e)
            {
                throw new RuntimeException(e);
            }
        }
 
        @Override
        public Object set(int index, Object element)
        {
            return super.set(index, transfer(element));
        }
 
        @Override
        public boolean add(Object element)
        {
            return super.add(transfer(element));
        }
 
        @Override
        public void add(int index, Object element)
        {
            super.add(index, transfer(element));
        }
    }
 
    public JSONObject()
    {
        super();
    }
 
    public JSONObject(final JSONObject other)
    {
        super(other);
    }
 
    @Override
    public String toString()
    {
        try
        {
            return JSON.marshal(this);
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }
 
    /**
     * 转换为紧凑格式的字符串。
     * 
     * @return 返回本对象紧凑格式字符串。
     */
    public String toCompactString()
    {
        try
        {
            return objectMapper.writeValueAsString(this);
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }
 
    /**
     * 获取指定字段的整数值。如果字段不存在,或者无法转换为整数,返回null。
     * 
     * @param name 字段名,支持多级。
     * @return 返回指定的整数值,或者null。
     */
    public Integer intValue(final String name)
    {
        return valueAsInt(value(name));
    }
 
    /**
     * 获取指定字段的整数值。如果字段不存在,或者无法转换为整数,返回defaultValue。
     * 
     * @param name 字段名,支持多级。
     * @param defaultValue 查询失败时,返回的值。
     * @return 返回指定的整数值,或者defaultValue。
     */
    public Integer intValue(final String name, final Integer defaultValue)
    {
        return StringUtils.nvl(intValue(name), defaultValue);
    }
 
    /**
     * 获取指定字段的长整数值。如果字段不存在,或者无法转换为长整数,返回null。
     * 
     * @param name 字段名,支持多级。
     * @return 返回指定的长整数值,或者null。
     */
    public Long longValue(final String name)
    {
        return valueAsLong(value(name));
    }
 
    /**
     * 获取指定字段的长整数值。如果字段不存在,或者无法转换为长整数,返回defaultValue。
     * 
     * @param name 字段名,支持多级。
     * @param defaultValue 查询失败时,返回的值。
     * @return 返回指定的长整数值,或者defaultValue。
     */
    public Long longValue(final String name, final Long defaultValue)
    {
        return StringUtils.nvl(longValue(name), defaultValue);
    }
 
    /**
     * 获取指定字段的布尔值。如果字段不存在,或者无法转换为布尔型,返回null。
     * 
     * @param name 字段名,支持多级。
     * @return 返回指定的布尔值,或者null。
     */
    public Boolean boolValue(final String name)
    {
        return valueAsBool(value(name));
    }
 
    /**
     * 获取指定字段的布尔值。如果字段不存在,或者无法转换为布尔型,返回defaultValue。
     * 
     * @param name 字段名,支持多级。
     * @param defaultValue 查询失败时,返回的值。
     * @return 返回指定的布尔值,或者defaultValue。
     */
    public Boolean boolValue(final String name, final Boolean defaultValue)
    {
        return StringUtils.nvl(boolValue(name), defaultValue);
    }
 
    /**
     * 获取指定字段的字符串值。如果字段不存在,返回null。
     * 
     * @param name 字段名,支持多级。
     * @return 返回指定的字符串值,或者null。
     */
    public String strValue(final String name)
    {
        return valueAsStr(value(name));
    }
 
    /**
     * 获取指定字段的字符串值。如果字段不存在,返回defaultValue。
     * 
     * @param name 字段名,支持多级。
     * @param defaultValue 查询失败时,返回的值。
     * @return 返回指定的字符串值,或者defaultValue。
     */
    public String strValue(final String name, final String defaultValue)
    {
        return StringUtils.nvl(strValue(name), defaultValue);
    }
 
    /**
     * 获取指定字段的值。
     * 
     * @param name 字段名,支持多级,支持数组下标。
     * @return 返回指定字段的值。
     */
    public Object value(final String name)
    {
        final int indexDot = name.indexOf('.');
        if (indexDot >= 0)
        {
            return obj(name.substring(0, indexDot)).value(name.substring(indexDot + 1));
        }
        else
        {
            final Matcher matcher = arrayNamePattern.matcher(name);
            if (matcher.find())
            {
                return endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<Object>()
                {
                    @Override
                    public Object callback(JSONArray arr, int index)
                    {
                        return elementAt(arr, index);
                    }
                });
            }
            else
            {
                return get(name);
            }
        }
    }
 
    /**
     * 设置指定字段的值。
     * 
     * @param name 字段名,支持多级,支持数组下标。
     * @param value 字段值。
     * @return 返回本对象。
     */
    public JSONObject value(final String name, final Object value)
    {
        final int indexDot = name.indexOf('.');
        if (indexDot >= 0)
        {
            obj(name.substring(0, indexDot)).value(name.substring(indexDot + 1), value);
        }
        else
        {
            final Matcher matcher = arrayNamePattern.matcher(name);
            if (matcher.find())
            {
                endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<Void>()
                {
                    @Override
                    public Void callback(JSONArray arr, int index)
                    {
                        elementAt(arr, index, value);
                        return null;
                    }
                });
            }
            else
            {
                set(name, value);
            }
        }
        return this;
    }
 
    /**
     * 获取对象(非标量类型)字段。返回的数据是一个结构体。当不存在指定对象时,则为指定的名字创建一个空的MessageObject对象。
     * 
     * @param name 字段名。不支持多级名字,支持数组下标。
     * @return 返回指定的对象。如果对象不存在,则为指定的名字创建一个空的MessageObject对象。
     */
    public JSONObject obj(final String name)
    {
        final Matcher matcher = arrayNamePattern.matcher(name);
        if (matcher.find())
        {
            return endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<JSONObject>()
            {
                @Override
                public JSONObject callback(JSONArray arr, int index)
                {
                    return objAt(arr, index);
                }
            });
        }
        else
        {
            JSONObject obj = getObj(name);
            if (obj == null)
            {
                obj = new JSONObject();
                put(name, obj);
            }
            return obj;
        }
    }
 
    /**
     * 获取数组字段。将名字对应的对象以数组对象返回,当指定的字段不存在时,创建一个空的数组。
     * 
     * @param name 字段名。不支持多级名字,不支持下标。
     * @return 返回一个数组(List)。
     */
    public JSONArray arr(final String name)
    {
        JSONArray arr = getArr(name);
        if (arr == null)
        {
            arr = new JSONArray();
            put(name, arr);
        }
        return arr;
    }
 
    /**
     * 获取对象(非标量类型)字段。返回的数据是一个结构体。
     * 
     * @param name 字段名。
     * @return 返回指定的对象字段。
     */
    public JSONObject getObj(final String name)
    {
        return (JSONObject) get(name);
    }
 
    /**
     * 获取数组类型字段。
     * 
     * @param name 字段名。
     * @return 返回数组类型字段。
     */
    public JSONArray getArr(final String name)
    {
        return (JSONArray) get(name);
    }
 
    /**
     * 返回字段整数值。如果不存在,返回null。
     * 
     * @param name 字段名。
     * @return 返回指定字段整数值。
     */
    public Integer getInt(final String name)
    {
        return valueAsInt(get(name));
    }
 
    /**
     * 返回字段整数值。如果不存在,返回defaultValue。
     * 
     * @param name 字段名。
     * @param defaultValue 字段不存在时,返回的值。
     * @return 返回指定字段整数值。
     */
    public Integer getInt(final String name, Integer defaultValue)
    {
        return StringUtils.nvl(getInt(name), defaultValue);
    }
 
    /**
     * 返回字段长整数值。如果不存在,返回null。
     * 
     * @param name 字段名。
     * @return 返回指定字段长整数值。
     */
    public Long getLong(final String name)
    {
        return valueAsLong(get(name));
    }
 
    /**
     * 返回字段长整数值。如果不存在,返回defaultValue。
     * 
     * @param name 字段名。
     * @param defaultValue 字段不存在时,返回的值。
     * @return 返回指定字段长整数值。
     */
    public Long getLong(final String name, Long defaultValue)
    {
        return StringUtils.nvl(getLong(name), defaultValue);
    }
 
    /**
     * 返回字段字符串值。如果不存在,返回null。
     * 
     * @param name 字段名。
     * @return 返回指定字段字符串值。
     */
    public String getStr(final String name)
    {
        return valueAsStr(get(name));
    }
 
    /**
     * 返回字段字符串值。如果不存在,返回defaultValue。
     * 
     * @param name 字段名。
     * @param defaultValue 字段不存在时,返回的值。
     * @return 返回指定字段字符串值。
     */
    public String getStr(final String name, final String defaultValue)
    {
        return StringUtils.nvl(getStr(name), defaultValue);
    }
 
    /**
     * 字段值按照布尔类型返回。如果不存在,返回null。
     * 
     * @param name 字段名。
     * @return 字段值。
     */
    public Boolean getBool(final String name)
    {
        return valueAsBool(get(name));
    }
 
    /**
     * 字段值按照布尔类型返回。如果不存在,返回defaultValue。
     * 
     * @param name 字段名。
     * @param defaultValue 字段不存在时,返回的值。
     * @return 字段值。
     */
    public Boolean getBool(final String name, final Boolean defaultValue)
    {
        return StringUtils.nvl(getBool(name), defaultValue);
    }
 
    /**
     * 设置字段值
     * 
     * @param name 字段名
     * @param value 字段值(标量:数字、字符串、布尔型;结构体:MessageObject)。 如果是Map类型同时非MessageObject类型,则自动转换为MessageObject类型再存入
     *            (此时,再修改Map中的数据,将不会体现到本对象中)。
     * @return 返回本对象
     */
    public JSONObject set(final String name, final Object value)
    {
        put(name, value);
        return this;
    }
 
    /**
     * 将本对象转换为Java Bean。
     * 
     * @param beanClass Java Bean的类对象。
     * @return 返回转换后的Java Bean。
     */
    public <T> T asBean(Class<T> beanClass)
    {
        try
        {
            return JSON.unmarshal(JSON.marshal(this), beanClass);
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }
 
    /**
     * 重载基类的方法。如果 value 是 Map 类型,但不是 MessageObject 类型,则创建一个包含内容等同于原 Map 的 MessageObject 作为 value(注意:此后再更改 Map 的内容,将不会反映到
     * MessageObject 中)。 重载此方法的目的是为了使JSON能够正确地解析为MessageObject对象。不建议直接调用此方法,请使用 set(name, value)方法设置字段值。
     */
    @Override
    public Object put(String key, Object value)
    {
        return super.put(key, transfer(value));
    }
 
    public static Integer valueAsInt(Object value)
    {
        if (value instanceof Integer)
        {
            return (Integer) value;
        }
        else if (value instanceof Number)
        {
            return ((Number) value).intValue();
        }
        else if (value instanceof String)
        {
            return Integer.valueOf((String) value);
        }
        else if (value instanceof Boolean)
        {
            return ((Boolean) value) ? 1 : 0;
        }
        else
        {
            return null;
        }
    }
 
    public static Long valueAsLong(Object value)
    {
        if (value instanceof Long)
        {
            return (Long) value;
        }
        else if (value instanceof Number)
        {
            return ((Number) value).longValue();
        }
        else if (value instanceof String)
        {
            return Long.valueOf((String) value);
        }
        else if (value instanceof Boolean)
        {
            return ((Boolean) value) ? 1L : 0L;
        }
        else
        {
            return null;
        }
    }
 
    public static String valueAsStr(Object value)
    {
        if (value instanceof String)
        {
            return (String) value;
        }
        else if (value != null)
        {
            return value.toString();
        }
        else
        {
            return null;
        }
    }
 
    public static Boolean valueAsBool(Object value)
    {
        if (value instanceof Boolean)
        {
            return (Boolean) value;
        }
        else if (value instanceof Number)
        {
            return ((Number) value).doubleValue() != 0.0;
        }
        else if (value instanceof String)
        {
            return Boolean.valueOf((String) value);
        }
        else
        {
            return null;
        }
    }
 
    /**
     * 将所有层次中凡是Map类型同时又不是MessageObject的类型,转换为MessageObject类型。
     * 
     * @param value 值。
     * @return 返回转换后的值。
     */
    @SuppressWarnings("unchecked")
    private static Object transfer(final Object value)
    {
        if (!(value instanceof JSONObject) && value instanceof Map)
        {
            return toObj((Map<String, Object>) value);
        }
        else if (!(value instanceof JSONArray) && value instanceof Collection)
        {
            return toArr((Collection<Object>) value);
        }
        else
        {
            return value;
        }
    }
 
    private static JSONArray toArr(final Collection<Object> list)
    {
        final JSONArray arr = new JSONArray(list.size());
        for (final Object element : list)
        {
            arr.add(element);
        }
        return arr;
    }
 
    private static JSONObject toObj(final Map<String, Object> map)
    {
        final JSONObject obj = new JSONObject();
        for (final Map.Entry<String, Object> ent : map.entrySet())
        {
            obj.put(ent.getKey(), transfer(ent.getValue()));
        }
        return obj;
    }
 
    /**
     * 将指定下标元素作为数组返回,如果不存在,则在该位置创建一个空的数组。
     * 
     * @param arr 当前数组。
     * @param index 下标。
     * @return 返回当前数组指定下标的元素,该元素应该是一个数组。
     */
    private static JSONArray arrayAt(JSONArray arr, int index)
    {
        expand(arr, index);
        if (arr.get(index) == null)
        {
            arr.set(index, new JSONArray());
        }
        return (JSONArray) arr.get(index);
    }
 
    /**
     * 将指定下标元素作为结构体返回,如果不存在,则在该位置创建一个空的结构体。
     * 
     * @param arr 当前数组。
     * @param index 下标。
     * @return 返回当前数组指定下标元素,该元素是一个结构体。
     */
    private static JSONObject objAt(final JSONArray arr, int index)
    {
        expand(arr, index);
        if (arr.get(index) == null)
        {
            arr.set(index, new JSONObject());
        }
        return (JSONObject) arr.get(index);
    }
 
    /**
     * 设置数组指定下标位置的值。
     * 
     * @param arr 数组。
     * @param index 下标。
     * @param value 值。
     */
    private static void elementAt(final JSONArray arr, final int index, final Object value)
    {
        expand(arr, index).set(index, value);
    }
 
    /**
     * 获取数组指定下标元素的值。
     * 
     * @param arr 数组。
     * @param index 下标。
     * @return 值。
     */
    private static Object elementAt(final JSONArray arr, final int index)
    {
        return expand(arr, index).get(index);
    }
 
    /**
     * 扩展数组到指定下标,以防止访问时下标越界。
     * 
     * @param arr 数组
     * @param index 下标
     * @return 返回传入的数组
     */
    private static JSONArray expand(final JSONArray arr, final int index)
    {
        while (arr.size() <= index)
        {
            arr.add(null);
        }
        return arr;
    }
 
    /**
     * 最后数组回调。
     * 
     * @author Mike
     *
     * @param <T> 回调返回数据类型。
     */
    private interface EndArrayCallback<T>
    {
        /**
         * 当定位到最后一级数组,将调用本方法。
         * 
         * @param arr 最后一级数组对象。
         * @param index 最后一级索引。
         * @return 返回回调的返回值。
         */
        T callback(JSONArray arr, int index);
    }
 
    /**
     * 处理多维数组的工具函数(包括一维数组)。多维数组的名字如:arrary[1][2][3], 则name=array,indexStr=[1][2][3],在callback中,endArr将是
     * array[1][2]指定的对象,indexe=3。
     * 
     * @param name 不带下标的名字,不支持多级名字。
     * @param indexesStr 索引部分的字符串,如:[1][2][3]
     * @param callback 回调函数。
     * @return 返回回调函数的返回值。
     */
    private <T> T endArray(final String name, final String indexesStr, final EndArrayCallback<T> callback)
    {
        JSONArray endArr = arr(name);
        final int[] indexes = parseIndexes(indexesStr);
        int i = 0;
        while (i < indexes.length - 1)
        {
            endArr = arrayAt(endArr, indexes[i++]);
        }
        return callback.callback(endArr, indexes[i]);
    }
 
    private static int[] parseIndexes(final String s)
    {
        int[] indexes = null;
        List<Integer> list = new ArrayList<Integer>();
 
        final StringTokenizer st = new StringTokenizer(s, "[]");
        while (st.hasMoreTokens())
        {
            final int index = Integer.valueOf(st.nextToken());
            if (index < 0)
            {
                throw new RuntimeException(String.format("Illegal index %1$d in \"%2$s\"", index, s));
            }
 
            list.add(index);
        }
 
        indexes = new int[list.size()];
        int i = 0;
        for (Integer tmp : list.toArray(new Integer[list.size()]))
        {
            indexes[i++] = tmp;
        }
 
        return indexes;
    }
}