• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

javadev / underscore-java / #3107

pending completion
#3107

push

web-flow
Added com.github.underscore.XmlBuilder

4410 of 4410 relevant lines covered (100.0%)

1.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/main/java/com/github/underscore/U.java
1
/*
2
 * The MIT License (MIT)
3
 *
4
 * Copyright 2015-2023 Valentyn Kolesnikov
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
package com.github.underscore;
25

26
import java.io.File;
27
import java.io.FileInputStream;
28
import java.io.FileOutputStream;
29
import java.io.IOException;
30
import java.net.URI;
31
import java.net.URISyntaxException;
32
import java.net.URL;
33
import java.nio.channels.Channels;
34
import java.nio.channels.ReadableByteChannel;
35
import java.nio.charset.StandardCharsets;
36
import java.nio.file.Files;
37
import java.nio.file.Paths;
38
import java.util.ArrayList;
39
import java.util.Arrays;
40
import java.util.Collection;
41
import java.util.Collections;
42
import java.util.Comparator;
43
import java.util.HashMap;
44
import java.util.HashSet;
45
import java.util.Iterator;
46
import java.util.LinkedHashMap;
47
import java.util.List;
48
import java.util.Locale;
49
import java.util.Map;
50
import java.util.Set;
51
import java.util.function.BiConsumer;
52
import java.util.function.BiFunction;
53
import java.util.function.BinaryOperator;
54
import java.util.function.Consumer;
55
import java.util.function.Function;
56
import java.util.function.Predicate;
57
import java.util.zip.GZIPInputStream;
58
import javax.xml.xpath.XPath;
59
import javax.xml.xpath.XPathConstants;
60
import javax.xml.xpath.XPathFactory;
61
import org.w3c.dom.NodeList;
62

63
@SuppressWarnings({
64
    "java:S135",
65
    "java:S1168",
66
    "java:S3740",
67
    "java:S3776",
68
    "java:S4423",
69
    "java:S4830",
70
    "java:S5843",
71
    "java:S5996",
72
    "java:S5998"
73
})
74
public class U<T> extends Underscore<T> {
75
    private static final int DEFAULT_TRUNC_LENGTH = 30;
76
    private static final String DEFAULT_TRUNC_OMISSION = "...";
77
    private static final java.util.regex.Pattern RE_LATIN_1 =
1✔
78
            java.util.regex.Pattern.compile("[\\xc0-\\xd6\\xd8-\\xde\\xdf-\\xf6\\xf8-\\xff]");
1✔
79
    private static final java.util.regex.Pattern RE_PROP_NAME =
1✔
80
            java.util.regex.Pattern.compile(
1✔
81
                    "[^.\\[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\2)\\[^\\]|\\.)*?)\2)\\]|"
82
                            + "(?=(\\.|\\[\\])(?:\4|$))");
83
    private static final Map<String, String> DEBURRED_LETTERS = new LinkedHashMap<>();
1✔
84
    private static final Map<String, List<String>> DEFAULT_HEADER_FIELDS = new HashMap<>();
1✔
85
    private static final Set<String> SUPPORTED_HTTP_METHODS =
1✔
86
            new HashSet<>(Arrays.asList("GET", "POST", "PUT", "DELETE"));
1✔
87
    private static final int BUFFER_LENGTH_1024 = 1024;
88
    private static final int RESPONSE_CODE_400 = 400;
89
    private static final String ROOT = "root";
90
    private static String upper = "[A-Z\\xc0-\\xd6\\xd8-\\xde\\u0400-\\u04FF]";
1✔
91
    private static String lower = "[a-z\\xdf-\\xf6\\xf8-\\xff]+";
1✔
92
    private static String selfClosing = "-self-closing";
1✔
93
    private static String nilKey = "-nil";
1✔
94
    private static java.util.regex.Pattern reWords =
1✔
95
            java.util.regex.Pattern.compile(
1✔
96
                    upper
97
                            + "+(?="
98
                            + upper
99
                            + lower
100
                            + ")|"
101
                            + upper
102
                            + "?"
103
                            + lower
104
                            + "|"
105
                            + upper
106
                            + "+|[0-9]+");
107

108
    static {
109
        String[] deburredLetters =
1✔
110
                new String[] {
111
                    "\u00c0", "A", "\u00c1", "A", "\u00c2", "A", "\u00c3", "A", "\u00c4", "A",
112
                    "\u00c5", "A", "\u00e0", "a", "\u00e1", "a", "\u00e2", "a", "\u00e3", "a",
113
                    "\u00e4", "a", "\u00e5", "a", "\u00c7", "C", "\u00e7", "c", "\u00d0", "D",
114
                    "\u00f0", "d", "\u00c8", "E", "\u00c9", "E", "\u00ca", "E", "\u00cb", "E",
115
                    "\u00e8", "e", "\u00e9", "e", "\u00ea", "e", "\u00eb", "e", "\u00cC", "I",
116
                    "\u00cd", "I", "\u00ce", "I", "\u00cf", "I", "\u00eC", "i", "\u00ed", "i",
117
                    "\u00ee", "i", "\u00ef", "i", "\u00d1", "N", "\u00f1", "n", "\u00d2", "O",
118
                    "\u00d3", "O", "\u00d4", "O", "\u00d5", "O", "\u00d6", "O", "\u00d8", "O",
119
                    "\u00f2", "o", "\u00f3", "o", "\u00f4", "o", "\u00f5", "o", "\u00f6", "o",
120
                    "\u00f8", "o", "\u00d9", "U", "\u00da", "U", "\u00db", "U", "\u00dc", "U",
121
                    "\u00f9", "u", "\u00fa", "u", "\u00fb", "u", "\u00fc", "u", "\u00dd", "Y",
122
                    "\u00fd", "y", "\u00ff", "y", "\u00c6", "Ae", "\u00e6", "ae", "\u00de", "Th",
123
                    "\u00fe", "th", "\u00df", "ss"
124
                };
125
        for (int index = 0; index < deburredLetters.length; index += 2) {
1✔
126
            DEBURRED_LETTERS.put(deburredLetters[index], deburredLetters[index + 1]);
1✔
127
        }
128
        DEFAULT_HEADER_FIELDS.put(
1✔
129
                "Content-Type", Arrays.asList("application/json", "charset=utf-8"));
1✔
130
    }
1✔
131

132
    public enum XmlToJsonMode {
1✔
133
        REPLACE_SELF_CLOSING_WITH_NULL,
1✔
134
        REPLACE_SELF_CLOSING_WITH_STRING,
1✔
135
        REPLACE_EMPTY_VALUE_WITH_NULL,
1✔
136
        REPLACE_EMPTY_TAG_WITH_NULL,
1✔
137
        REPLACE_EMPTY_TAG_WITH_STRING,
1✔
138
        REMOVE_FIRST_LEVEL,
1✔
139
        WITHOUT_NAMESPACES
1✔
140
    }
141

142
    public enum JsonToXmlMode {
1✔
143
        FORCE_ATTRIBUTE_USAGE,
1✔
144
        DEFINE_ROOT_NAME,
1✔
145
        REPLACE_NULL_WITH_EMPTY_VALUE,
1✔
146
        REPLACE_EMPTY_STRING_WITH_EMPTY_VALUE,
1✔
147
        ADD_ROOT,
1✔
148
        REMOVE_ARRAY_ATTRIBUTE,
1✔
149
        REMOVE_ATTRIBUTES
1✔
150
    }
151

152
    public U(final Iterable<T> iterable) {
153
        super(iterable);
1✔
154
    }
1✔
155

156
    public U(final String string) {
157
        super(string);
1✔
158
    }
1✔
159

160
    public static class Chain<T> extends Underscore.Chain<T> {
161
        public Chain(final T item) {
162
            super(item);
1✔
163
        }
1✔
164

165
        public Chain(final List<T> list) {
166
            super(list);
1✔
167
        }
1✔
168

169
        public Chain(final Map<String, Object> map) {
170
            super(map);
1✔
171
        }
1✔
172

173
        @Override
174
        public Chain<T> first() {
175
            return new Chain<>(Underscore.first(value()));
1✔
176
        }
177

178
        @Override
179
        public Chain<T> first(int n) {
180
            return new Chain<>(Underscore.first(value(), n));
1✔
181
        }
182

183
        @Override
184
        public Chain<T> firstOrNull() {
185
            return new Chain<>(Underscore.firstOrNull(value()));
1✔
186
        }
187

188
        @Override
189
        public Chain<T> firstOrNull(final Predicate<T> pred) {
190
            return new Chain<>(Underscore.firstOrNull(value(), pred));
1✔
191
        }
192

193
        @Override
194
        public Chain<T> initial() {
195
            return new Chain<>(Underscore.initial(value()));
1✔
196
        }
197

198
        @Override
199
        public Chain<T> initial(int n) {
200
            return new Chain<>(Underscore.initial(value(), n));
1✔
201
        }
202

203
        @Override
204
        public Chain<T> last() {
205
            return new Chain<>(Underscore.last(value()));
1✔
206
        }
207

208
        @Override
209
        public Chain<T> last(int n) {
210
            return new Chain<>(Underscore.last(value(), n));
1✔
211
        }
212

213
        @Override
214
        public Chain<T> lastOrNull() {
215
            return new Chain<>(Underscore.lastOrNull(value()));
1✔
216
        }
217

218
        @Override
219
        public Chain<T> lastOrNull(final Predicate<T> pred) {
220
            return new Chain<>(Underscore.lastOrNull(value(), pred));
1✔
221
        }
222

223
        @Override
224
        public Chain<T> rest() {
225
            return new Chain<>(Underscore.rest(value()));
1✔
226
        }
227

228
        @Override
229
        public Chain<T> rest(int n) {
230
            return new Chain<>(Underscore.rest(value(), n));
1✔
231
        }
232

233
        @Override
234
        public Chain<T> compact() {
235
            return new Chain<>(Underscore.compact(value()));
1✔
236
        }
237

238
        @Override
239
        public Chain<T> compact(final T falsyValue) {
240
            return new Chain<>(Underscore.compact(value(), falsyValue));
1✔
241
        }
242

243
        @Override
244
        public Chain flatten() {
245
            return new Chain<>(Underscore.flatten(value()));
1✔
246
        }
247

248
        @Override
249
        public <F> Chain<F> map(final Function<? super T, F> func) {
250
            return new Chain<>(Underscore.map(value(), func));
1✔
251
        }
252

253
        @Override
254
        public <F> Chain<F> mapMulti(final BiConsumer<? super T, ? super Consumer<F>> mapper) {
255
            return new Chain<>(Underscore.mapMulti(value(), mapper));
1✔
256
        }
257

258
        @Override
259
        public <F> Chain<F> mapIndexed(final BiFunction<Integer, ? super T, F> func) {
260
            return new Chain<>(Underscore.mapIndexed(value(), func));
1✔
261
        }
262

263
        @Override
264
        public Chain<T> filter(final Predicate<T> pred) {
265
            return new Chain<>(Underscore.filter(value(), pred));
1✔
266
        }
267

268
        @Override
269
        public Chain<T> filterIndexed(final PredicateIndexed<T> pred) {
270
            return new Chain<>(Underscore.filterIndexed(value(), pred));
1✔
271
        }
272

273
        @Override
274
        public Chain<T> rejectIndexed(final PredicateIndexed<T> pred) {
275
            return new Chain<>(Underscore.rejectIndexed(value(), pred));
1✔
276
        }
277

278
        @Override
279
        public Chain<T> reject(final Predicate<T> pred) {
280
            return new Chain<>(Underscore.reject(value(), pred));
1✔
281
        }
282

283
        @Override
284
        public Chain<T> filterFalse(final Predicate<T> pred) {
285
            return new Chain<>(Underscore.filterFalse(value(), pred));
1✔
286
        }
287

288
        @Override
289
        public <F> Chain<F> reduce(final BiFunction<F, T, F> func, final F zeroElem) {
290
            return new Chain<>(Underscore.reduce(value(), func, zeroElem));
1✔
291
        }
292

293
        @Override
294
        public Chain<Optional<T>> reduce(final BinaryOperator<T> func) {
295
            return new Chain<>(Underscore.reduce(value(), func));
1✔
296
        }
297

298
        @Override
299
        public <F> Chain<F> reduceRight(final BiFunction<F, T, F> func, final F zeroElem) {
300
            return new Chain<>(Underscore.reduceRight(value(), func, zeroElem));
1✔
301
        }
302

303
        @Override
304
        public Chain<Optional<T>> reduceRight(final BinaryOperator<T> func) {
305
            return new Chain<>(Underscore.reduceRight(value(), func));
1✔
306
        }
307

308
        @Override
309
        public Chain<Optional<T>> find(final Predicate<T> pred) {
310
            return new Chain<>(Underscore.find(value(), pred));
1✔
311
        }
312

313
        @Override
314
        public Chain<Optional<T>> findLast(final Predicate<T> pred) {
315
            return new Chain<>(Underscore.findLast(value(), pred));
1✔
316
        }
317

318
        @Override
319
        @SuppressWarnings("unchecked")
320
        public Chain<Comparable> max() {
321
            return new Chain<>(Underscore.max((Collection) value()));
1✔
322
        }
323

324
        @Override
325
        public <F extends Comparable<? super F>> Chain<T> max(final Function<T, F> func) {
326
            return new Chain<>(Underscore.max(value(), func));
1✔
327
        }
328

329
        @Override
330
        @SuppressWarnings("unchecked")
331
        public Chain<Comparable> min() {
332
            return new Chain<>(Underscore.min((Collection) value()));
1✔
333
        }
334

335
        @Override
336
        public <F extends Comparable<? super F>> Chain<T> min(final Function<T, F> func) {
337
            return new Chain<>(Underscore.min(value(), func));
1✔
338
        }
339

340
        @Override
341
        @SuppressWarnings("unchecked")
342
        public Chain<Comparable> sort() {
343
            return new Chain<>(Underscore.sort((List<Comparable>) value()));
1✔
344
        }
345

346
        @Override
347
        @SuppressWarnings("unchecked")
348
        public <F extends Comparable<? super F>> Chain<F> sortWith(final Comparator<F> comparator) {
349
            return new Chain<>(Underscore.sortWith((List<F>) value(), comparator));
1✔
350
        }
351

352
        @Override
353
        public <F extends Comparable<? super F>> Chain<T> sortBy(final Function<T, F> func) {
354
            return new Chain<>(Underscore.sortBy(value(), func));
1✔
355
        }
356

357
        @Override
358
        @SuppressWarnings("unchecked")
359
        public <K> Chain<Map<K, Comparable>> sortBy(final K key) {
360
            return new Chain<>(Underscore.sortBy((List<Map<K, Comparable>>) value(), key));
1✔
361
        }
362

363
        @Override
364
        public <F> Chain<Map<F, List<T>>> groupBy(final Function<T, F> func) {
365
            return new Chain<>(Underscore.groupBy(value(), func));
1✔
366
        }
367

368
        @Override
369
        public <F> Chain<Map<F, Optional<T>>> groupBy(
370
                final Function<T, F> func, final BinaryOperator<T> binaryOperator) {
371
            return new Chain<>(Underscore.groupBy(value(), func, binaryOperator));
1✔
372
        }
373

374
        @Override
375
        public Chain<Map<Object, List<T>>> indexBy(final String property) {
376
            return new Chain<>(Underscore.indexBy(value(), property));
1✔
377
        }
378

379
        @Override
380
        public <F> Chain<Map<F, Integer>> countBy(final Function<T, F> func) {
381
            return new Chain<>(Underscore.countBy(value(), func));
1✔
382
        }
383

384
        @Override
385
        public Chain<Map<T, Integer>> countBy() {
386
            return new Chain<>(Underscore.countBy(value()));
1✔
387
        }
388

389
        @Override
390
        public Chain<T> shuffle() {
391
            return new Chain<>(Underscore.shuffle(value()));
1✔
392
        }
393

394
        @Override
395
        public Chain<T> sample() {
396
            return new Chain<>(Underscore.sample(value()));
1✔
397
        }
398

399
        @Override
400
        public Chain<T> sample(final int howMany) {
401
            return new Chain<>(newArrayList(Underscore.sample(value(), howMany)));
1✔
402
        }
403

404
        @Override
405
        public Chain<T> tap(final Consumer<T> func) {
406
            Underscore.tap(value(), func);
1✔
407
            return new Chain<>(value());
1✔
408
        }
409

410
        @Override
411
        public Chain<T> forEach(final Consumer<T> func) {
412
            Underscore.forEach(value(), func);
1✔
413
            return new Chain<>(value());
1✔
414
        }
415

416
        @Override
417
        public Chain<T> forEachRight(final Consumer<T> func) {
418
            Underscore.forEachRight(value(), func);
1✔
419
            return new Chain<>(value());
1✔
420
        }
421

422
        @Override
423
        public Chain<Boolean> every(final Predicate<T> pred) {
424
            return new Chain<>(Underscore.every(value(), pred));
1✔
425
        }
426

427
        @Override
428
        public Chain<Boolean> some(final Predicate<T> pred) {
429
            return new Chain<>(Underscore.some(value(), pred));
1✔
430
        }
431

432
        @Override
433
        public Chain<Integer> count(final Predicate<T> pred) {
434
            return new Chain<>(Underscore.count(value(), pred));
1✔
435
        }
436

437
        @Override
438
        public Chain<Boolean> contains(final T elem) {
439
            return new Chain<>(Underscore.contains(value(), elem));
1✔
440
        }
441

442
        @Override
443
        public Chain<Boolean> containsWith(final T elem) {
444
            return new Chain<>(Underscore.containsWith(value(), elem));
1✔
445
        }
446

447
        @Override
448
        public Chain<T> invoke(final String methodName, final List<Object> args) {
449
            return new Chain<>(Underscore.invoke(value(), methodName, args));
1✔
450
        }
451

452
        @Override
453
        public Chain<T> invoke(final String methodName) {
454
            return new Chain<>(Underscore.invoke(value(), methodName));
1✔
455
        }
456

457
        @Override
458
        public Chain<Object> pluck(final String propertyName) {
459
            return new Chain<>(Underscore.pluck(value(), propertyName));
1✔
460
        }
461

462
        @Override
463
        public <E> Chain<T> where(final List<Map.Entry<String, E>> properties) {
464
            return new Chain<>(Underscore.where(value(), properties));
1✔
465
        }
466

467
        @Override
468
        public <E> Chain<Optional<T>> findWhere(final List<Map.Entry<String, E>> properties) {
469
            return new Chain<>(Underscore.findWhere(value(), properties));
1✔
470
        }
471

472
        @Override
473
        public Chain<T> uniq() {
474
            return new Chain<>(Underscore.uniq(value()));
1✔
475
        }
476

477
        @Override
478
        public <F> Chain<T> uniq(final Function<T, F> func) {
479
            return new Chain<>(newArrayList(Underscore.uniq(value(), func)));
1✔
480
        }
481

482
        @Override
483
        public Chain<T> distinct() {
484
            return new Chain<>(Underscore.uniq(value()));
1✔
485
        }
486

487
        @Override
488
        @SuppressWarnings("unchecked")
489
        public <F> Chain<F> distinctBy(final Function<T, F> func) {
490
            return new Chain<>(newArrayList((Iterable<F>) Underscore.uniq(value(), func)));
1✔
491
        }
492

493
        @Override
494
        @SuppressWarnings("unchecked")
495
        public Chain<T> union(final List<T>... lists) {
496
            return new Chain<>(Underscore.union(value(), lists));
1✔
497
        }
498

499
        @Override
500
        @SuppressWarnings("unchecked")
501
        public Chain<T> intersection(final List<T>... lists) {
502
            return new Chain<>(Underscore.intersection(value(), lists));
1✔
503
        }
504

505
        @Override
506
        @SuppressWarnings("unchecked")
507
        public Chain<T> difference(final List<T>... lists) {
508
            return new Chain<>(Underscore.difference(value(), lists));
1✔
509
        }
510

511
        @Override
512
        public Chain<Integer> range(final int stop) {
513
            return new Chain<>(Underscore.range(stop));
1✔
514
        }
515

516
        @Override
517
        public Chain<Integer> range(final int start, final int stop) {
518
            return new Chain<>(Underscore.range(start, stop));
1✔
519
        }
520

521
        @Override
522
        public Chain<Integer> range(final int start, final int stop, final int step) {
523
            return new Chain<>(Underscore.range(start, stop, step));
1✔
524
        }
525

526
        @Override
527
        public Chain<List<T>> chunk(final int size) {
528
            return new Chain<>(Underscore.chunk(value(), size, size));
1✔
529
        }
530

531
        @Override
532
        public Chain<List<T>> chunk(final int size, final int step) {
533
            return new Chain<>(Underscore.chunk(value(), size, step));
1✔
534
        }
535

536
        @Override
537
        public Chain<List<T>> chunkFill(final int size, final T fillValue) {
538
            return new Chain<>(Underscore.chunkFill(value(), size, size, fillValue));
1✔
539
        }
540

541
        @Override
542
        public Chain<List<T>> chunkFill(final int size, final int step, final T fillValue) {
543
            return new Chain<>(Underscore.chunkFill(value(), size, step, fillValue));
1✔
544
        }
545

546
        @Override
547
        public Chain<T> cycle(final int times) {
548
            return new Chain<>(Underscore.cycle(value(), times));
1✔
549
        }
550

551
        @Override
552
        public Chain<T> interpose(final T element) {
553
            return new Chain<>(Underscore.interpose(value(), element));
1✔
554
        }
555

556
        @Override
557
        public Chain<T> interposeByList(final Iterable<T> interIter) {
558
            return new Chain<>(Underscore.interposeByList(value(), interIter));
1✔
559
        }
560

561
        @Override
562
        @SuppressWarnings("unchecked")
563
        public Chain<T> concat(final List<T>... lists) {
564
            return new Chain<>(Underscore.concat(value(), lists));
1✔
565
        }
566

567
        @Override
568
        public Chain<T> slice(final int start) {
569
            return new Chain<>(Underscore.slice(value(), start));
1✔
570
        }
571

572
        @Override
573
        public Chain<T> slice(final int start, final int end) {
574
            return new Chain<>(Underscore.slice(value(), start, end));
1✔
575
        }
576

577
        public Chain<Map<String, Object>> set(final String path, Object value) {
578
            U.set(map(), path, value);
1✔
579
            return new Chain<>(map());
1✔
580
        }
581

582
        public Chain<Map<String, Object>> set(final List<String> paths, Object value) {
583
            U.set(map(), paths, value);
1✔
584
            return new Chain<>(map());
1✔
585
        }
586

587
        @Override
588
        public Chain<T> reverse() {
589
            return new Chain<>(Underscore.reverse(value()));
1✔
590
        }
591

592
        @Override
593
        public Chain<String> join() {
594
            return new Chain<>(Underscore.join(value()));
1✔
595
        }
596

597
        @Override
598
        public Chain<String> join(final String separator) {
599
            return new Chain<>(Underscore.join(value(), separator));
1✔
600
        }
601

602
        @Override
603
        public Chain<T> skip(final int numberToSkip) {
604
            return new Chain<>(value().subList(numberToSkip, value().size()));
1✔
605
        }
606

607
        @Override
608
        public Chain<T> limit(final int size) {
609
            return new Chain<>(value().subList(0, size));
1✔
610
        }
611

612
        @Override
613
        @SuppressWarnings("unchecked")
614
        public <K, V> Chain<Map<K, V>> toMap() {
615
            return new Chain<>(Underscore.toMap((Iterable<Map.Entry<K, V>>) value()));
1✔
616
        }
617

618
        public Chain<T> drop() {
619
            return new Chain<>(Underscore.drop(value()));
1✔
620
        }
621

622
        public Chain<T> drop(final Integer n) {
623
            return new Chain<>(Underscore.drop(value(), n));
1✔
624
        }
625

626
        public Chain<T> dropRight() {
627
            return new Chain<>(U.dropRight(value()));
1✔
628
        }
629

630
        public Chain<T> dropRight(final Integer n) {
631
            return new Chain<>(U.dropRight(value(), n));
1✔
632
        }
633

634
        public Chain<T> dropWhile(final Predicate<T> pred) {
635
            return new Chain<>(U.dropWhile(value(), pred));
1✔
636
        }
637

638
        public Chain<T> dropRightWhile(final Predicate<T> pred) {
639
            return new Chain<>(U.dropRightWhile(value(), pred));
1✔
640
        }
641

642
        @SuppressWarnings("unchecked")
643
        public Chain<Object> fill(final Object value) {
644
            return new Chain<>(U.fill((List<Object>) value(), value));
1✔
645
        }
646

647
        @SuppressWarnings("unchecked")
648
        public Chain<Object> fill(final Object value, final Integer start, final Integer end) {
649
            return new Chain<>(U.fill((List<Object>) value(), value, start, end));
1✔
650
        }
651

652
        public Chain<Object> flattenDeep() {
653
            return new Chain<>(U.flattenDeep(value()));
1✔
654
        }
655

656
        @SuppressWarnings("unchecked")
657
        public Chain<Object> pull(final Object... values) {
658
            return new Chain<>(U.pull((List<Object>) value(), values));
1✔
659
        }
660

661
        @SuppressWarnings("unchecked")
662
        public Chain<Object> pullAt(final Integer... indexes) {
663
            return new Chain<>(U.pullAt((List<Object>) value(), indexes));
1✔
664
        }
665

666
        public Chain<T> remove(final Predicate<T> pred) {
667
            return new Chain<>(U.remove(value(), pred));
1✔
668
        }
669

670
        public Chain<T> take() {
671
            return new Chain<>(U.take(value()));
1✔
672
        }
673

674
        public Chain<T> takeRight() {
675
            return new Chain<>(U.takeRight(value()));
1✔
676
        }
677

678
        public Chain<T> take(final Integer n) {
679
            return new Chain<>(U.take(value(), n));
1✔
680
        }
681

682
        public Chain<T> takeRight(final Integer n) {
683
            return new Chain<>(U.takeRight(value(), n));
1✔
684
        }
685

686
        public Chain<T> takeWhile(final Predicate<T> pred) {
687
            return new Chain<>(U.takeWhile(value(), pred));
1✔
688
        }
689

690
        public Chain<T> takeRightWhile(final Predicate<T> pred) {
691
            return new Chain<>(U.takeRightWhile(value(), pred));
1✔
692
        }
693

694
        @SuppressWarnings("unchecked")
695
        public Chain<T> xor(final List<T> list) {
696
            return new Chain<>(U.xor(value(), list));
1✔
697
        }
698

699
        public Chain<T> at(final Integer... indexes) {
700
            return new Chain<>(U.at(value(), indexes));
1✔
701
        }
702

703
        @SuppressWarnings("unchecked")
704
        public <F extends Number> Chain<F> sum() {
705
            return new Chain<>(U.sum((List<F>) value()));
1✔
706
        }
707

708
        public <F extends Number> Chain<F> sum(final Function<T, F> func) {
709
            return new Chain<>(U.sum(value(), func));
1✔
710
        }
711

712
        @SuppressWarnings("unchecked")
713
        public Chain<Double> mean() {
714
            return new Chain<>(U.mean((List<Number>) value()));
1✔
715
        }
716

717
        @SuppressWarnings("unchecked")
718
        public Chain<Double> median() {
719
            return new Chain<>(U.median((List<Number>) value()));
1✔
720
        }
721

722
        public Chain<String> camelCase() {
723
            return new Chain<>(U.camelCase((String) item()));
1✔
724
        }
725

726
        public Chain<String> lowerFirst() {
727
            return new Chain<>(U.lowerFirst((String) item()));
1✔
728
        }
729

730
        public Chain<String> upperFirst() {
731
            return new Chain<>(U.upperFirst((String) item()));
1✔
732
        }
733

734
        public Chain<String> capitalize() {
735
            return new Chain<>(U.capitalize((String) item()));
1✔
736
        }
737

738
        public Chain<String> deburr() {
739
            return new Chain<>(U.deburr((String) item()));
1✔
740
        }
741

742
        public Chain<Boolean> endsWith(final String target) {
743
            return new Chain<>(U.endsWith((String) item(), target));
1✔
744
        }
745

746
        public Chain<Boolean> endsWith(final String target, final Integer position) {
747
            return new Chain<>(U.endsWith((String) item(), target, position));
1✔
748
        }
749

750
        public Chain<String> kebabCase() {
751
            return new Chain<>(U.kebabCase((String) item()));
1✔
752
        }
753

754
        public Chain<String> repeat(final int length) {
755
            return new Chain<>(U.repeat((String) item(), length));
1✔
756
        }
757

758
        public Chain<String> pad(final int length) {
759
            return new Chain<>(U.pad((String) item(), length));
1✔
760
        }
761

762
        public Chain<String> pad(final int length, final String chars) {
763
            return new Chain<>(U.pad((String) item(), length, chars));
1✔
764
        }
765

766
        public Chain<String> padStart(final int length) {
767
            return new Chain<>(U.padStart((String) item(), length));
1✔
768
        }
769

770
        public Chain<String> padStart(final int length, final String chars) {
771
            return new Chain<>(U.padStart((String) item(), length, chars));
1✔
772
        }
773

774
        public Chain<String> padEnd(final int length) {
775
            return new Chain<>(U.padEnd((String) item(), length));
1✔
776
        }
777

778
        public Chain<String> padEnd(final int length, final String chars) {
779
            return new Chain<>(U.padEnd((String) item(), length, chars));
1✔
780
        }
781

782
        public Chain<String> snakeCase() {
783
            return new Chain<>(U.snakeCase((String) item()));
1✔
784
        }
785

786
        public Chain<String> startCase() {
787
            return new Chain<>(U.startCase((String) item()));
1✔
788
        }
789

790
        public Chain<Boolean> startsWith(final String target) {
791
            return new Chain<>(U.startsWith((String) item(), target));
1✔
792
        }
793

794
        public Chain<Boolean> startsWith(final String target, final Integer position) {
795
            return new Chain<>(U.startsWith((String) item(), target, position));
1✔
796
        }
797

798
        public Chain<String> trim() {
799
            return new Chain<>(U.trim((String) item()));
1✔
800
        }
801

802
        public Chain<String> trim(final String chars) {
803
            return new Chain<>(U.trim((String) item(), chars));
1✔
804
        }
805

806
        public Chain<String> trimStart() {
807
            return new Chain<>(U.trimStart((String) item()));
1✔
808
        }
809

810
        public Chain<String> trimStart(final String chars) {
811
            return new Chain<>(U.trimStart((String) item(), chars));
1✔
812
        }
813

814
        public Chain<String> trimEnd() {
815
            return new Chain<>(U.trimEnd((String) item()));
1✔
816
        }
817

818
        public Chain<String> trunc() {
819
            return new Chain<>(U.trunc((String) item()));
1✔
820
        }
821

822
        public Chain<String> trunc(final int length) {
823
            return new Chain<>(U.trunc((String) item(), length));
1✔
824
        }
825

826
        public Chain<String> trimEnd(final String chars) {
827
            return new Chain<>(U.trimEnd((String) item(), chars));
1✔
828
        }
829

830
        public Chain<String> uncapitalize() {
831
            return new Chain<>(U.uncapitalize((String) item()));
1✔
832
        }
833

834
        public Chain<String> words() {
835
            return new Chain<>(U.words((String) item()));
1✔
836
        }
837

838
        public Chain<String> toJson() {
839
            return new Chain<>(Json.toJson(value()));
1✔
840
        }
841

842
        public Chain<Object> fromJson() {
843
            return new Chain<>(Json.fromJson((String) item()));
1✔
844
        }
845

846
        public Chain<String> toXml() {
847
            return new Chain<>(Xml.toXml(value()));
1✔
848
        }
849

850
        public Chain<Object> fromXml() {
851
            return new Chain<>(Xml.fromXml((String) item()));
1✔
852
        }
853

854
        public Chain<String> fetch() {
855
            return new Chain<>(U.fetch((String) item()).text());
1✔
856
        }
857

858
        public Chain<String> fetch(final String method, final String body) {
859
            return new Chain<>(U.fetch((String) item(), method, body).text());
1✔
860
        }
861

862
        public Chain<List<T>> createPermutationWithRepetition(final int permutationLength) {
863
            return new Chain<>(U.createPermutationWithRepetition(value(), permutationLength));
1✔
864
        }
865

866
        public Chain<String> toJsonJavaString() {
867
            return new Chain<>(Json.toJsonJavaString(value()));
1✔
868
        }
869

870
        public Chain<String> xmlToJson() {
871
            return new Chain<>(U.xmlToJson((String) item()));
1✔
872
        }
873

874
        public Chain<String> jsonToXml() {
875
            return new Chain<>(U.jsonToXml((String) item()));
1✔
876
        }
877
    }
878

879
    public static Chain<String> chain(final String item) {
880
        return new U.Chain<>(item);
1✔
881
    }
882

883
    public static <T> Chain<T> chain(final List<T> list) {
884
        return new U.Chain<>(list);
1✔
885
    }
886

887
    public static Chain<Map<String, Object>> chain(final Map<String, Object> map) {
888
        return new U.Chain<>(map);
1✔
889
    }
890

891
    public static <T> Chain<T> chain(final Iterable<T> iterable) {
892
        return new U.Chain<>(newArrayList(iterable));
1✔
893
    }
894

895
    public static <T> Chain<T> chain(final Iterable<T> iterable, int size) {
896
        return new U.Chain<>(newArrayList(iterable, size));
1✔
897
    }
898

899
    @SuppressWarnings("unchecked")
900
    public static <T> Chain<T> chain(final T... list) {
901
        return new U.Chain<>(Arrays.asList(list));
1✔
902
    }
903

904
    public static Chain<Integer> chain(final int[] array) {
905
        return new U.Chain<>(newIntegerList(array));
1✔
906
    }
907

908
    @Override
909
    public Chain<T> chain() {
910
        return new U.Chain<>(newArrayList(value()));
1✔
911
    }
912

913
    public static Chain<String> of(final String item) {
914
        return new U.Chain<>(item);
1✔
915
    }
916

917
    public static <T> Chain<T> of(final List<T> list) {
918
        return new U.Chain<>(list);
1✔
919
    }
920

921
    public static Chain<Map<String, Object>> of(final Map<String, Object> map) {
922
        return new U.Chain<>(map);
1✔
923
    }
924

925
    public static <T> Chain<T> of(final Iterable<T> iterable) {
926
        return new U.Chain<>(newArrayList(iterable));
1✔
927
    }
928

929
    public static <T> Chain<T> of(final Iterable<T> iterable, int size) {
930
        return new U.Chain<>(newArrayList(iterable, size));
1✔
931
    }
932

933
    @SuppressWarnings("unchecked")
934
    public static <T> Chain<T> of(final T... list) {
935
        return new U.Chain<>(Arrays.asList(list));
1✔
936
    }
937

938
    public static Chain<Integer> of(final int[] array) {
939
        return new U.Chain<>(newIntegerList(array));
1✔
940
    }
941

942
    @Override
943
    public Chain<T> of() {
944
        return new U.Chain<>(newArrayList(value()));
1✔
945
    }
946

947
    public static <T> List<T> drop(final Iterable<T> iterable) {
948
        return rest(newArrayList(iterable));
1✔
949
    }
950

951
    public List<T> drop() {
952
        return drop(getIterable());
1✔
953
    }
954

955
    public static <T> List<T> drop(final Iterable<T> iterable, final Integer n) {
956
        return rest(newArrayList(iterable), n);
1✔
957
    }
958

959
    public List<T> drop(final Integer n) {
960
        return drop(getIterable(), n);
1✔
961
    }
962

963
    public static <T> List<T> dropRight(final Iterable<T> iterable) {
964
        return initial(newArrayList(iterable));
1✔
965
    }
966

967
    public List<T> dropRight() {
968
        return dropRight(getIterable());
1✔
969
    }
970

971
    public static <T> List<T> dropRight(final Iterable<T> iterable, final Integer n) {
972
        return initial(newArrayList(iterable), n);
1✔
973
    }
974

975
    public List<T> dropRight(final Integer n) {
976
        return dropRight(getIterable(), n);
1✔
977
    }
978

979
    public static <T> List<T> dropWhile(final Iterable<T> iterable, final Predicate<T> pred) {
980
        return rest(newArrayList(iterable), findIndex(newArrayList(iterable), negate(pred)));
1✔
981
    }
982

983
    public List<T> dropWhile(final Predicate<T> pred) {
984
        return dropWhile(getIterable(), pred);
1✔
985
    }
986

987
    public static <T> List<T> dropRightWhile(final Iterable<T> iterable, final Predicate<T> pred) {
988
        return reverse(dropWhile(reverse(iterable), pred));
1✔
989
    }
990

991
    public List<T> dropRightWhile(final Predicate<T> pred) {
992
        return dropRightWhile(getIterable(), pred);
1✔
993
    }
994

995
    public static <T> List<T> fill(List<T> list, T item) {
996
        for (int i = 0; i < size(list); i++) {
1✔
997
            list.set(i, item);
1✔
998
        }
999
        return list;
1✔
1000
    }
1001

1002
    public static <T> T[] fill(T[] array, T item) {
1003
        Arrays.fill(array, item);
1✔
1004
        return array;
1✔
1005
    }
1006

1007
    @SuppressWarnings("unchecked")
1008
    public List<Object> fill(Object value) {
1009
        return fill((List<Object>) getIterable(), value);
1✔
1010
    }
1011

1012
    public static List<Object> fill(
1013
            final List<Object> list, Object value, Integer start, Integer end) {
1014
        for (int index = start; index < end; index += 1) {
1✔
1015
            list.set(index, value);
1✔
1016
        }
1017
        return list;
1✔
1018
    }
1019

1020
    @SuppressWarnings("unchecked")
1021
    public List<Object> fill(Object value, Integer start, Integer end) {
1022
        return fill((List<Object>) getIterable(), value, start, end);
1✔
1023
    }
1024

1025
    public static <E> List<E> flattenDeep(final List<?> list) {
1026
        return flatten(list, false);
1✔
1027
    }
1028

1029
    public List<T> flattenDeep() {
1030
        return flattenDeep((List<?>) getIterable());
1✔
1031
    }
1032

1033
    public static List<Object> pull(final List<Object> list, Object... values) {
1034
        final List<Object> valuesList = Arrays.asList(values);
1✔
1035
        list.removeIf(valuesList::contains);
1✔
1036
        return list;
1✔
1037
    }
1038

1039
    @SuppressWarnings("unchecked")
1040
    public List<Object> pull(Object... values) {
1041
        return pull((List<Object>) getIterable(), values);
1✔
1042
    }
1043

1044
    public static List<Object> pullAt(final List<Object> list, final Integer... indexes) {
1045
        final List<Object> result = newArrayList();
1✔
1046
        final List<Integer> indexesList = Arrays.asList(indexes);
1✔
1047
        int index = 0;
1✔
1048
        for (final Iterator<Object> iterator = list.iterator(); iterator.hasNext(); ) {
1✔
1049
            final Object object = iterator.next();
1✔
1050
            if (indexesList.contains(index)) {
1✔
1051
                result.add(object);
1✔
1052
                iterator.remove();
1✔
1053
            }
1054
            index += 1;
1✔
1055
        }
1✔
1056
        return result;
1✔
1057
    }
1058

1059
    @SuppressWarnings("unchecked")
1060
    public List<Object> pullAt(final Integer... indexes) {
1061
        return pullAt((List<Object>) getIterable(), indexes);
1✔
1062
    }
1063

1064
    public static <T> List<T> remove(final List<T> list, final Predicate<T> pred) {
1065
        final List<T> result = newArrayList();
1✔
1066
        for (final Iterator<T> iterator = list.iterator(); iterator.hasNext(); ) {
1✔
1067
            final T object = iterator.next();
1✔
1068
            if (pred.test(object)) {
1✔
1069
                result.add(object);
1✔
1070
                iterator.remove();
1✔
1071
            }
1072
        }
1✔
1073
        return result;
1✔
1074
    }
1075

1076
    public List<T> remove(final Predicate<T> pred) {
1077
        return remove((List<T>) getIterable(), pred);
1✔
1078
    }
1079

1080
    public static <T> List<T> take(final Iterable<T> iterable) {
1081
        return first(newArrayList(iterable), 1);
1✔
1082
    }
1083

1084
    public List<T> take() {
1085
        return take(getIterable());
1✔
1086
    }
1087

1088
    public static <T> List<T> takeRight(final Iterable<T> iterable) {
1089
        return last(newArrayList(iterable), 1);
1✔
1090
    }
1091

1092
    public List<T> takeRight() {
1093
        return takeRight(getIterable());
1✔
1094
    }
1095

1096
    public static <T> List<T> take(final Iterable<T> iterable, final Integer n) {
1097
        return first(newArrayList(iterable), n);
1✔
1098
    }
1099

1100
    public List<T> take(final Integer n) {
1101
        return take(getIterable(), n);
1✔
1102
    }
1103

1104
    public static <T> List<T> takeRight(final Iterable<T> iterable, final Integer n) {
1105
        return last(newArrayList(iterable), n);
1✔
1106
    }
1107

1108
    public List<T> takeRight(final Integer n) {
1109
        return takeRight(getIterable(), n);
1✔
1110
    }
1111

1112
    public static <T> List<T> takeWhile(final Iterable<T> iterable, final Predicate<T> pred) {
1113
        return first(newArrayList(iterable), findIndex(newArrayList(iterable), negate(pred)));
1✔
1114
    }
1115

1116
    public List<T> takeWhile(final Predicate<T> pred) {
1117
        return takeWhile(getIterable(), pred);
1✔
1118
    }
1119

1120
    public static <T> List<T> takeRightWhile(final Iterable<T> iterable, final Predicate<T> pred) {
1121
        return reverse(takeWhile(reverse(iterable), pred));
1✔
1122
    }
1123

1124
    public List<T> takeRightWhile(final Predicate<T> pred) {
1125
        return takeRightWhile(getIterable(), pred);
1✔
1126
    }
1127

1128
    @SuppressWarnings("unchecked")
1129
    public static <T> List<T> xor(final List<T>... lists) {
1130
        int index = -1;
1✔
1131
        int length = lists.length;
1✔
1132
        List<T> result = null;
1✔
1133
        while (++index < length) {
1✔
1134
            final List<T> array = lists[index];
1✔
1135
            result =
1136
                    result == null
1✔
1137
                            ? array
1✔
1138
                            : concat(difference(result, array), difference(array, result));
1✔
1139
        }
1✔
1140
        return uniq(result);
1✔
1141
    }
1142

1143
    @SuppressWarnings("unchecked")
1144
    public List<T> xor(final List<T> list) {
1145
        return xor((List<T>) getIterable(), list);
1✔
1146
    }
1147

1148
    public static <T> List<T> at(final List<T> list, final Integer... indexes) {
1149
        final List<T> result = newArrayList();
1✔
1150
        final List<Integer> indexesList = Arrays.asList(indexes);
1✔
1151
        int index = 0;
1✔
1152
        for (final T object : list) {
1✔
1153
            if (indexesList.contains(index)) {
1✔
1154
                result.add(object);
1✔
1155
            }
1156
            index += 1;
1✔
1157
        }
1✔
1158
        return result;
1✔
1159
    }
1160

1161
    public List<T> at(final Integer... indexes) {
1162
        return at((List<T>) getIterable(), indexes);
1✔
1163
    }
1164

1165
    public static <T extends Number> Double average(final Iterable<T> iterable) {
1166
        T sum = sum(iterable);
1✔
1167
        if (sum == null) {
1✔
1168
            return null;
1✔
1169
        }
1170
        return sum.doubleValue() / size(iterable);
1✔
1171
    }
1172

1173
    public static <E, F extends Number> Double average(
1174
            final Iterable<E> iterable, final Function<E, F> func) {
1175
        F sum = sum(iterable, func);
1✔
1176
        if (sum == null) {
1✔
1177
            return null;
1✔
1178
        }
1179
        return sum.doubleValue() / size(iterable);
1✔
1180
    }
1181

1182
    public static <N extends Number> Double average(N[] array) {
1183
        N sum = sum(array);
1✔
1184
        if (sum == null) {
1✔
1185
            return null;
1✔
1186
        }
1187
        return sum.doubleValue() / array.length;
1✔
1188
    }
1189

1190
    public static Double average(java.math.BigDecimal first, java.math.BigDecimal second) {
1191
        if (first == null || second == null) {
1✔
1192
            return null;
1✔
1193
        }
1194
        return sum(first, second).doubleValue() / 2;
1✔
1195
    }
1196

1197
    public static Double average(java.math.BigInteger first, java.math.BigInteger second) {
1198
        if (first == null || second == null) {
1✔
1199
            return null;
1✔
1200
        }
1201
        return sum(first, second).doubleValue() / 2;
1✔
1202
    }
1203

1204
    public static Double average(Byte first, Byte second) {
1205
        if (first == null || second == null) {
1✔
1206
            return null;
1✔
1207
        }
1208
        return sum(first, second).doubleValue() / 2;
1✔
1209
    }
1210

1211
    public static Double average(Double first, Double second) {
1212
        if (first == null || second == null) {
1✔
1213
            return null;
1✔
1214
        }
1215
        return sum(first, second) / 2;
1✔
1216
    }
1217

1218
    public static Double average(Float first, Float second) {
1219
        if (first == null || second == null) {
1✔
1220
            return null;
1✔
1221
        }
1222
        return sum(first, second).doubleValue() / 2;
1✔
1223
    }
1224

1225
    public static Double average(Integer first, Integer second) {
1226
        if (first == null || second == null) {
1✔
1227
            return null;
1✔
1228
        }
1229
        return sum(first, second).doubleValue() / 2;
1✔
1230
    }
1231

1232
    public static Double average(Long first, Long second) {
1233
        if (first == null || second == null) {
1✔
1234
            return null;
1✔
1235
        }
1236
        return sum(first, second).doubleValue() / 2;
1✔
1237
    }
1238

1239
    public static <T extends Number> T sum(final Iterable<T> iterable) {
1240
        T result = null;
1✔
1241
        for (final T item : iterable) {
1✔
1242
            result = add(result, item);
1✔
1243
        }
1✔
1244
        return result;
1✔
1245
    }
1246

1247
    public static <E, F extends Number> F sum(
1248
            final Iterable<E> iterable, final Function<E, F> func) {
1249
        F result = null;
1✔
1250
        for (final E item : iterable) {
1✔
1251
            result = add(result, func.apply(item));
1✔
1252
        }
1✔
1253
        return result;
1✔
1254
    }
1255

1256
    public static <N extends Number> N sum(N[] array) {
1257
        N result = null;
1✔
1258
        for (final N item : array) {
1✔
1259
            result = add(result, item);
1✔
1260
        }
1261
        return result;
1✔
1262
    }
1263

1264
    @SuppressWarnings("unchecked")
1265
    public <F extends Number> F sum() {
1266
        return sum((List<F>) getIterable());
1✔
1267
    }
1268

1269
    @SuppressWarnings("unchecked")
1270
    public <E, F extends Number> F sum(final Function<E, F> func) {
1271
        return sum((List<E>) getIterable(), func);
1✔
1272
    }
1273

1274
    @SuppressWarnings("unchecked")
1275
    public static <T extends Number> T add(final T first, final T second) {
1276
        if (first == null) {
1✔
1277
            return second;
1✔
1278
        } else if (second == null) {
1✔
1279
            return first;
1✔
1280
        } else if (first instanceof java.math.BigDecimal) {
1✔
1281
            return (T) sum((java.math.BigDecimal) first, (java.math.BigDecimal) second);
1✔
1282
        } else if (second instanceof java.math.BigInteger) {
1✔
1283
            return (T) sum((java.math.BigInteger) first, (java.math.BigInteger) second);
1✔
1284
        } else if (first instanceof Byte) {
1✔
1285
            return (T) sum((Byte) first, (Byte) second);
1✔
1286
        } else if (first instanceof Double) {
1✔
1287
            return (T) sum((Double) first, (Double) second);
1✔
1288
        } else if (first instanceof Float) {
1✔
1289
            return (T) sum((Float) first, (Float) second);
1✔
1290
        } else if (first instanceof Integer) {
1✔
1291
            return (T) sum((Integer) first, (Integer) second);
1✔
1292
        } else if (first instanceof Long) {
1✔
1293
            return (T) sum((Long) first, (Long) second);
1✔
1294
        } else if (first instanceof Short) {
1✔
1295
            return (T) sum((Short) first, (Short) second);
1✔
1296
        } else {
1297
            throw new UnsupportedOperationException(
1✔
1298
                    "Sum only supports official subclasses of Number");
1299
        }
1300
    }
1301

1302
    private static java.math.BigDecimal sum(
1303
            java.math.BigDecimal first, java.math.BigDecimal second) {
1304
        return first.add(second);
1✔
1305
    }
1306

1307
    private static java.math.BigInteger sum(
1308
            java.math.BigInteger first, java.math.BigInteger second) {
1309
        return first.add(second);
1✔
1310
    }
1311

1312
    private static Byte sum(Byte first, Byte second) {
1313
        return (byte) (first + second);
1✔
1314
    }
1315

1316
    private static Double sum(Double first, Double second) {
1317
        return first + second;
1✔
1318
    }
1319

1320
    private static Float sum(Float first, Float second) {
1321
        return first + second;
1✔
1322
    }
1323

1324
    private static Integer sum(Integer first, Integer second) {
1325
        return first + second;
1✔
1326
    }
1327

1328
    private static Long sum(Long first, Long second) {
1329
        return first + second;
1✔
1330
    }
1331

1332
    private static Short sum(Short first, Short second) {
1333
        return (short) (first + second);
1✔
1334
    }
1335

1336
    @SuppressWarnings("unchecked")
1337
    public static <T extends Number> T subtract(final T... values) {
1338
        if (values.length == 0) {
1✔
1339
            return null;
1✔
1340
        }
1341
        T result = values[0];
1✔
1342
        for (int i = 1; i < values.length; i++) {
1✔
1343
            if (result instanceof java.math.BigDecimal) {
1✔
1344
                java.math.BigDecimal value = (java.math.BigDecimal) values[i];
1✔
1345
                result = add(result, (T) value.negate());
1✔
1346
            } else if (result instanceof java.math.BigInteger) {
1✔
1347
                java.math.BigInteger value = (java.math.BigInteger) values[i];
1✔
1348
                result = add(result, (T) value.negate());
1✔
1349
            } else if (result instanceof Byte) {
1✔
1350
                result = add(result, (T) Byte.valueOf((byte) (values[i].byteValue() * -1)));
1✔
1351
            } else if (result instanceof Double) {
1✔
1352
                result = add(result, (T) Double.valueOf(values[i].doubleValue() * -1));
1✔
1353
            } else if (result instanceof Float) {
1✔
1354
                result = add(result, (T) Float.valueOf(values[i].floatValue() * -1));
1✔
1355
            } else if (result instanceof Integer) {
1✔
1356
                result = add(result, (T) Integer.valueOf(values[i].intValue() * -1));
1✔
1357
            } else if (result instanceof Long) {
1✔
1358
                result = add(result, (T) Long.valueOf(values[i].longValue() * -1));
1✔
1359
            } else if (result instanceof Short) {
1✔
1360
                result = add(result, (T) Short.valueOf((short) (values[i].shortValue() * -1)));
1✔
1361
            } else {
1362
                throw new UnsupportedOperationException(
1✔
1363
                        "Subtract only supports official subclasses of Number");
1364
            }
1365
        }
1366
        return result;
1✔
1367
    }
1368

1369
    public static <T extends Number> double mean(final Iterable<T> iterable) {
1370
        T result = null;
1✔
1371
        int count = 0;
1✔
1372
        for (final T item : iterable) {
1✔
1373
            result = add(result, item);
1✔
1374
            count += 1;
1✔
1375
        }
1✔
1376
        if (result == null) {
1✔
1377
            return 0d;
1✔
1378
        }
1379
        return result.doubleValue() / count;
1✔
1380
    }
1381

1382
    @SuppressWarnings("unchecked")
1383
    public double mean() {
1384
        return mean((Iterable<Number>) getIterable());
1✔
1385
    }
1386

1387
    @SuppressWarnings("unchecked")
1388
    public static <T extends Number> double median(final Iterable<T> iterable) {
1389
        final List<T> result = newArrayList((Collection) iterable);
1✔
1390
        final int size = size(iterable);
1✔
1391
        if (size == 0) {
1✔
1392
            throw new IllegalArgumentException("Iterable cannot be empty");
1✔
1393
        }
1394
        if (size % 2 != 0) {
1✔
1395
            return result.get(size / 2).doubleValue();
1✔
1396
        }
1397
        return (result.get(size / 2 - 1).doubleValue() + result.get(size / 2).doubleValue()) / 2;
1✔
1398
    }
1399

1400
    @SuppressWarnings("unchecked")
1401
    public double median() {
1402
        return median((Iterable<Number>) getIterable());
1✔
1403
    }
1404

1405
    public static String camelCase(final String string) {
1406
        return createCompounder(
1✔
1407
                        (result, word, index) -> {
1408
                            final String localWord = word.toLowerCase(Locale.getDefault());
1✔
1409
                            return result
1✔
1410
                                    + (index > 0
1✔
1411
                                            ? localWord
1412
                                                            .substring(0, 1)
1✔
1413
                                                            .toUpperCase(Locale.getDefault())
1✔
1414
                                                    + localWord.substring(1)
1✔
1415
                                            : localWord);
1✔
1416
                        })
1417
                .apply(string);
1✔
1418
    }
1419

1420
    public static String lowerFirst(final String string) {
1421
        return createCaseFirst("toLowerCase").apply(string);
1✔
1422
    }
1423

1424
    public static String upperFirst(final String string) {
1425
        return createCaseFirst("toUpperCase").apply(string);
1✔
1426
    }
1427

1428
    public static String capitalize(final String string) {
1429
        return upperFirst(baseToString(string));
1✔
1430
    }
1431

1432
    public static String uncapitalize(final String string) {
1433
        return lowerFirst(baseToString(string));
1✔
1434
    }
1435

1436
    private static String baseToString(String value) {
1437
        return value == null ? "" : value;
1✔
1438
    }
1439

1440
    public static String deburr(final String string) {
1441
        final String localString = baseToString(string);
1✔
1442
        final StringBuilder sb = new StringBuilder();
1✔
1443
        for (final String str : localString.split("")) {
1✔
1444
            if (RE_LATIN_1.matcher(str).matches()) {
1✔
1445
                sb.append(DEBURRED_LETTERS.get(str));
1✔
1446
            } else {
1447
                sb.append(str);
1✔
1448
            }
1449
        }
1450
        return sb.toString();
1✔
1451
    }
1452

1453
    public static List<String> words(final String string) {
1454
        final String localString = baseToString(string);
1✔
1455
        final List<String> result = new ArrayList<>();
1✔
1456
        final java.util.regex.Matcher matcher = reWords.matcher(localString);
1✔
1457
        while (matcher.find()) {
1✔
1458
            result.add(matcher.group());
1✔
1459
        }
1460
        return result;
1✔
1461
    }
1462

1463
    private static Function<String, String> createCompounder(
1464
            final Function3<String, String, Integer, String> callback) {
1465
        return string -> {
1✔
1466
            int index = -1;
1✔
1467
            List<String> array = words(deburr(string));
1✔
1468
            int length = array.size();
1✔
1469
            String result = "";
1✔
1470

1471
            while (++index < length) {
1✔
1472
                result = callback.apply(result, array.get(index), index);
1✔
1473
            }
1474
            return result;
1✔
1475
        };
1476
    }
1477

1478
    private static Function<String, String> createCaseFirst(final String methodName) {
1479
        return string -> {
1✔
1480
            final String localString = baseToString(string);
1✔
1481
            final String chr = localString.isEmpty() ? "" : localString.substring(0, 1);
1✔
1482
            final String trailing = localString.length() > 1 ? localString.substring(1) : "";
1✔
1483
            return Underscore.invoke(Collections.singletonList(chr), methodName).get(0) + trailing;
1✔
1484
        };
1485
    }
1486

1487
    public static boolean endsWith(final String string, final String target) {
1488
        return endsWith(string, target, null);
1✔
1489
    }
1490

1491
    public static boolean endsWith(
1492
            final String string, final String target, final Integer position) {
1493
        if (string == null || target == null) {
1✔
1494
            return false;
1✔
1495
        }
1496
        final String localString = baseToString(string);
1✔
1497

1498
        final int length = localString.length();
1✔
1499
        final int fixedPosition = position == null || position < 0 ? 0 : position;
1✔
1500
        final int localPosition = position == null ? length : Math.min(fixedPosition, length);
1✔
1501

1502
        final int localPosition2 = localPosition - target.length();
1✔
1503
        return localPosition2 >= 0 && localString.indexOf(target, localPosition2) == localPosition2;
1✔
1504
    }
1505

1506
    public static String kebabCase(final String string) {
1507
        return createCompounder(
1✔
1508
                        (result, word, index) ->
1509
                                result
1✔
1510
                                        + (index > 0 ? "-" : "")
1✔
1511
                                        + word.toLowerCase(Locale.getDefault()))
1✔
1512
                .apply(string);
1✔
1513
    }
1514

1515
    public static String repeat(final String string, final int length) {
1516
        final StringBuilder result = new StringBuilder();
1✔
1517
        final StringBuilder localString = new StringBuilder(baseToString(string));
1✔
1518
        if (length < 1 || string == null) {
1✔
1519
            return result.toString();
1✔
1520
        }
1521
        int n = length;
1✔
1522
        do {
1523
            if (n % 2 != 0) {
1✔
1524
                result.append(localString);
1✔
1525
            }
1526
            n = (int) Math.floor(n / (double) 2);
1✔
1527
            localString.append(localString);
1✔
1528
        } while (n > 0);
1✔
1529
        return result.toString();
1✔
1530
    }
1531

1532
    private static String createPadding(final String string, final int length, final String chars) {
1533
        final int strLength = string.length();
1✔
1534
        final int padLength = length - strLength;
1✔
1535
        final String localChars = chars == null ? " " : chars;
1✔
1536
        return repeat(localChars, (int) Math.ceil(padLength / (double) localChars.length()))
1✔
1537
                .substring(0, padLength);
1✔
1538
    }
1539

1540
    public static String pad(final String string, final int length) {
1541
        return pad(string, length, null);
1✔
1542
    }
1543

1544
    public static String pad(final String string, final int length, final String chars) {
1545
        final String localString = baseToString(string);
1✔
1546
        final int strLength = localString.length();
1✔
1547
        if (strLength >= length) {
1✔
1548
            return localString;
1✔
1549
        }
1550
        final double mid = (length - strLength) / (double) 2;
1✔
1551
        final int leftLength = (int) Math.floor(mid);
1✔
1552
        final int rightLength = (int) Math.ceil(mid);
1✔
1553
        final String localChars = createPadding("", rightLength, chars);
1✔
1554
        return localChars.substring(0, leftLength) + localString + localChars;
1✔
1555
    }
1556

1557
    private static Function3<String, Integer, String, String> createPadDir(
1558
            final boolean fromRight) {
1559
        return (string, length, chars) -> {
1✔
1560
            final String localString = baseToString(string);
1✔
1561
            return (fromRight ? localString : "")
1✔
1562
                    + createPadding(localString, length, chars)
1✔
1563
                    + (fromRight ? "" : localString);
1✔
1564
        };
1565
    }
1566

1567
    public static String padStart(final String string, final Integer length) {
1568
        return createPadDir(false).apply(string, length, null);
1✔
1569
    }
1570

1571
    public static String padStart(final String string, final Integer length, final String chars) {
1572
        return createPadDir(false).apply(string, length, chars);
1✔
1573
    }
1574

1575
    public static String padEnd(final String string, final Integer length) {
1576
        return createPadDir(true).apply(string, length, null);
1✔
1577
    }
1578

1579
    public static String padEnd(final String string, final Integer length, final String chars) {
1580
        return createPadDir(true).apply(string, length, chars);
1✔
1581
    }
1582

1583
    public static String snakeCase(final String string) {
1584
        return createCompounder(
1✔
1585
                        (result, word, index) ->
1586
                                result
1✔
1587
                                        + (index > 0 ? "_" : "")
1✔
1588
                                        + word.toLowerCase(Locale.getDefault()))
1✔
1589
                .apply(string);
1✔
1590
    }
1591

1592
    public static String startCase(final String string) {
1593
        return createCompounder(
1✔
1594
                        (result, word, index) ->
1595
                                result
1✔
1596
                                        + (index > 0 ? " " : "")
1✔
1597
                                        + word.substring(0, 1).toUpperCase(Locale.getDefault())
1✔
1598
                                        + word.substring(1))
1✔
1599
                .apply(string);
1✔
1600
    }
1601

1602
    public static boolean startsWith(final String string, final String target) {
1603
        return startsWith(string, target, null);
1✔
1604
    }
1605

1606
    public static boolean startsWith(
1607
            final String string, final String target, final Integer position) {
1608
        if (string == null || target == null) {
1✔
1609
            return false;
1✔
1610
        }
1611
        final String localString = baseToString(string);
1✔
1612

1613
        final int length = localString.length();
1✔
1614
        final int localPosition;
1615
        if (position == null) {
1✔
1616
            localPosition = 0;
1✔
1617
        } else {
1618
            final int from = position < 0 ? 0 : position;
1✔
1619
            localPosition = Math.min(from, length);
1✔
1620
        }
1621

1622
        return localString.lastIndexOf(target, localPosition) == localPosition;
1✔
1623
    }
1624

1625
    private static int charsLeftIndex(final String string, final String chars) {
1626
        int index = 0;
1✔
1627
        final int length = string.length();
1✔
1628
        while (index < length && chars.indexOf(string.charAt(index)) > -1) {
1✔
1629
            index += 1;
1✔
1630
        }
1631
        return index == length ? -1 : index;
1✔
1632
    }
1633

1634
    private static int charsRightIndex(final String string, final String chars) {
1635
        int index = string.length() - 1;
1✔
1636
        while (index >= 0 && chars.indexOf(string.charAt(index)) > -1) {
1✔
1637
            index -= 1;
1✔
1638
        }
1639
        return index;
1✔
1640
    }
1641

1642
    public static String trim(final String string) {
1643
        return trim(string, null);
1✔
1644
    }
1645

1646
    public static String trim(final String string, final String chars) {
1647
        final String localString = baseToString(string);
1✔
1648
        if (localString.isEmpty()) {
1✔
1649
            return localString;
1✔
1650
        }
1651
        final String localChars;
1652
        if (chars == null) {
1✔
1653
            localChars = " ";
1✔
1654
        } else {
1655
            localChars = chars;
1✔
1656
        }
1657
        final int leftIndex = charsLeftIndex(localString, localChars);
1✔
1658
        final int rightIndex = charsRightIndex(localString, localChars);
1✔
1659
        return leftIndex > -1 ? localString.substring(leftIndex, rightIndex + 1) : localString;
1✔
1660
    }
1661

1662
    public static String trimStart(final String string) {
1663
        return trimStart(string, null);
1✔
1664
    }
1665

1666
    public static String trimStart(final String string, final String chars) {
1667
        final String localString = baseToString(string);
1✔
1668
        if (localString.isEmpty()) {
1✔
1669
            return localString;
1✔
1670
        }
1671
        final String localChars;
1672
        if (chars == null) {
1✔
1673
            localChars = " ";
1✔
1674
        } else {
1675
            localChars = chars;
1✔
1676
        }
1677
        final int leftIndex = charsLeftIndex(localString, localChars);
1✔
1678
        return leftIndex > -1 ? localString.substring(leftIndex) : localString;
1✔
1679
    }
1680

1681
    public static String trimEnd(final String string) {
1682
        return trimEnd(string, null);
1✔
1683
    }
1684

1685
    public static String trimEnd(final String string, final String chars) {
1686
        final String localString = baseToString(string);
1✔
1687
        if (localString.isEmpty()) {
1✔
1688
            return localString;
1✔
1689
        }
1690
        final String localChars;
1691
        if (chars == null) {
1✔
1692
            localChars = " ";
1✔
1693
        } else {
1694
            localChars = chars;
1✔
1695
        }
1696
        final int rightIndex = charsRightIndex(localString, localChars);
1✔
1697
        return rightIndex > -1 ? localString.substring(0, rightIndex + 1) : localString;
1✔
1698
    }
1699

1700
    public static String trunc(final String string) {
1701
        return trunc(string, DEFAULT_TRUNC_LENGTH);
1✔
1702
    }
1703

1704
    public static String trunc(final String string, final Integer length) {
1705
        final String localString = baseToString(string);
1✔
1706
        final String omission = DEFAULT_TRUNC_OMISSION;
1✔
1707
        if (length >= localString.length()) {
1✔
1708
            return localString;
1✔
1709
        }
1710
        final int end = length - omission.length();
1✔
1711
        final String result = localString.substring(0, end);
1✔
1712
        return result + omission;
1✔
1713
    }
1714

1715
    public static List<String> stringToPath(final String string) {
1716
        final List<String> result = new ArrayList<>();
1✔
1717
        final java.util.regex.Matcher matcher = RE_PROP_NAME.matcher(baseToString(string));
1✔
1718
        while (matcher.find()) {
1✔
1719
            result.add(matcher.group(1) == null ? matcher.group(0) : matcher.group(1));
1✔
1720
        }
1721
        return result;
1✔
1722
    }
1723

1724
    private enum OperationType {
1✔
1725
        GET,
1✔
1726
        SET,
1✔
1727
        REMOVE
1✔
1728
    }
1729

1730
    @SuppressWarnings("unchecked")
1731
    private static <T> T baseGetOrSetOrRemove(
1732
            final Map<String, Object> object,
1733
            final List<String> paths,
1734
            final Object value,
1735
            OperationType operationType) {
1736
        int index = 0;
1✔
1737
        final int length = paths.size();
1✔
1738

1739
        Object localObject = object;
1✔
1740
        Object savedLocalObject = null;
1✔
1741
        String savedPath = null;
1✔
1742
        while (localObject != null && index < length) {
1✔
1743
            if (localObject instanceof Map) {
1✔
1744
                Map.Entry mapEntry = getMapEntry((Map) localObject);
1✔
1745
                if (mapEntry != null && "#item".equals(mapEntry.getKey())) {
1✔
1746
                    localObject = mapEntry.getValue();
1✔
1747
                    continue;
1✔
1748
                }
1749
                savedLocalObject = localObject;
1✔
1750
                savedPath = paths.get(index);
1✔
1751
                localObject = ((Map) localObject).get(paths.get(index));
1✔
1752
            } else if (localObject instanceof List) {
1✔
1753
                savedLocalObject = localObject;
1✔
1754
                savedPath = paths.get(index);
1✔
1755
                localObject = ((List) localObject).get(Integer.parseInt(paths.get(index)));
1✔
1756
            } else {
1757
                break;
1758
            }
1759
            index += 1;
1✔
1760
        }
1761
        if (index > 0 && index == length) {
1✔
1762
            checkSetAndRemove(value, operationType, savedLocalObject, savedPath);
1✔
1763
            return (T) localObject;
1✔
1764
        }
1765
        return null;
1✔
1766
    }
1767

1768
    @SuppressWarnings("unchecked")
1769
    private static void checkSetAndRemove(
1770
            Object value, OperationType operationType, Object savedLocalObject, String savedPath) {
1771
        if (operationType == OperationType.SET) {
1✔
1772
            if (savedLocalObject instanceof Map) {
1✔
1773
                ((Map) savedLocalObject).put(savedPath, value);
1✔
1774
            } else {
1775
                ((List) savedLocalObject).set(Integer.parseInt(savedPath), value);
1✔
1776
            }
1777
        } else if (operationType == OperationType.REMOVE) {
1✔
1778
            if (savedLocalObject instanceof Map) {
1✔
1779
                ((Map) savedLocalObject).remove(savedPath);
1✔
1780
            } else {
1781
                ((List) savedLocalObject).remove(Integer.parseInt(savedPath));
1✔
1782
            }
1783
        }
1784
    }
1✔
1785

1786
    private static Map.Entry getMapEntry(Map map) {
1787
        return map.isEmpty() ? null : (Map.Entry) map.entrySet().iterator().next();
1✔
1788
    }
1789

1790
    public static <T> T get(final Map<String, Object> object, final String path) {
1791
        return get(object, stringToPath(path));
1✔
1792
    }
1793

1794
    public static <T> T get(final Map<String, Object> object, final List<String> paths) {
1795
        return baseGetOrSetOrRemove(object, paths, null, OperationType.GET);
1✔
1796
    }
1797

1798
    public static String selectToken(final Map<String, Object> object, final String expression) {
1799
        final String xml = toXml(object);
1✔
1800
        try {
1801
            final XPath xPath = XPathFactory.newInstance().newXPath();
1✔
1802
            final org.w3c.dom.Document document = Xml.Document.createDocument(xml);
1✔
1803
            final NodeList nodes =
1✔
1804
                    (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET);
1✔
1805
            if (nodes.getLength() == 0) {
1✔
1806
                return null;
1✔
1807
            }
1808
            return nodes.item(0).getNodeValue();
1✔
1809
        } catch (Exception ex) {
1✔
1810
            throw new IllegalArgumentException(ex);
1✔
1811
        }
1812
    }
1813

1814
    public static List<String> selectTokens(
1815
            final Map<String, Object> object, final String expression) {
1816
        final String xml = toXml(object);
1✔
1817
        try {
1818
            final XPath xPath = XPathFactory.newInstance().newXPath();
1✔
1819
            final org.w3c.dom.Document document = Xml.Document.createDocument(xml);
1✔
1820
            final NodeList nodes =
1✔
1821
                    (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET);
1✔
1822
            final List<String> result = new ArrayList<>();
1✔
1823
            for (int i = 0; i < nodes.getLength(); i++) {
1✔
1824
                result.add(nodes.item(i).getNodeValue());
1✔
1825
            }
1826
            return result;
1✔
1827
        } catch (Exception ex) {
1✔
1828
            throw new IllegalArgumentException(ex);
1✔
1829
        }
1830
    }
1831

1832
    public static <T> T set(final Map<String, Object> object, final String path, Object value) {
1833
        return set(object, stringToPath(path), value);
1✔
1834
    }
1835

1836
    public static <T> T set(
1837
            final Map<String, Object> object, final List<String> paths, Object value) {
1838
        return baseGetOrSetOrRemove(object, paths, value, OperationType.SET);
1✔
1839
    }
1840

1841
    public static <T> T remove(final Map<String, Object> object, final String path) {
1842
        return remove(object, stringToPath(path));
1✔
1843
    }
1844

1845
    public static <T> T remove(final Map<String, Object> object, final List<String> paths) {
1846
        return baseGetOrSetOrRemove(object, paths, null, OperationType.REMOVE);
1✔
1847
    }
1848

1849
    public static Map<String, Object> rename(
1850
            final Map<String, Object> map, final String oldKey, final String newKey) {
1851
        Map<String, Object> outMap = newLinkedHashMap();
1✔
1852
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
1853
            if (entry.getKey().equals(oldKey)) {
1✔
1854
                outMap.put(newKey, makeObjectForRename(entry.getValue(), oldKey, newKey));
1✔
1855
            } else {
1856
                outMap.put(entry.getKey(), makeObjectForRename(entry.getValue(), oldKey, newKey));
1✔
1857
            }
1858
        }
1✔
1859
        return outMap;
1✔
1860
    }
1861

1862
    @SuppressWarnings("unchecked")
1863
    private static Object makeObjectForRename(
1864
            Object value, final String oldKey, final String newKey) {
1865
        final Object result;
1866
        if (value instanceof List) {
1✔
1867
            List<Object> values = newArrayList();
1✔
1868
            for (Object item : (List) value) {
1✔
1869
                values.add(
1✔
1870
                        item instanceof Map
1✔
1871
                                ? rename((Map<String, Object>) item, oldKey, newKey)
1✔
1872
                                : item);
1✔
1873
            }
1✔
1874
            result = values;
1✔
1875
        } else if (value instanceof Map) {
1✔
1876
            result = rename((Map<String, Object>) value, oldKey, newKey);
1✔
1877
        } else {
1878
            result = value;
1✔
1879
        }
1880
        return result;
1✔
1881
    }
1882

1883
    public static Map<String, Object> setValue(
1884
            final Map<String, Object> map, final String key, final Object newValue) {
1885
        return setValue(map, key, (key1, value) -> newValue);
1✔
1886
    }
1887

1888
    public static Map<String, Object> setValue(
1889
            final Map<String, Object> map,
1890
            final String key,
1891
            final BiFunction<String, Object, Object> newValue) {
1892
        Map<String, Object> outMap = newLinkedHashMap();
1✔
1893
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
1894
            if (entry.getKey().equals(key)) {
1✔
1895
                outMap.put(
1✔
1896
                        key,
1897
                        makeObjectForSetValue(
1✔
1898
                                newValue.apply(key, entry.getValue()), key, newValue));
1✔
1899
            } else {
1900
                outMap.put(entry.getKey(), makeObjectForSetValue(entry.getValue(), key, newValue));
1✔
1901
            }
1902
        }
1✔
1903
        return outMap;
1✔
1904
    }
1905

1906
    @SuppressWarnings("unchecked")
1907
    private static Object makeObjectForSetValue(
1908
            Object value, final String key, final BiFunction<String, Object, Object> newValue) {
1909
        final Object result;
1910
        if (value instanceof List) {
1✔
1911
            List<Object> values = newArrayList();
1✔
1912
            for (Object item : (List) value) {
1✔
1913
                values.add(
1✔
1914
                        item instanceof Map
1✔
1915
                                ? setValue((Map<String, Object>) item, key, newValue)
1✔
1916
                                : item);
1✔
1917
            }
1✔
1918
            result = values;
1✔
1919
        } else if (value instanceof Map) {
1✔
1920
            result = setValue((Map<String, Object>) value, key, newValue);
1✔
1921
        } else {
1922
            result = value;
1✔
1923
        }
1924
        return result;
1✔
1925
    }
1926

1927
    public static Map<String, Object> update(
1928
            final Map<String, Object> map1, final Map<String, Object> map2) {
1929
        Map<String, Object> outMap = newLinkedHashMap();
1✔
1930
        for (Map.Entry<String, Object> entry : map1.entrySet()) {
1✔
1931
            String key = entry.getKey();
1✔
1932
            Object value2 = entry.getValue();
1✔
1933
            if (map2.containsKey(key)) {
1✔
1934
                createKey(map2, key, value2, outMap);
1✔
1935
            } else {
1936
                outMap.put(key, value2);
1✔
1937
            }
1938
        }
1✔
1939
        for (Map.Entry<String, Object> entry : map2.entrySet()) {
1✔
1940
            String key = entry.getKey();
1✔
1941
            Object value2 = entry.getValue();
1✔
1942
            if (map1.containsKey(key)) {
1✔
1943
                createKey(map1, key, value2, outMap);
1✔
1944
            } else {
1945
                outMap.put(key, value2);
1✔
1946
            }
1947
        }
1✔
1948
        return outMap;
1✔
1949
    }
1950

1951
    @SuppressWarnings("unchecked")
1952
    private static void createKey(
1953
            final Map<String, Object> map, String key, Object value2, Map<String, Object> outMap) {
1954
        Object value1 = map.get(key);
1✔
1955
        if (value1 instanceof Map && value2 instanceof Map) {
1✔
1956
            outMap.put(key, update((Map<String, Object>) value1, (Map<String, Object>) value2));
1✔
1957
        } else if (value1 instanceof List && value2 instanceof List) {
1✔
1958
            outMap.put(key, merge((List<Object>) value1, (List<Object>) value2));
1✔
1959
        } else if (value1 instanceof List) {
1✔
1960
            outMap.put(key, merge((List<Object>) value1, newArrayList(value2)));
1✔
1961
        } else if (value2 instanceof List) {
1✔
1962
            outMap.put(key, merge(newArrayList(value1), (List<Object>) value2));
1✔
1963
        } else {
1964
            outMap.put(key, value2);
1✔
1965
        }
1966
    }
1✔
1967

1968
    public static List<Object> merge(List<Object> list1, List<Object> list2) {
1969
        List<Object> outList1 = newArrayList(list1);
1✔
1970
        List<Object> outList2 = newArrayList(list2);
1✔
1971
        outList2.removeAll(list1);
1✔
1972
        outList1.addAll(outList2);
1✔
1973
        return outList1;
1✔
1974
    }
1975

1976
    public static class FetchResponse {
1977
        private final boolean ok;
1978
        private final int status;
1979
        private final Map<String, List<String>> headerFields;
1980
        private final java.io.ByteArrayOutputStream stream;
1981

1982
        public FetchResponse(
1983
                final boolean ok,
1984
                final int status,
1985
                final Map<String, List<String>> headerFields,
1986
                final java.io.ByteArrayOutputStream stream) {
1✔
1987
            this.ok = ok;
1✔
1988
            this.status = status;
1✔
1989
            this.stream = stream;
1✔
1990
            this.headerFields = headerFields;
1✔
1991
        }
1✔
1992

1993
        public boolean isOk() {
1994
            return ok;
1✔
1995
        }
1996

1997
        public int getStatus() {
1998
            return status;
1✔
1999
        }
2000

2001
        public Map<String, List<String>> getHeaderFields() {
2002
            return headerFields;
1✔
2003
        }
2004

2005
        public byte[] blob() {
2006
            return stream.toByteArray();
1✔
2007
        }
2008

2009
        public String text() {
2010
            return stream.toString(StandardCharsets.UTF_8);
1✔
2011
        }
2012

2013
        public Object json() {
2014
            return Json.fromJson(text());
1✔
2015
        }
2016

2017
        public Map<String, Object> jsonMap() {
2018
            return fromJsonMap(text());
1✔
2019
        }
2020

2021
        public Object xml() {
2022
            return Xml.fromXml(text());
1✔
2023
        }
2024

2025
        public Map<String, Object> xmlMap() {
2026
            return fromXmlMap(text());
1✔
2027
        }
2028
    }
2029

2030
    public static long downloadUrl(final String url, final String fileName)
2031
            throws IOException, URISyntaxException {
2032
        final URL website = new URI(url).toURL();
1✔
2033
        try (ReadableByteChannel rbc = Channels.newChannel(website.openStream());
1✔
2034
                final FileOutputStream fos = new FileOutputStream(fileName)) {
1✔
2035
            return fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
1✔
2036
        }
2037
    }
2038

2039
    public static void decompressGzip(final String sourceFileName, final String targetFileName)
2040
            throws IOException {
2041
        try (GZIPInputStream gis =
1✔
2042
                new GZIPInputStream(new FileInputStream(new File(sourceFileName)))) {
2043
            Files.copy(gis, Paths.get(targetFileName));
1✔
2044
        }
2045
    }
1✔
2046

2047
    public static FetchResponse fetch(final String url) {
2048
        return fetch(url, null, null, DEFAULT_HEADER_FIELDS, null, null);
1✔
2049
    }
2050

2051
    public static FetchResponse fetch(
2052
            final String url, final Integer connectTimeout, final Integer readTimeout) {
2053
        return fetch(url, null, null, DEFAULT_HEADER_FIELDS, connectTimeout, readTimeout);
1✔
2054
    }
2055

2056
    public static FetchResponse fetch(
2057
            final String url,
2058
            final Integer connectTimeout,
2059
            final Integer readTimeout,
2060
            final Integer retryCount,
2061
            final Integer timeBetweenRetry) {
2062
        return Fetch.fetch(
1✔
2063
                url,
2064
                null,
2065
                null,
2066
                DEFAULT_HEADER_FIELDS,
2067
                connectTimeout,
2068
                readTimeout,
2069
                retryCount,
2070
                timeBetweenRetry);
2071
    }
2072

2073
    public static FetchResponse fetch(final String url, final String method, final String body) {
2074
        return fetch(url, method, body, DEFAULT_HEADER_FIELDS, null, null);
1✔
2075
    }
2076

2077
    public static class BaseHttpSslSocketFactory extends javax.net.ssl.SSLSocketFactory {
2078
        private javax.net.ssl.SSLContext getSslContext() {
2079
            return createEasySslContext();
2080
        }
2081

2082
        @Override
2083
        public java.net.Socket createSocket(
2084
                java.net.InetAddress arg0, int arg1, java.net.InetAddress arg2, int arg3)
2085
                throws java.io.IOException {
2086
            return getSslContext().getSocketFactory().createSocket(arg0, arg1, arg2, arg3);
2087
        }
2088

2089
        @Override
2090
        public java.net.Socket createSocket(
2091
                String arg0, int arg1, java.net.InetAddress arg2, int arg3)
2092
                throws java.io.IOException {
2093
            return getSslContext().getSocketFactory().createSocket(arg0, arg1, arg2, arg3);
2094
        }
2095

2096
        @Override
2097
        public java.net.Socket createSocket(java.net.InetAddress arg0, int arg1)
2098
                throws java.io.IOException {
2099
            return getSslContext().getSocketFactory().createSocket(arg0, arg1);
2100
        }
2101

2102
        @Override
2103
        public java.net.Socket createSocket(String arg0, int arg1) throws java.io.IOException {
2104
            return getSslContext().getSocketFactory().createSocket(arg0, arg1);
2105
        }
2106

2107
        @Override
2108
        public String[] getSupportedCipherSuites() {
2109
            return new String[] {};
2110
        }
2111

2112
        @Override
2113
        public String[] getDefaultCipherSuites() {
2114
            return new String[] {};
2115
        }
2116

2117
        @Override
2118
        public java.net.Socket createSocket(
2119
                java.net.Socket arg0, String arg1, int arg2, boolean arg3)
2120
                throws java.io.IOException {
2121
            return getSslContext().getSocketFactory().createSocket(arg0, arg1, arg2, arg3);
2122
        }
2123

2124
        private javax.net.ssl.SSLContext createEasySslContext() {
2125
            try {
2126
                javax.net.ssl.SSLContext context = javax.net.ssl.SSLContext.getInstance("SSL");
2127
                context.init(
2128
                        null, new javax.net.ssl.TrustManager[] {MyX509TrustManager.manger}, null);
2129
                return context;
2130
            } catch (Exception ex) {
2131
                throw new UnsupportedOperationException(ex);
2132
            }
2133
        }
2134

2135
        public static class MyX509TrustManager implements javax.net.ssl.X509TrustManager {
2136

2137
            static MyX509TrustManager manger = new MyX509TrustManager();
2138

2139
            public MyX509TrustManager() {
2140
                // ignore MyX509TrustManager
2141
            }
2142

2143
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
2144
                return new java.security.cert.X509Certificate[] {};
2145
            }
2146

2147
            public void checkClientTrusted(
2148
                    java.security.cert.X509Certificate[] chain, String authType) {
2149
                // ignore checkClientTrusted
2150
            }
2151

2152
            public void checkServerTrusted(
2153
                    java.security.cert.X509Certificate[] chain, String authType) {
2154
                // ignore checkServerTrusted
2155
            }
2156
        }
2157
    }
2158

2159
    public static void setupConnection(
2160
            final java.net.HttpURLConnection connection,
2161
            final String method,
2162
            final Map<String, List<String>> headerFields,
2163
            final Integer connectTimeout,
2164
            final Integer readTimeout)
2165
            throws java.io.IOException {
2166
        final String localMethod;
2167
        if (SUPPORTED_HTTP_METHODS.contains(method)) {
1✔
2168
            localMethod = method;
1✔
2169
        } else {
2170
            localMethod = "GET";
1✔
2171
        }
2172
        connection.setRequestMethod(localMethod);
1✔
2173
        if (connectTimeout != null) {
1✔
2174
            connection.setConnectTimeout(connectTimeout);
1✔
2175
        }
2176
        if (readTimeout != null) {
1✔
2177
            connection.setReadTimeout(readTimeout);
1✔
2178
        }
2179
        if (connection instanceof javax.net.ssl.HttpsURLConnection) {
1✔
2180
            ((javax.net.ssl.HttpsURLConnection) connection)
1✔
2181
                    .setSSLSocketFactory(new BaseHttpSslSocketFactory());
1✔
2182
        }
2183
        if (headerFields != null) {
1✔
2184
            for (final Map.Entry<String, List<String>> header : headerFields.entrySet()) {
1✔
2185
                connection.setRequestProperty(header.getKey(), join(header.getValue(), ";"));
1✔
2186
            }
1✔
2187
        }
2188
    }
1✔
2189

2190
    public static FetchResponse fetch(
2191
            final String url,
2192
            final String method,
2193
            final String body,
2194
            final Map<String, List<String>> headerFields,
2195
            final Integer connectTimeout,
2196
            final Integer readTimeout) {
2197
        try {
2198
            final java.net.URL localUrl = new java.net.URI(url).toURL();
1✔
2199
            final java.net.HttpURLConnection connection =
1✔
2200
                    (java.net.HttpURLConnection) localUrl.openConnection();
1✔
2201
            setupConnection(connection, method, headerFields, connectTimeout, readTimeout);
1✔
2202
            if (body != null) {
1✔
2203
                connection.setDoOutput(true);
1✔
2204
                final java.io.DataOutputStream outputStream =
1✔
2205
                        new java.io.DataOutputStream(connection.getOutputStream());
1✔
2206
                outputStream.write(body.getBytes(StandardCharsets.UTF_8));
1✔
2207
                outputStream.close();
1✔
2208
            }
2209
            final int responseCode = connection.getResponseCode();
1✔
2210
            final java.io.InputStream inputStream;
2211
            if (responseCode < RESPONSE_CODE_400) {
1✔
2212
                inputStream = connection.getInputStream();
1✔
2213
            } else {
2214
                inputStream = connection.getErrorStream();
1✔
2215
            }
2216
            final java.io.ByteArrayOutputStream result = new java.io.ByteArrayOutputStream();
1✔
2217
            final byte[] buffer = new byte[BUFFER_LENGTH_1024];
1✔
2218
            int length;
2219
            while ((length = inputStream.read(buffer)) != -1) {
1✔
2220
                result.write(buffer, 0, length);
1✔
2221
            }
2222
            inputStream.close();
1✔
2223
            return new FetchResponse(
1✔
2224
                    responseCode < RESPONSE_CODE_400,
2225
                    responseCode,
2226
                    connection.getHeaderFields(),
1✔
2227
                    result);
2228
        } catch (java.io.IOException | java.net.URISyntaxException ex) {
1✔
2229
            throw new UnsupportedOperationException(ex);
1✔
2230
        }
2231
    }
2232

2233
    public static class Fetch {
2234
        private Fetch() {}
2235

2236
        @SuppressWarnings("java:S107")
2237
        public static FetchResponse fetch(
2238
                final String url,
2239
                final String method,
2240
                final String body,
2241
                final Map<String, List<String>> headerFields,
2242
                final Integer connectTimeout,
2243
                final Integer readTimeout,
2244
                final Integer retryCount,
2245
                final Integer timeBetweenRetry) {
2246
            if (nonNull(retryCount)
2247
                    && retryCount > 0
2248
                    && retryCount <= 10
2249
                    && nonNull(timeBetweenRetry)
2250
                    && timeBetweenRetry > 0) {
2251
                int localRetryCount = 0;
2252
                UnsupportedOperationException saveException;
2253
                do {
2254
                    try {
2255
                        final FetchResponse fetchResponse =
2256
                                U.fetch(
2257
                                        url,
2258
                                        method,
2259
                                        body,
2260
                                        headerFields,
2261
                                        connectTimeout,
2262
                                        readTimeout);
2263
                        if (fetchResponse.getStatus() == 429) {
2264
                            saveException = new UnsupportedOperationException("Too Many Requests");
2265
                        } else {
2266
                            return fetchResponse;
2267
                        }
2268
                    } catch (UnsupportedOperationException ex) {
2269
                        saveException = ex;
2270
                    }
2271
                    localRetryCount += 1;
2272
                    try {
2273
                        java.util.concurrent.TimeUnit.MILLISECONDS.sleep(timeBetweenRetry);
2274
                    } catch (InterruptedException ex) {
2275
                        saveException = new UnsupportedOperationException(ex);
2276
                        Thread.currentThread().interrupt();
2277
                    }
2278
                } while (localRetryCount <= retryCount);
2279
                throw saveException;
2280
            }
2281
            return U.fetch(url, method, body, headerFields, connectTimeout, readTimeout);
2282
        }
2283
    }
2284

2285
    public static List<String> explode(final String input) {
2286
        List<String> result = newArrayList();
1✔
2287
        if (isNull(input)) {
1✔
2288
            return result;
1✔
2289
        }
2290
        for (char character : input.toCharArray()) {
1✔
2291
            result.add(String.valueOf(character));
1✔
2292
        }
2293
        return result;
1✔
2294
    }
2295

2296
    public static String implode(final String[] input) {
2297
        StringBuilder builder = new StringBuilder();
1✔
2298
        for (String character : input) {
1✔
2299
            if (nonNull(character)) {
1✔
2300
                builder.append(character);
1✔
2301
            }
2302
        }
2303
        return builder.toString();
1✔
2304
    }
2305

2306
    public static String implode(final Iterable<String> input) {
2307
        StringBuilder builder = new StringBuilder();
1✔
2308
        for (String character : input) {
1✔
2309
            if (nonNull(character)) {
1✔
2310
                builder.append(character);
1✔
2311
            }
2312
        }
1✔
2313
        return builder.toString();
1✔
2314
    }
2315

2316
    public String camelCase() {
2317
        return camelCase(getString().get());
1✔
2318
    }
2319

2320
    public String lowerFirst() {
2321
        return lowerFirst(getString().get());
1✔
2322
    }
2323

2324
    public String upperFirst() {
2325
        return upperFirst(getString().get());
1✔
2326
    }
2327

2328
    public String capitalize() {
2329
        return capitalize(getString().get());
1✔
2330
    }
2331

2332
    public String deburr() {
2333
        return deburr(getString().get());
1✔
2334
    }
2335

2336
    public boolean endsWith(final String target) {
2337
        return endsWith(getString().get(), target);
1✔
2338
    }
2339

2340
    public boolean endsWith(final String target, final Integer position) {
2341
        return endsWith(getString().get(), target, position);
1✔
2342
    }
2343

2344
    public String kebabCase() {
2345
        return kebabCase(getString().get());
1✔
2346
    }
2347

2348
    public String repeat(final int length) {
2349
        return repeat(getString().get(), length);
1✔
2350
    }
2351

2352
    public String pad(final int length) {
2353
        return pad(getString().get(), length);
1✔
2354
    }
2355

2356
    public String pad(final int length, final String chars) {
2357
        return pad(getString().get(), length, chars);
1✔
2358
    }
2359

2360
    public String padStart(final int length) {
2361
        return padStart(getString().get(), length);
1✔
2362
    }
2363

2364
    public String padStart(final int length, final String chars) {
2365
        return padStart(getString().get(), length, chars);
1✔
2366
    }
2367

2368
    public String padEnd(final int length) {
2369
        return padEnd(getString().get(), length);
1✔
2370
    }
2371

2372
    public String padEnd(final int length, final String chars) {
2373
        return padEnd(getString().get(), length, chars);
1✔
2374
    }
2375

2376
    public String snakeCase() {
2377
        return snakeCase(getString().get());
1✔
2378
    }
2379

2380
    public String startCase() {
2381
        return startCase(getString().get());
1✔
2382
    }
2383

2384
    public boolean startsWith(final String target) {
2385
        return startsWith(getString().get(), target);
1✔
2386
    }
2387

2388
    public boolean startsWith(final String target, final Integer position) {
2389
        return startsWith(getString().get(), target, position);
1✔
2390
    }
2391

2392
    public String trim() {
2393
        return trim(getString().get());
1✔
2394
    }
2395

2396
    public String trimWith(final String chars) {
2397
        return trim(getString().get(), chars);
1✔
2398
    }
2399

2400
    public String trimStart() {
2401
        return trimStart(getString().get());
1✔
2402
    }
2403

2404
    public String trimStartWith(final String chars) {
2405
        return trimStart(getString().get(), chars);
1✔
2406
    }
2407

2408
    public String trimEnd() {
2409
        return trimEnd(getString().get());
1✔
2410
    }
2411

2412
    public String trimEndWith(final String chars) {
2413
        return trimEnd(getString().get(), chars);
1✔
2414
    }
2415

2416
    public String trunc() {
2417
        return trunc(getString().get());
1✔
2418
    }
2419

2420
    public String trunc(final int length) {
2421
        return trunc(getString().get(), length);
1✔
2422
    }
2423

2424
    public String uncapitalize() {
2425
        return uncapitalize(getString().get());
1✔
2426
    }
2427

2428
    public List<String> words() {
2429
        return words(getString().get());
1✔
2430
    }
2431

2432
    public static class LruCache<K, V> {
2433
        private static final boolean SORT_BY_ACCESS = true;
2434
        private static final float LOAD_FACTOR = 0.75F;
2435
        private final Map<K, V> lruCacheMap;
2436
        private final int capacity;
2437

2438
        public LruCache(int capacity) {
1✔
2439
            this.capacity = capacity;
1✔
2440
            this.lruCacheMap = new LinkedHashMap<>(capacity, LOAD_FACTOR, SORT_BY_ACCESS);
1✔
2441
        }
1✔
2442

2443
        public V get(K key) {
2444
            return lruCacheMap.get(key);
1✔
2445
        }
2446

2447
        public void put(K key, V value) {
2448
            if (lruCacheMap.containsKey(key)) {
1✔
2449
                lruCacheMap.remove(key);
1✔
2450
            } else if (lruCacheMap.size() >= capacity) {
1✔
2451
                lruCacheMap.remove(lruCacheMap.keySet().iterator().next());
1✔
2452
            }
2453
            lruCacheMap.put(key, value);
1✔
2454
        }
1✔
2455
    }
2456

2457
    public static <K, V> LruCache<K, V> createLruCache(final int capacity) {
2458
        return new LruCache<>(capacity);
1✔
2459
    }
2460

2461
    public static <T> List<List<T>> createPermutationWithRepetition(
2462
            final List<T> list, final int permutationLength) {
2463
        final long resultSize = (long) Math.pow(list.size(), permutationLength);
1✔
2464
        final List<List<T>> result = new ArrayList<>((int) resultSize);
1✔
2465
        final int[] bitVector = new int[permutationLength];
1✔
2466
        for (int index = 0; index < resultSize; index += 1) {
1✔
2467
            List<T> result2 = new ArrayList<>(permutationLength);
1✔
2468
            for (int index2 = 0; index2 < permutationLength; index2 += 1) {
1✔
2469
                result2.add(list.get(bitVector[index2]));
1✔
2470
            }
2471
            int index3 = 0;
1✔
2472
            while (index3 < permutationLength && bitVector[index3] == list.size() - 1) {
1✔
2473
                bitVector[index3] = 0;
1✔
2474
                index3 += 1;
1✔
2475
            }
2476
            if (index3 < permutationLength) {
1✔
2477
                bitVector[index3] += 1;
1✔
2478
            }
2479
            result.add(result2);
1✔
2480
        }
2481
        return result;
1✔
2482
    }
2483

2484
    public List<List<T>> createPermutationWithRepetition(final int permutationLength) {
2485
        return createPermutationWithRepetition((List<T>) value(), permutationLength);
1✔
2486
    }
2487

2488
    protected static <T> List<T> newArrayList() {
2489
        return Underscore.newArrayList();
1✔
2490
    }
2491

2492
    protected static <T> List<T> newArrayList(final Iterable<T> iterable) {
2493
        return Underscore.newArrayList(iterable);
1✔
2494
    }
2495

2496
    protected static <T> Set<T> newLinkedHashSet() {
2497
        return Underscore.newLinkedHashSet();
1✔
2498
    }
2499

2500
    protected static <K, E> Map<K, E> newLinkedHashMap() {
2501
        return Underscore.newLinkedHashMap();
1✔
2502
    }
2503

2504
    public static <T> String join(final Iterable<T> iterable, final String separator) {
2505
        return Underscore.join(iterable, separator);
1✔
2506
    }
2507

2508
    public static String toJson(Collection collection) {
2509
        return Json.toJson(collection);
1✔
2510
    }
2511

2512
    public static String toJson(Map map) {
2513
        return Json.toJson(map);
1✔
2514
    }
2515

2516
    public String toJson() {
2517
        return Json.toJson((Collection) getIterable());
1✔
2518
    }
2519

2520
    public static String toJsonJavaString(Collection collection) {
2521
        return Json.toJsonJavaString(collection);
1✔
2522
    }
2523

2524
    public static String toJsonJavaString(Map map) {
2525
        return Json.toJsonJavaString(map);
1✔
2526
    }
2527

2528
    public String toJsonJavaString() {
2529
        return Json.toJsonJavaString((Collection) getIterable());
1✔
2530
    }
2531

2532
    @SuppressWarnings("unchecked")
2533
    public static <T> T fromXml(final String xml) {
2534
        return (T) Xml.fromXml(xml);
1✔
2535
    }
2536

2537
    public static Map<String, Object> fromXmlMap(final String xml) {
2538
        return fromXmlMap(xml, Xml.FromType.FOR_CONVERT);
1✔
2539
    }
2540

2541
    public static Map<String, Object> fromXmlMap(final String xml, final Xml.FromType fromType) {
2542
        final Object object = Xml.fromXml(xml, fromType);
1✔
2543
        return getStringObjectMap(object);
1✔
2544
    }
2545

2546
    @SuppressWarnings("unchecked")
2547
    public static <T> T fromXml(final String xml, final Xml.FromType fromType) {
2548
        return (T) Xml.fromXml(xml, fromType);
1✔
2549
    }
2550

2551
    @SuppressWarnings("unchecked")
2552
    public static <T> T fromXmlMakeArrays(final String xml) {
2553
        return (T) Xml.fromXmlMakeArrays(xml);
1✔
2554
    }
2555

2556
    @SuppressWarnings("unchecked")
2557
    public static <T> T fromXmlWithoutNamespaces(final String xml) {
2558
        return (T) Xml.fromXmlWithoutNamespaces(xml);
1✔
2559
    }
2560

2561
    public static Map<String, Object> fromXmlWithoutNamespacesMap(final String xml) {
2562
        final Object object = Xml.fromXmlWithoutNamespaces(xml);
1✔
2563
        return getStringObjectMap(object);
1✔
2564
    }
2565

2566
    @SuppressWarnings("unchecked")
2567
    public static <T> T fromXmlWithoutAttributes(final String xml) {
2568
        return (T) Xml.fromXmlWithoutAttributes(xml);
1✔
2569
    }
2570

2571
    @SuppressWarnings("unchecked")
2572
    public static <T> T fromXmlWithoutNamespacesAndAttributes(final String xml) {
2573
        return (T) Xml.fromXmlWithoutNamespacesAndAttributes(xml);
1✔
2574
    }
2575

2576
    public static String toXml(Collection collection) {
2577
        return Xml.toXml(collection);
1✔
2578
    }
2579

2580
    public static String toXml(Map map) {
2581
        return Xml.toXml(map);
1✔
2582
    }
2583

2584
    @SuppressWarnings("unchecked")
2585
    public static <T> T fromJson(String string) {
2586
        return (T) Json.fromJson(string);
1✔
2587
    }
2588

2589
    public Object fromJson() {
2590
        return Json.fromJson(getString().get());
1✔
2591
    }
2592

2593
    public static Map<String, Object> fromJsonMap(final String string) {
2594
        final Object object = Json.fromJson(string);
1✔
2595
        return getStringObjectMap(object);
1✔
2596
    }
2597

2598
    @SuppressWarnings("unchecked")
2599
    private static Map<String, Object> getStringObjectMap(Object object) {
2600
        final Map<String, Object> result;
2601
        if (object instanceof Map) {
1✔
2602
            result = (Map<String, Object>) object;
1✔
2603
        } else {
2604
            result = newLinkedHashMap();
1✔
2605
            result.put("value", object);
1✔
2606
        }
2607
        return result;
1✔
2608
    }
2609

2610
    public String toXml() {
2611
        return Xml.toXml((Collection) getIterable());
1✔
2612
    }
2613

2614
    public Object fromXml() {
2615
        return Xml.fromXml(getString().get());
1✔
2616
    }
2617

2618
    @SuppressWarnings("unchecked")
2619
    public static String jsonToXml(
2620
            String json,
2621
            Xml.XmlStringBuilder.Step identStep,
2622
            JsonToXmlMode mode,
2623
            String newRootName) {
2624
        Object object = Json.fromJson(json);
1✔
2625
        final String result;
2626
        if (object instanceof Map) {
1✔
2627
            if (mode == JsonToXmlMode.FORCE_ATTRIBUTE_USAGE) {
1✔
2628
                result = Xml.toXml(forceAttributeUsage((Map) object), identStep, newRootName);
1✔
2629
            } else if (mode == JsonToXmlMode.DEFINE_ROOT_NAME) {
1✔
2630
                result = Xml.toXml((Map) object, identStep, newRootName);
1✔
2631
            } else if (mode == JsonToXmlMode.REPLACE_NULL_WITH_EMPTY_VALUE) {
1✔
2632
                result = Xml.toXml(replaceNullWithEmptyValue((Map) object), identStep, newRootName);
1✔
2633
            } else if (mode == JsonToXmlMode.REPLACE_EMPTY_STRING_WITH_EMPTY_VALUE) {
1✔
2634
                result =
1✔
2635
                        Xml.toXml(
1✔
2636
                                replaceEmptyStringWithEmptyValue((Map) object),
1✔
2637
                                identStep,
2638
                                newRootName);
2639
            } else if (mode == JsonToXmlMode.ADD_ROOT
1✔
2640
                    && !Xml.XmlValue.getMapKey(object).equals(ROOT)) {
1✔
2641
                final Map<String, Object> map = U.newLinkedHashMap();
1✔
2642
                map.put(newRootName, object);
1✔
2643
                result = Xml.toXml(map, identStep);
1✔
2644
            } else if (mode == JsonToXmlMode.REMOVE_ARRAY_ATTRIBUTE) {
1✔
2645
                result = Xml.toXml((Map) object, identStep, newRootName, Xml.ArrayTrue.SKIP);
1✔
2646
            } else if (mode == JsonToXmlMode.REMOVE_ATTRIBUTES) {
1✔
2647
                result =
1✔
2648
                        Xml.toXml(
1✔
2649
                                replaceNumberAndBooleanWithString((Map) object),
1✔
2650
                                identStep,
2651
                                newRootName,
2652
                                Xml.ArrayTrue.SKIP);
2653
            } else {
2654
                result = Xml.toXml((Map) object, identStep);
1✔
2655
            }
2656
            return result;
1✔
2657
        }
2658
        return Xml.toXml((List) object, identStep);
1✔
2659
    }
2660

2661
    public static String jsonToXml(String json, Xml.XmlStringBuilder.Step identStep) {
2662
        return jsonToXml(json, identStep, null, ROOT);
1✔
2663
    }
2664

2665
    public static String jsonToXml(String json, JsonToXmlMode mode) {
2666
        return jsonToXml(json, Xml.XmlStringBuilder.Step.TWO_SPACES, mode, ROOT);
1✔
2667
    }
2668

2669
    public static String jsonToXml(String json, JsonToXmlMode mode, String newRootName) {
2670
        return jsonToXml(json, Xml.XmlStringBuilder.Step.TWO_SPACES, mode, newRootName);
1✔
2671
    }
2672

2673
    public static String jsonToXml(String json, String newRootName) {
2674
        return jsonToXml(
1✔
2675
                json,
2676
                Xml.XmlStringBuilder.Step.TWO_SPACES,
2677
                JsonToXmlMode.DEFINE_ROOT_NAME,
2678
                newRootName);
2679
    }
2680

2681
    public static String jsonToXml(String json) {
2682
        return jsonToXml(json, Xml.XmlStringBuilder.Step.TWO_SPACES, null, null);
1✔
2683
    }
2684

2685
    @SuppressWarnings("unchecked")
2686
    public static String xmlToJson(
2687
            String xml, Json.JsonStringBuilder.Step identStep, XmlToJsonMode mode) {
2688
        Object object = Xml.fromXml(xml);
1✔
2689
        final String result;
2690
        if (object instanceof Map) {
1✔
2691
            if (mode == XmlToJsonMode.REPLACE_SELF_CLOSING_WITH_NULL) {
1✔
2692
                result = Json.toJson(replaceSelfClosingWithNull((Map) object), identStep);
1✔
2693
            } else if (mode == XmlToJsonMode.REPLACE_SELF_CLOSING_WITH_STRING) {
1✔
2694
                result = Json.toJson(replaceSelfClosingWithEmpty((Map) object), identStep);
1✔
2695
            } else if (mode == XmlToJsonMode.REPLACE_EMPTY_VALUE_WITH_NULL) {
1✔
2696
                result = Json.toJson(replaceEmptyValueWithNull((Map) object), identStep);
1✔
2697
            } else if (mode == XmlToJsonMode.REPLACE_EMPTY_TAG_WITH_NULL) {
1✔
2698
                result =
1✔
2699
                        Json.toJson(
1✔
2700
                                replaceEmptyValueWithNull(replaceSelfClosingWithNull((Map) object)),
1✔
2701
                                identStep);
2702
            } else if (mode == XmlToJsonMode.REPLACE_EMPTY_TAG_WITH_STRING) {
1✔
2703
                result =
1✔
2704
                        Json.toJson(
1✔
2705
                                (Map<String, Object>)
2706
                                        replaceEmptyValueWithEmptyString(
1✔
2707
                                                replaceSelfClosingWithEmpty((Map) object)),
1✔
2708
                                identStep);
2709
            } else if (mode == XmlToJsonMode.REMOVE_FIRST_LEVEL) {
1✔
2710
                result = Json.toJson(replaceFirstLevel((Map) object), identStep);
1✔
2711
            } else if (mode == XmlToJsonMode.WITHOUT_NAMESPACES) {
1✔
2712
                result = Json.toJson((Map) Xml.fromXmlWithoutNamespaces(xml), identStep);
1✔
2713
            } else {
2714
                result = Json.toJson((Map) object, identStep);
1✔
2715
            }
2716
            return result;
1✔
2717
        }
2718
        return Json.toJson((List) object, identStep);
1✔
2719
    }
2720

2721
    public static String xmlToJson(String xml) {
2722
        return xmlToJson(xml, Json.JsonStringBuilder.Step.TWO_SPACES, null);
1✔
2723
    }
2724

2725
    public static String xmlToJson(String xml, Json.JsonStringBuilder.Step identStep) {
2726
        return xmlToJson(xml, identStep, null);
1✔
2727
    }
2728

2729
    public static String xmlToJson(String xml, XmlToJsonMode mode) {
2730
        return xmlToJson(xml, Json.JsonStringBuilder.Step.TWO_SPACES, mode);
1✔
2731
    }
2732

2733
    public static String xmlOrJsonToJson(String xmlOrJson, Json.JsonStringBuilder.Step identStep) {
2734
        TextType textType = getTextType(xmlOrJson);
1✔
2735
        final String result;
2736
        if (textType == TextType.JSON) {
1✔
2737
            result = getJsonString(identStep, fromJson(xmlOrJson));
1✔
2738
        } else if (textType == TextType.XML) {
1✔
2739
            result = getJsonString(identStep, fromXml(xmlOrJson));
1✔
2740
        } else {
2741
            result = xmlOrJson;
1✔
2742
        }
2743
        return result;
1✔
2744
    }
2745

2746
    public static String xmlOrJsonToJson(String xmlOrJson) {
2747
        return xmlOrJsonToJson(xmlOrJson, Json.JsonStringBuilder.Step.TWO_SPACES);
1✔
2748
    }
2749

2750
    @SuppressWarnings("unchecked")
2751
    private static String getJsonString(Json.JsonStringBuilder.Step identStep, Object object) {
2752
        final String result;
2753
        if (object instanceof Map) {
1✔
2754
            result = Json.toJson((Map) object, identStep);
1✔
2755
        } else {
2756
            result = Json.toJson((List) object, identStep);
1✔
2757
        }
2758
        return result;
1✔
2759
    }
2760

2761
    public static String xmlOrJsonToXml(String xmlOrJson, Xml.XmlStringBuilder.Step identStep) {
2762
        TextType textType = getTextType(xmlOrJson);
1✔
2763
        final String result;
2764
        if (textType == TextType.JSON) {
1✔
2765
            result = getXmlString(identStep, fromJson(xmlOrJson));
1✔
2766
        } else if (textType == TextType.XML) {
1✔
2767
            result = getXmlString(identStep, fromXml(xmlOrJson));
1✔
2768
        } else {
2769
            result = xmlOrJson;
1✔
2770
        }
2771
        return result;
1✔
2772
    }
2773

2774
    public static String xmlOrJsonToXml(String xmlOrJson) {
2775
        return xmlOrJsonToXml(xmlOrJson, Xml.XmlStringBuilder.Step.TWO_SPACES);
1✔
2776
    }
2777

2778
    @SuppressWarnings("unchecked")
2779
    private static String getXmlString(Xml.XmlStringBuilder.Step identStep, Object object) {
2780
        final String result;
2781
        if (object instanceof Map) {
1✔
2782
            result = Xml.toXml((Map) object, identStep);
1✔
2783
        } else {
2784
            result = Xml.toXml((List) object, identStep);
1✔
2785
        }
2786
        return result;
1✔
2787
    }
2788

2789
    public enum TextType {
1✔
2790
        JSON,
1✔
2791
        XML,
1✔
2792
        OTHER
1✔
2793
    }
2794

2795
    public static TextType getTextType(String text) {
2796
        String trimmed = trim(text);
1✔
2797
        final TextType textType;
2798
        if (trimmed.startsWith("{") && trimmed.endsWith("}")
1✔
2799
                || trimmed.startsWith("[") && trimmed.endsWith("]")) {
1✔
2800
            textType = TextType.JSON;
1✔
2801
        } else if (trimmed.startsWith("<") && trimmed.endsWith(">")) {
1✔
2802
            textType = TextType.XML;
1✔
2803
        } else {
2804
            textType = TextType.OTHER;
1✔
2805
        }
2806
        return textType;
1✔
2807
    }
2808

2809
    public static String formatJsonOrXml(String jsonOrXml, String identStep) {
2810
        TextType textType = getTextType(jsonOrXml);
1✔
2811
        final String result;
2812
        if (textType == TextType.JSON) {
1✔
2813
            result = formatJson(jsonOrXml, Json.JsonStringBuilder.Step.valueOf(identStep));
1✔
2814
        } else if (textType == TextType.XML) {
1✔
2815
            result = formatXml(jsonOrXml, Xml.XmlStringBuilder.Step.valueOf(identStep));
1✔
2816
        } else {
2817
            result = jsonOrXml;
1✔
2818
        }
2819
        return result;
1✔
2820
    }
2821

2822
    public static String formatJsonOrXml(String jsonOrXml) {
2823
        return formatJsonOrXml(jsonOrXml, "TWO_SPACES");
1✔
2824
    }
2825

2826
    public static String formatJson(String json, Json.JsonStringBuilder.Step identStep) {
2827
        return Json.formatJson(json, identStep);
1✔
2828
    }
2829

2830
    public static String formatJson(String json) {
2831
        return Json.formatJson(json);
1✔
2832
    }
2833

2834
    public static String formatXml(String xml, Xml.XmlStringBuilder.Step identStep) {
2835
        return Xml.formatXml(xml, identStep);
1✔
2836
    }
2837

2838
    public static String formatXml(String xml) {
2839
        return Xml.formatXml(xml);
1✔
2840
    }
2841

2842
    public static String changeXmlEncoding(
2843
            String xml, Xml.XmlStringBuilder.Step identStep, String encoding) {
2844
        return Xml.changeXmlEncoding(xml, identStep, encoding);
1✔
2845
    }
2846

2847
    public static String changeXmlEncoding(String xml, String encoding) {
2848
        return Xml.changeXmlEncoding(xml, encoding);
1✔
2849
    }
2850

2851
    public static Map<String, Object> removeMinusesAndConvertNumbers(Map<String, Object> map) {
2852
        Map<String, Object> outMap = newLinkedHashMap();
1✔
2853
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
2854
            final String newKey;
2855
            if (entry.getKey().startsWith("-")) {
1✔
2856
                newKey = entry.getKey().substring(1);
1✔
2857
            } else {
2858
                newKey = entry.getKey();
1✔
2859
            }
2860
            if (!entry.getKey().equals(selfClosing)
1✔
2861
                    && !entry.getKey().equals("#omit-xml-declaration")) {
1✔
2862
                outMap.put(newKey, makeObject(entry.getValue()));
1✔
2863
            }
2864
        }
1✔
2865
        return outMap;
1✔
2866
    }
2867

2868
    @SuppressWarnings("unchecked")
2869
    private static Object makeObject(Object value) {
2870
        final Object result;
2871
        if (value instanceof List) {
1✔
2872
            List<Object> values = newArrayList();
1✔
2873
            for (Object item : (List) value) {
1✔
2874
                values.add(
1✔
2875
                        item instanceof Map
1✔
2876
                                ? removeMinusesAndConvertNumbers((Map<String, Object>) item)
1✔
2877
                                : item);
1✔
2878
            }
1✔
2879
            result = values;
1✔
2880
        } else if (value instanceof Map) {
1✔
2881
            result = removeMinusesAndConvertNumbers((Map) value);
1✔
2882
        } else {
2883
            String stringValue = String.valueOf(value);
1✔
2884
            result = isJsonNumber(stringValue) ? Xml.stringToNumber(stringValue) : value;
1✔
2885
        }
2886
        return result;
1✔
2887
    }
2888

2889
    public static boolean isJsonNumber(final String string) {
2890
        boolean eFound = false;
1✔
2891
        boolean periodValid = true;
1✔
2892
        boolean pmValid = true;
1✔
2893
        boolean numberEncountered = false;
1✔
2894
        for (char ch : string.toCharArray()) {
1✔
2895
            if (pmValid) {
1✔
2896
                pmValid = false;
1✔
2897
                if (ch == '-') {
1✔
2898
                    continue;
1✔
2899
                }
2900
            }
2901
            if (!eFound && (ch == 'e' || ch == 'E')) {
1✔
2902
                eFound = true;
1✔
2903
                periodValid = false;
1✔
2904
                pmValid = true;
1✔
2905
                numberEncountered = false;
1✔
2906
                continue;
1✔
2907
            }
2908
            if (periodValid && ch == '.') {
1✔
2909
                periodValid = false;
1✔
2910
                continue;
1✔
2911
            }
2912
            if (ch < '0' || ch > '9') {
1✔
2913
                return false;
1✔
2914
            }
2915
            numberEncountered = true;
1✔
2916
        }
2917
        return numberEncountered;
1✔
2918
    }
2919

2920
    @SuppressWarnings("unchecked")
2921
    public static Map<String, Object> replaceSelfClosingWithNull(Map<String, Object> map) {
2922
        return (Map<String, Object>) replaceSelfClosingWithValue(map, null);
1✔
2923
    }
2924

2925
    @SuppressWarnings("unchecked")
2926
    public static Map<String, Object> replaceSelfClosingWithEmpty(Map<String, Object> map) {
2927
        Object result = replaceSelfClosingWithValue(map, "");
1✔
2928
        if (result instanceof Map) {
1✔
2929
            return (Map<String, Object>) result;
1✔
2930
        }
2931
        return Collections.emptyMap();
1✔
2932
    }
2933

2934
    @SuppressWarnings("unchecked")
2935
    public static Object replaceSelfClosingWithValue(Map<String, Object> map, String value) {
2936
        Object outMap = newLinkedHashMap();
1✔
2937
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
2938
            if (selfClosing.equals(entry.getKey()) && "true".equals(entry.getValue())) {
1✔
2939
                if (map.size() == 1) {
1✔
2940
                    outMap = value;
1✔
2941
                    break;
1✔
2942
                }
2943
            } else {
2944
                ((Map<String, Object>) outMap)
1✔
2945
                        .put(
1✔
2946
                                String.valueOf(entry.getKey()),
1✔
2947
                                makeObjectSelfClose(entry.getValue(), value));
1✔
2948
            }
2949
        }
1✔
2950
        return outMap;
1✔
2951
    }
2952

2953
    @SuppressWarnings("unchecked")
2954
    private static Object makeObjectSelfClose(Object value, String newValue) {
2955
        final Object result;
2956
        if (value instanceof List) {
1✔
2957
            List<Object> values = newArrayList();
1✔
2958
            for (Object item : (List) value) {
1✔
2959
                values.add(
1✔
2960
                        item instanceof Map
1✔
2961
                                ? replaceSelfClosingWithValue((Map) item, newValue)
1✔
2962
                                : item);
1✔
2963
            }
1✔
2964
            result = values;
1✔
2965
        } else if (value instanceof Map) {
1✔
2966
            result = replaceSelfClosingWithValue((Map) value, newValue);
1✔
2967
        } else {
2968
            result = value;
1✔
2969
        }
2970
        return result;
1✔
2971
    }
2972

2973
    public static Map<String, Object> replaceEmptyValueWithNull(Map<String, Object> map) {
2974
        if (map == null || map.isEmpty()) {
1✔
2975
            return null;
1✔
2976
        }
2977
        Map<String, Object> outMap = newLinkedHashMap();
1✔
2978
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
2979
            outMap.put(String.valueOf(entry.getKey()), makeObjectEmptyValue(entry.getValue()));
1✔
2980
        }
1✔
2981
        return outMap;
1✔
2982
    }
2983

2984
    @SuppressWarnings("unchecked")
2985
    private static Object makeObjectEmptyValue(Object value) {
2986
        final Object result;
2987
        if (value instanceof List) {
1✔
2988
            List<Object> values = newArrayList();
1✔
2989
            for (Object item : (List) value) {
1✔
2990
                values.add(item instanceof Map ? replaceEmptyValueWithNull((Map) item) : item);
1✔
2991
            }
1✔
2992
            result = values;
1✔
2993
        } else if (value instanceof Map) {
1✔
2994
            result = replaceEmptyValueWithNull((Map) value);
1✔
2995
        } else {
2996
            result = value;
1✔
2997
        }
2998
        return result;
1✔
2999
    }
3000

3001
    public static Object replaceEmptyValueWithEmptyString(Map<String, Object> map) {
3002
        if (map.isEmpty()) {
1✔
3003
            return "";
1✔
3004
        }
3005
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3006
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3007
            outMap.put(String.valueOf(entry.getKey()), makeObjectEmptyString(entry.getValue()));
1✔
3008
        }
1✔
3009
        return outMap;
1✔
3010
    }
3011

3012
    @SuppressWarnings("unchecked")
3013
    private static Object makeObjectEmptyString(Object value) {
3014
        final Object result;
3015
        if (value instanceof List) {
1✔
3016
            List<Object> values = newArrayList();
1✔
3017
            for (Object item : (List) value) {
1✔
3018
                values.add(
1✔
3019
                        item instanceof Map ? replaceEmptyValueWithEmptyString((Map) item) : item);
1✔
3020
            }
1✔
3021
            result = values;
1✔
3022
        } else if (value instanceof Map) {
1✔
3023
            result = replaceEmptyValueWithEmptyString((Map) value);
1✔
3024
        } else {
3025
            result = value;
1✔
3026
        }
3027
        return result;
1✔
3028
    }
3029

3030
    public static Map<String, Object> forceAttributeUsage(Map<String, Object> map) {
3031
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3032
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3033
            outMap.put(
1✔
3034
                    entry.getValue() instanceof Map
1✔
3035
                                    || entry.getValue() instanceof List
1✔
3036
                                    || String.valueOf(entry.getKey()).startsWith("-")
1✔
3037
                            ? String.valueOf(entry.getKey())
1✔
3038
                            : "-" + entry.getKey(),
1✔
3039
                    makeAttributeUsage(entry.getValue()));
1✔
3040
        }
1✔
3041
        return outMap;
1✔
3042
    }
3043

3044
    @SuppressWarnings("unchecked")
3045
    private static Object makeAttributeUsage(Object value) {
3046
        final Object result;
3047
        if (value instanceof List) {
1✔
3048
            List<Object> values = newArrayList();
1✔
3049
            for (Object item : (List) value) {
1✔
3050
                values.add(item instanceof Map ? forceAttributeUsage((Map) item) : item);
1✔
3051
            }
1✔
3052
            result = values;
1✔
3053
        } else if (value instanceof Map) {
1✔
3054
            result = forceAttributeUsage((Map) value);
1✔
3055
        } else {
3056
            result = value;
1✔
3057
        }
3058
        return result;
1✔
3059
    }
3060

3061
    public static Map<String, Object> replaceNullWithEmptyValue(Map<String, Object> map) {
3062
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3063
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3064
            outMap.put(
1✔
3065
                    entry.getKey(),
1✔
3066
                    entry.getValue() == null
1✔
3067
                            ? newLinkedHashMap()
1✔
3068
                            : makeReplaceNullValue(entry.getValue()));
1✔
3069
        }
1✔
3070
        return outMap;
1✔
3071
    }
3072

3073
    @SuppressWarnings("unchecked")
3074
    private static Object makeReplaceNullValue(Object value) {
3075
        final Object result;
3076
        if (value instanceof List) {
1✔
3077
            List<Object> values = newArrayList();
1✔
3078
            for (Object item : (List) value) {
1✔
3079
                values.add(item instanceof Map ? replaceNullWithEmptyValue((Map) item) : item);
1✔
3080
            }
1✔
3081
            result = values;
1✔
3082
        } else if (value instanceof Map) {
1✔
3083
            result = replaceNullWithEmptyValue((Map) value);
1✔
3084
        } else {
3085
            result = value;
1✔
3086
        }
3087
        return result;
1✔
3088
    }
3089

3090
    public static Map<String, Object> replaceEmptyStringWithEmptyValue(Map<String, Object> map) {
3091
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3092
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3093
            outMap.put(
1✔
3094
                    entry.getKey(),
1✔
3095
                    "".equals(entry.getValue())
1✔
3096
                            ? newLinkedHashMap()
1✔
3097
                            : makeReplaceEmptyString(entry.getValue()));
1✔
3098
        }
1✔
3099
        return outMap;
1✔
3100
    }
3101

3102
    @SuppressWarnings("unchecked")
3103
    private static Object makeReplaceEmptyString(Object value) {
3104
        final Object result;
3105
        if (value instanceof List) {
1✔
3106
            List<Object> values = newArrayList();
1✔
3107
            for (Object item : (List) value) {
1✔
3108
                values.add(
1✔
3109
                        item instanceof Map ? replaceEmptyStringWithEmptyValue((Map) item) : item);
1✔
3110
            }
1✔
3111
            result = values;
1✔
3112
        } else if (value instanceof Map) {
1✔
3113
            result = replaceEmptyStringWithEmptyValue((Map) value);
1✔
3114
        } else {
3115
            result = value;
1✔
3116
        }
3117
        return result;
1✔
3118
    }
3119

3120
    public static Map<String, Object> replaceNumberAndBooleanWithString(Map<String, Object> map) {
3121
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3122
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3123
            outMap.put(
1✔
3124
                    entry.getKey(),
1✔
3125
                    entry.getValue() instanceof Boolean || entry.getValue() instanceof Number
1✔
3126
                            ? String.valueOf(entry.getValue())
1✔
3127
                            : makeReplaceNumberAndBoolean(entry.getValue()));
1✔
3128
        }
1✔
3129
        return outMap;
1✔
3130
    }
3131

3132
    @SuppressWarnings("unchecked")
3133
    private static Object makeReplaceNumberAndBoolean(Object value) {
3134
        final Object result;
3135
        if (value instanceof List) {
1✔
3136
            List<Object> values = newArrayList();
1✔
3137
            for (Object item : (List) value) {
1✔
3138
                if (item instanceof Map) {
1✔
3139
                    values.add(replaceNumberAndBooleanWithString((Map) item));
1✔
3140
                } else if (item instanceof Number || item instanceof Boolean || isNull(item)) {
1✔
3141
                    values.add(String.valueOf(item));
1✔
3142
                } else {
3143
                    values.add(item);
1✔
3144
                }
3145
            }
1✔
3146
            result = values;
1✔
3147
        } else if (value instanceof Map) {
1✔
3148
            result = replaceNumberAndBooleanWithString((Map) value);
1✔
3149
        } else if (isNull(value)) {
1✔
3150
            result = "null";
1✔
3151
        } else {
3152
            result = value;
1✔
3153
        }
3154
        return result;
1✔
3155
    }
3156

3157
    public static Map<String, Object> replaceFirstLevel(Map<String, Object> map) {
3158
        return replaceFirstLevel(map, 0);
1✔
3159
    }
3160

3161
    @SuppressWarnings("unchecked")
3162
    public static Map<String, Object> replaceFirstLevel(Map<String, Object> map, int level) {
3163
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3164
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3165
            outMap.put(entry.getKey(), makeReplaceFirstLevel(entry.getValue(), level + 1));
1✔
3166
        }
1✔
3167
        if (level == 0 && Xml.XmlValue.getMapValue(outMap) instanceof Map) {
1✔
3168
            Map<String, Object> outMap2 = (Map<String, Object>) Xml.XmlValue.getMapValue(outMap);
1✔
3169
            if (selfClosing.equals(Xml.XmlValue.getMapKey(outMap2))
1✔
3170
                    && "true".equals(Xml.XmlValue.getMapValue(outMap2))) {
1✔
3171
                outMap2.remove(selfClosing);
1✔
3172
            }
3173
            return outMap2;
1✔
3174
        }
3175
        return outMap;
1✔
3176
    }
3177

3178
    @SuppressWarnings("unchecked")
3179
    private static Object makeReplaceFirstLevel(Object value, int level) {
3180
        final Object result;
3181
        if (value instanceof List) {
1✔
3182
            List<Object> values = newArrayList();
1✔
3183
            for (Object item : (List) value) {
1✔
3184
                values.add(item instanceof Map ? replaceFirstLevel((Map) item, level + 1) : item);
1✔
3185
            }
1✔
3186
            result = values;
1✔
3187
        } else if (value instanceof Map) {
1✔
3188
            result = replaceFirstLevel((Map) value, level + 1);
1✔
3189
        } else {
3190
            result = value;
1✔
3191
        }
3192
        return result;
1✔
3193
    }
3194

3195
    public static Map<String, Object> replaceNilWithNull(Map<String, Object> map) {
3196
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3197
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3198
            Object outValue = makeReplaceNilWithNull(entry.getValue());
1✔
3199
            if (outValue instanceof Map
1✔
3200
                    && (nilKey.equals(Xml.XmlValue.getMapKey(outValue))
1✔
3201
                            || Xml.XmlValue.getMapKey(outValue).endsWith(":nil"))
1✔
3202
                    && "true".equals(Xml.XmlValue.getMapValue(outValue))
1✔
3203
                    && ((Map) outValue).containsKey(selfClosing)
1✔
3204
                    && "true".equals(((Map) outValue).get(selfClosing))) {
1✔
3205
                outValue = null;
1✔
3206
            }
3207
            outMap.put(entry.getKey(), outValue);
1✔
3208
        }
1✔
3209
        return outMap;
1✔
3210
    }
3211

3212
    @SuppressWarnings("unchecked")
3213
    private static Object makeReplaceNilWithNull(Object value) {
3214
        final Object result;
3215
        if (value instanceof List) {
1✔
3216
            List<Object> values = newArrayList();
1✔
3217
            for (Object item : (List) value) {
1✔
3218
                values.add(item instanceof Map ? replaceNilWithNull((Map) item) : item);
1✔
3219
            }
1✔
3220
            result = values;
1✔
3221
        } else if (value instanceof Map) {
1✔
3222
            result = replaceNilWithNull((Map) value);
1✔
3223
        } else {
3224
            result = value;
1✔
3225
        }
3226
        return result;
1✔
3227
    }
3228

3229
    public static Map<String, Object> deepCopyMap(Map<String, Object> map) {
3230
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3231
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3232
            outMap.put(entry.getKey(), makeDeepCopyMap(entry.getValue()));
1✔
3233
        }
1✔
3234
        return outMap;
1✔
3235
    }
3236

3237
    @SuppressWarnings("unchecked")
3238
    private static Object makeDeepCopyMap(Object value) {
3239
        final Object result;
3240
        if (value instanceof List) {
1✔
3241
            List<Object> values = newArrayList();
1✔
3242
            for (Object item : (List) value) {
1✔
3243
                values.add(item instanceof Map ? deepCopyMap((Map) item) : item);
1✔
3244
            }
1✔
3245
            result = values;
1✔
3246
        } else if (value instanceof Map) {
1✔
3247
            result = deepCopyMap((Map) value);
1✔
3248
        } else {
3249
            result = value;
1✔
3250
        }
3251
        return result;
1✔
3252
    }
3253

3254
    public static Builder objectBuilder() {
3255
        return new U.Builder();
1✔
3256
    }
3257

3258
    public static class Builder {
3259
        private final Map<String, Object> data;
3260

3261
        public Builder() {
1✔
3262
            data = newLinkedHashMap();
1✔
3263
        }
1✔
3264

3265
        public Builder add(final String key, final Object value) {
3266
            data.put(key, value);
1✔
3267
            return this;
1✔
3268
        }
3269

3270
        public Builder add(final Object value) {
3271
            data.put(String.valueOf(data.size()), value);
1✔
3272
            return this;
1✔
3273
        }
3274

3275
        public <T> T get(final String path) {
3276
            return U.get(data, path);
1✔
3277
        }
3278

3279
        public <T> T get(final List<String> paths) {
3280
            return U.get(data, paths);
1✔
3281
        }
3282

3283
        public Builder set(final String path, final Object value) {
3284
            U.set(data, path, value);
1✔
3285
            return this;
1✔
3286
        }
3287

3288
        public Builder set(final List<String> paths, final Object value) {
3289
            U.set(data, paths, value);
1✔
3290
            return this;
1✔
3291
        }
3292

3293
        public Builder remove(final String key) {
3294
            U.remove(data, key);
1✔
3295
            return this;
1✔
3296
        }
3297

3298
        public Builder remove(final List<String> keys) {
3299
            U.remove(data, keys);
1✔
3300
            return this;
1✔
3301
        }
3302

3303
        public Builder clear() {
3304
            data.clear();
1✔
3305
            return this;
1✔
3306
        }
3307

3308
        public boolean isEmpty() {
3309
            return data.isEmpty();
1✔
3310
        }
3311

3312
        public int size() {
3313
            return data.size();
1✔
3314
        }
3315

3316
        public Builder add(final Builder builder) {
3317
            data.put(String.valueOf(data.size()), builder.build());
1✔
3318
            return this;
1✔
3319
        }
3320

3321
        public Builder add(final String key, final ArrayBuilder builder) {
3322
            data.put(key, builder.build());
1✔
3323
            return this;
1✔
3324
        }
3325

3326
        public Builder add(final String key, final Builder builder) {
3327
            data.put(key, builder.build());
1✔
3328
            return this;
1✔
3329
        }
3330

3331
        public Builder add(final Map<String, Object> map) {
3332
            data.putAll(deepCopyMap(map));
1✔
3333
            return this;
1✔
3334
        }
3335

3336
        public Builder update(final Map<String, Object> map) {
3337
            U.update(data, deepCopyMap(map));
1✔
3338
            return this;
1✔
3339
        }
3340

3341
        public Builder addNull(final String key) {
3342
            data.put(key, null);
1✔
3343
            return this;
1✔
3344
        }
3345

3346
        @SuppressWarnings("unchecked")
3347
        public Map<String, Object> build() {
3348
            return (Map<String, Object>) ((LinkedHashMap) data).clone();
1✔
3349
        }
3350

3351
        public String toXml() {
3352
            return Xml.toXml(data);
1✔
3353
        }
3354

3355
        public static Builder fromXml(final String xml) {
3356
            final Builder builder = new Builder();
1✔
3357
            builder.data.putAll(fromXmlMap(xml));
1✔
3358
            return builder;
1✔
3359
        }
3360

3361
        public static Builder fromMap(final Map<String, Object> map) {
3362
            final Builder builder = new Builder();
1✔
3363
            builder.data.putAll(deepCopyMap(map));
1✔
3364
            return builder;
1✔
3365
        }
3366

3367
        public String toJson() {
3368
            return Json.toJson(data);
1✔
3369
        }
3370

3371
        public static Builder fromJson(final String json) {
3372
            final Builder builder = new Builder();
1✔
3373
            builder.data.putAll(fromJsonMap(json));
1✔
3374
            return builder;
1✔
3375
        }
3376

3377
        public Chain<Object> toChain() {
3378
            return new U.Chain<>(data.entrySet());
1✔
3379
        }
3380

3381
        @Override
3382
        public String toString() {
3383
            return data.toString();
1✔
3384
        }
3385
    }
3386

3387
    public static ArrayBuilder arrayBuilder() {
3388
        return new U.ArrayBuilder();
1✔
3389
    }
3390

3391
    public static class ArrayBuilder {
3392
        private final List<Object> data;
3393

3394
        public ArrayBuilder() {
1✔
3395
            data = newArrayList();
1✔
3396
        }
1✔
3397

3398
        public ArrayBuilder add(final Object value) {
3399
            data.add(value);
1✔
3400
            return this;
1✔
3401
        }
3402

3403
        public ArrayBuilder addNull() {
3404
            data.add(null);
1✔
3405
            return this;
1✔
3406
        }
3407

3408
        public <T> T get(final String path) {
3409
            return U.get(U.getStringObjectMap(data), "value." + path);
1✔
3410
        }
3411

3412
        public <T> T get(final List<String> paths) {
3413
            List<String> newPaths = new ArrayList<>();
1✔
3414
            newPaths.add("value");
1✔
3415
            newPaths.addAll(paths);
1✔
3416
            return U.get(U.getStringObjectMap(data), newPaths);
1✔
3417
        }
3418

3419
        public ArrayBuilder set(final int index, final Object value) {
3420
            data.set(index, value);
1✔
3421
            return this;
1✔
3422
        }
3423

3424
        public ArrayBuilder remove(final int index) {
3425
            data.remove(index);
1✔
3426
            return this;
1✔
3427
        }
3428

3429
        public ArrayBuilder clear() {
3430
            data.clear();
1✔
3431
            return this;
1✔
3432
        }
3433

3434
        public boolean isEmpty() {
3435
            return data.isEmpty();
1✔
3436
        }
3437

3438
        public int size() {
3439
            return data.size();
1✔
3440
        }
3441

3442
        public ArrayBuilder add(final ArrayBuilder builder) {
3443
            data.addAll(builder.build());
1✔
3444
            return this;
1✔
3445
        }
3446

3447
        public ArrayBuilder add(final Builder builder) {
3448
            data.add(builder.build());
1✔
3449
            return this;
1✔
3450
        }
3451

3452
        @SuppressWarnings("unchecked")
3453
        public ArrayBuilder merge(final List<Object> list) {
3454
            U.merge(data, (List<Object>) ((ArrayList) list).clone());
1✔
3455
            return this;
1✔
3456
        }
3457

3458
        @SuppressWarnings("unchecked")
3459
        public List<Object> build() {
3460
            return (List<Object>) ((ArrayList) data).clone();
1✔
3461
        }
3462

3463
        public String toXml() {
3464
            return Xml.toXml(data);
1✔
3465
        }
3466

3467
        public static ArrayBuilder fromXml(final String xml) {
3468
            final ArrayBuilder builder = new ArrayBuilder();
1✔
3469
            builder.data.addAll(U.<List<Object>>fromXml(xml));
1✔
3470
            return builder;
1✔
3471
        }
3472

3473
        public String toJson() {
3474
            return Json.toJson(data);
1✔
3475
        }
3476

3477
        public static ArrayBuilder fromJson(final String json) {
3478
            final ArrayBuilder builder = new ArrayBuilder();
1✔
3479
            builder.data.addAll(U.<List<Object>>fromJson(json));
1✔
3480
            return builder;
1✔
3481
        }
3482

3483
        public Chain<Object> toChain() {
3484
            return new U.Chain<>(data);
1✔
3485
        }
3486

3487
        @Override
3488
        public String toString() {
3489
            return data.toString();
1✔
3490
        }
3491
    }
3492
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc