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

javadev / underscore-java / #3210

pending completion
#3210

push

web-flow
Bump maven-project-info-reports-plugin from 3.4.4 to 3.4.5

4359 of 4359 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> xmlToJson() {
867
            return new Chain<>(U.xmlToJson((String) item()));
1✔
868
        }
869

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

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

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

883
    public static Chain<Map<String, Object>> chain(final Map<String, Object> map) {
884
        return new U.Chain<>(map);
1✔
885
    }
886

887
    public static <T> Chain<T> chain(final Iterable<T> iterable) {
888
        return new U.Chain<>(newArrayList(iterable));
1✔
889
    }
890

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

895
    @SuppressWarnings("unchecked")
896
    public static <T> Chain<T> chain(final T... list) {
897
        return new U.Chain<>(Arrays.asList(list));
1✔
898
    }
899

900
    public static Chain<Integer> chain(final int[] array) {
901
        return new U.Chain<>(newIntegerList(array));
1✔
902
    }
903

904
    @Override
905
    public Chain<T> chain() {
906
        return new U.Chain<>(newArrayList(value()));
1✔
907
    }
908

909
    public static Chain<String> of(final String item) {
910
        return new U.Chain<>(item);
1✔
911
    }
912

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

917
    public static Chain<Map<String, Object>> of(final Map<String, Object> map) {
918
        return new U.Chain<>(map);
1✔
919
    }
920

921
    public static <T> Chain<T> of(final Iterable<T> iterable) {
922
        return new U.Chain<>(newArrayList(iterable));
1✔
923
    }
924

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

929
    @SuppressWarnings("unchecked")
930
    public static <T> Chain<T> of(final T... list) {
931
        return new U.Chain<>(Arrays.asList(list));
1✔
932
    }
933

934
    public static Chain<Integer> of(final int[] array) {
935
        return new U.Chain<>(newIntegerList(array));
1✔
936
    }
937

938
    @Override
939
    public Chain<T> of() {
940
        return new U.Chain<>(newArrayList(value()));
1✔
941
    }
942

943
    public static <T> List<T> drop(final Iterable<T> iterable) {
944
        return rest(newArrayList(iterable));
1✔
945
    }
946

947
    public List<T> drop() {
948
        return drop(getIterable());
1✔
949
    }
950

951
    public static <T> List<T> drop(final Iterable<T> iterable, final Integer n) {
952
        return rest(newArrayList(iterable), n);
1✔
953
    }
954

955
    public List<T> drop(final Integer n) {
956
        return drop(getIterable(), n);
1✔
957
    }
958

959
    public static <T> List<T> dropRight(final Iterable<T> iterable) {
960
        return initial(newArrayList(iterable));
1✔
961
    }
962

963
    public List<T> dropRight() {
964
        return dropRight(getIterable());
1✔
965
    }
966

967
    public static <T> List<T> dropRight(final Iterable<T> iterable, final Integer n) {
968
        return initial(newArrayList(iterable), n);
1✔
969
    }
970

971
    public List<T> dropRight(final Integer n) {
972
        return dropRight(getIterable(), n);
1✔
973
    }
974

975
    public static <T> List<T> dropWhile(final Iterable<T> iterable, final Predicate<T> pred) {
976
        return rest(newArrayList(iterable), findIndex(newArrayList(iterable), negate(pred)));
1✔
977
    }
978

979
    public List<T> dropWhile(final Predicate<T> pred) {
980
        return dropWhile(getIterable(), pred);
1✔
981
    }
982

983
    public static <T> List<T> dropRightWhile(final Iterable<T> iterable, final Predicate<T> pred) {
984
        return reverse(dropWhile(reverse(iterable), pred));
1✔
985
    }
986

987
    public List<T> dropRightWhile(final Predicate<T> pred) {
988
        return dropRightWhile(getIterable(), pred);
1✔
989
    }
990

991
    public static <T> List<T> fill(List<T> list, T item) {
992
        for (int i = 0; i < size(list); i++) {
1✔
993
            list.set(i, item);
1✔
994
        }
995
        return list;
1✔
996
    }
997

998
    public static <T> T[] fill(T[] array, T item) {
999
        Arrays.fill(array, item);
1✔
1000
        return array;
1✔
1001
    }
1002

1003
    @SuppressWarnings("unchecked")
1004
    public List<Object> fill(Object value) {
1005
        return fill((List<Object>) getIterable(), value);
1✔
1006
    }
1007

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

1016
    @SuppressWarnings("unchecked")
1017
    public List<Object> fill(Object value, Integer start, Integer end) {
1018
        return fill((List<Object>) getIterable(), value, start, end);
1✔
1019
    }
1020

1021
    public static <E> List<E> flattenDeep(final List<?> list) {
1022
        return flatten(list, false);
1✔
1023
    }
1024

1025
    public List<T> flattenDeep() {
1026
        return flattenDeep((List<?>) getIterable());
1✔
1027
    }
1028

1029
    public static List<Object> pull(final List<Object> list, Object... values) {
1030
        final List<Object> valuesList = Arrays.asList(values);
1✔
1031
        list.removeIf(valuesList::contains);
1✔
1032
        return list;
1✔
1033
    }
1034

1035
    @SuppressWarnings("unchecked")
1036
    public List<Object> pull(Object... values) {
1037
        return pull((List<Object>) getIterable(), values);
1✔
1038
    }
1039

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

1055
    @SuppressWarnings("unchecked")
1056
    public List<Object> pullAt(final Integer... indexes) {
1057
        return pullAt((List<Object>) getIterable(), indexes);
1✔
1058
    }
1059

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

1072
    public List<T> remove(final Predicate<T> pred) {
1073
        return remove((List<T>) getIterable(), pred);
1✔
1074
    }
1075

1076
    public static <T> List<T> take(final Iterable<T> iterable) {
1077
        return first(newArrayList(iterable), 1);
1✔
1078
    }
1079

1080
    public List<T> take() {
1081
        return take(getIterable());
1✔
1082
    }
1083

1084
    public static <T> List<T> takeRight(final Iterable<T> iterable) {
1085
        return last(newArrayList(iterable), 1);
1✔
1086
    }
1087

1088
    public List<T> takeRight() {
1089
        return takeRight(getIterable());
1✔
1090
    }
1091

1092
    public static <T> List<T> take(final Iterable<T> iterable, final Integer n) {
1093
        return first(newArrayList(iterable), n);
1✔
1094
    }
1095

1096
    public List<T> take(final Integer n) {
1097
        return take(getIterable(), n);
1✔
1098
    }
1099

1100
    public static <T> List<T> takeRight(final Iterable<T> iterable, final Integer n) {
1101
        return last(newArrayList(iterable), n);
1✔
1102
    }
1103

1104
    public List<T> takeRight(final Integer n) {
1105
        return takeRight(getIterable(), n);
1✔
1106
    }
1107

1108
    public static <T> List<T> takeWhile(final Iterable<T> iterable, final Predicate<T> pred) {
1109
        return first(newArrayList(iterable), findIndex(newArrayList(iterable), negate(pred)));
1✔
1110
    }
1111

1112
    public List<T> takeWhile(final Predicate<T> pred) {
1113
        return takeWhile(getIterable(), pred);
1✔
1114
    }
1115

1116
    public static <T> List<T> takeRightWhile(final Iterable<T> iterable, final Predicate<T> pred) {
1117
        return reverse(takeWhile(reverse(iterable), pred));
1✔
1118
    }
1119

1120
    public List<T> takeRightWhile(final Predicate<T> pred) {
1121
        return takeRightWhile(getIterable(), pred);
1✔
1122
    }
1123

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

1139
    @SuppressWarnings("unchecked")
1140
    public List<T> xor(final List<T> list) {
1141
        return xor((List<T>) getIterable(), list);
1✔
1142
    }
1143

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

1157
    public List<T> at(final Integer... indexes) {
1158
        return at((List<T>) getIterable(), indexes);
1✔
1159
    }
1160

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

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

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

1186
    public static Double average(java.math.BigDecimal first, java.math.BigDecimal second) {
1187
        if (first == null || second == null) {
1✔
1188
            return null;
1✔
1189
        }
1190
        return sum(first, second).doubleValue() / 2;
1✔
1191
    }
1192

1193
    public static Double average(java.math.BigInteger first, java.math.BigInteger second) {
1194
        if (first == null || second == null) {
1✔
1195
            return null;
1✔
1196
        }
1197
        return sum(first, second).doubleValue() / 2;
1✔
1198
    }
1199

1200
    public static Double average(Byte first, Byte second) {
1201
        if (first == null || second == null) {
1✔
1202
            return null;
1✔
1203
        }
1204
        return sum(first, second).doubleValue() / 2;
1✔
1205
    }
1206

1207
    public static Double average(Double first, Double second) {
1208
        if (first == null || second == null) {
1✔
1209
            return null;
1✔
1210
        }
1211
        return sum(first, second) / 2;
1✔
1212
    }
1213

1214
    public static Double average(Float first, Float second) {
1215
        if (first == null || second == null) {
1✔
1216
            return null;
1✔
1217
        }
1218
        return sum(first, second).doubleValue() / 2;
1✔
1219
    }
1220

1221
    public static Double average(Integer first, Integer second) {
1222
        if (first == null || second == null) {
1✔
1223
            return null;
1✔
1224
        }
1225
        return sum(first, second).doubleValue() / 2;
1✔
1226
    }
1227

1228
    public static Double average(Long first, Long second) {
1229
        if (first == null || second == null) {
1✔
1230
            return null;
1✔
1231
        }
1232
        return sum(first, second).doubleValue() / 2;
1✔
1233
    }
1234

1235
    public static <T extends Number> T sum(final Iterable<T> iterable) {
1236
        T result = null;
1✔
1237
        for (final T item : iterable) {
1✔
1238
            result = add(result, item);
1✔
1239
        }
1✔
1240
        return result;
1✔
1241
    }
1242

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

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

1260
    @SuppressWarnings("unchecked")
1261
    public <F extends Number> F sum() {
1262
        return sum((List<F>) getIterable());
1✔
1263
    }
1264

1265
    @SuppressWarnings("unchecked")
1266
    public <E, F extends Number> F sum(final Function<E, F> func) {
1267
        return sum((List<E>) getIterable(), func);
1✔
1268
    }
1269

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

1298
    private static java.math.BigDecimal sum(
1299
            java.math.BigDecimal first, java.math.BigDecimal second) {
1300
        return first.add(second);
1✔
1301
    }
1302

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

1308
    private static Byte sum(Byte first, Byte second) {
1309
        return (byte) (first + second);
1✔
1310
    }
1311

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

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

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

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

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

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

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

1378
    @SuppressWarnings("unchecked")
1379
    public double mean() {
1380
        return mean((Iterable<Number>) getIterable());
1✔
1381
    }
1382

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

1396
    @SuppressWarnings("unchecked")
1397
    public double median() {
1398
        return median((Iterable<Number>) getIterable());
1✔
1399
    }
1400

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

1416
    public static String lowerFirst(final String string) {
1417
        return createCaseFirst("toLowerCase").apply(string);
1✔
1418
    }
1419

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

1424
    public static String capitalize(final String string) {
1425
        return upperFirst(baseToString(string));
1✔
1426
    }
1427

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

1432
    private static String baseToString(String value) {
1433
        return value == null ? "" : value;
1✔
1434
    }
1435

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

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

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

1467
            while (++index < length) {
1✔
1468
                result = callback.apply(result, array.get(index), index);
1✔
1469
            }
1470
            return result;
1✔
1471
        };
1472
    }
1473

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

1483
    public static boolean endsWith(final String string, final String target) {
1484
        return endsWith(string, target, null);
1✔
1485
    }
1486

1487
    public static boolean endsWith(
1488
            final String string, final String target, final Integer position) {
1489
        if (string == null || target == null) {
1✔
1490
            return false;
1✔
1491
        }
1492
        final String localString = baseToString(string);
1✔
1493

1494
        final int length = localString.length();
1✔
1495
        final int fixedPosition = position == null || position < 0 ? 0 : position;
1✔
1496
        final int localPosition = position == null ? length : Math.min(fixedPosition, length);
1✔
1497

1498
        final int localPosition2 = localPosition - target.length();
1✔
1499
        return localPosition2 >= 0 && localString.indexOf(target, localPosition2) == localPosition2;
1✔
1500
    }
1501

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

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

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

1536
    public static String pad(final String string, final int length) {
1537
        return pad(string, length, null);
1✔
1538
    }
1539

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

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

1563
    public static String padStart(final String string, final Integer length) {
1564
        return createPadDir(false).apply(string, length, null);
1✔
1565
    }
1566

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

1571
    public static String padEnd(final String string, final Integer length) {
1572
        return createPadDir(true).apply(string, length, null);
1✔
1573
    }
1574

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

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

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

1598
    public static boolean startsWith(final String string, final String target) {
1599
        return startsWith(string, target, null);
1✔
1600
    }
1601

1602
    public static boolean startsWith(
1603
            final String string, final String target, final Integer position) {
1604
        if (string == null || target == null) {
1✔
1605
            return false;
1✔
1606
        }
1607
        final String localString = baseToString(string);
1✔
1608

1609
        final int length = localString.length();
1✔
1610
        final int localPosition;
1611
        if (position == null) {
1✔
1612
            localPosition = 0;
1✔
1613
        } else {
1614
            final int from = position < 0 ? 0 : position;
1✔
1615
            localPosition = Math.min(from, length);
1✔
1616
        }
1617

1618
        return localString.lastIndexOf(target, localPosition) == localPosition;
1✔
1619
    }
1620

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

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

1638
    public static String trim(final String string) {
1639
        return trim(string, null);
1✔
1640
    }
1641

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

1658
    public static String trimStart(final String string) {
1659
        return trimStart(string, null);
1✔
1660
    }
1661

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

1677
    public static String trimEnd(final String string) {
1678
        return trimEnd(string, null);
1✔
1679
    }
1680

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

1696
    public static String trunc(final String string) {
1697
        return trunc(string, DEFAULT_TRUNC_LENGTH);
1✔
1698
    }
1699

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

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

1720
    private enum OperationType {
1✔
1721
        GET,
1✔
1722
        SET,
1✔
1723
        UPDATE,
1✔
1724
        REMOVE
1✔
1725
    }
1726

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

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

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

1784
    private static void checkSetOrUpdate(
1785
            Object value,
1786
            OperationType operationType,
1787
            Map<String, Object> savedLocalObject,
1788
            String savedPath) {
1789
        if (operationType == OperationType.UPDATE && savedLocalObject.containsKey(savedPath)) {
1✔
1790
            savedLocalObject.put(Underscore.uniqueId(savedPath), value);
1✔
1791
        } else {
1792
            savedLocalObject.put(savedPath, value);
1✔
1793
        }
1794
    }
1✔
1795

1796
    private static Map.Entry getMapEntry(Map map) {
1797
        return map.isEmpty() ? null : (Map.Entry) map.entrySet().iterator().next();
1✔
1798
    }
1799

1800
    public static <T> T get(final Map<String, Object> object, final String path) {
1801
        return get(object, stringToPath(path));
1✔
1802
    }
1803

1804
    public static <T> T get(final Map<String, Object> object, final List<String> paths) {
1805
        return baseGetOrSetOrRemove(object, paths, null, OperationType.GET);
1✔
1806
    }
1807

1808
    public static String selectToken(final Map<String, Object> object, final String expression) {
1809
        final String xml = toXml(object);
1✔
1810
        try {
1811
            final XPath xPath = XPathFactory.newInstance().newXPath();
1✔
1812
            final org.w3c.dom.Document document = Xml.Document.createDocument(xml);
1✔
1813
            final NodeList nodes =
1✔
1814
                    (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET);
1✔
1815
            if (nodes.getLength() == 0) {
1✔
1816
                return null;
1✔
1817
            }
1818
            return nodes.item(0).getNodeValue();
1✔
1819
        } catch (Exception ex) {
1✔
1820
            throw new IllegalArgumentException(ex);
1✔
1821
        }
1822
    }
1823

1824
    public static List<String> selectTokens(
1825
            final Map<String, Object> object, final String expression) {
1826
        final String xml = toXml(object);
1✔
1827
        try {
1828
            final XPath xPath = XPathFactory.newInstance().newXPath();
1✔
1829
            final org.w3c.dom.Document document = Xml.Document.createDocument(xml);
1✔
1830
            final NodeList nodes =
1✔
1831
                    (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET);
1✔
1832
            final List<String> result = new ArrayList<>();
1✔
1833
            for (int i = 0; i < nodes.getLength(); i++) {
1✔
1834
                result.add(nodes.item(i).getNodeValue());
1✔
1835
            }
1836
            return result;
1✔
1837
        } catch (Exception ex) {
1✔
1838
            throw new IllegalArgumentException(ex);
1✔
1839
        }
1840
    }
1841

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

1846
    public static <T> T set(
1847
            final Map<String, Object> object, final List<String> paths, Object value) {
1848
        return baseGetOrSetOrRemove(object, paths, value, OperationType.SET);
1✔
1849
    }
1850

1851
    public static <T> T update(final Map<String, Object> object, final String path, Object value) {
1852
        return update(object, stringToPath(path), value);
1✔
1853
    }
1854

1855
    public static <T> T update(
1856
            final Map<String, Object> object, final List<String> paths, Object value) {
1857
        return baseGetOrSetOrRemove(object, paths, value, OperationType.UPDATE);
1✔
1858
    }
1859

1860
    public static <T> T remove(final Map<String, Object> object, final String path) {
1861
        return remove(object, stringToPath(path));
1✔
1862
    }
1863

1864
    public static <T> T remove(final Map<String, Object> object, final List<String> paths) {
1865
        return baseGetOrSetOrRemove(object, paths, null, OperationType.REMOVE);
1✔
1866
    }
1867

1868
    public static Map<String, Object> rename(
1869
            final Map<String, Object> map, final String oldKey, final String newKey) {
1870
        Map<String, Object> outMap = newLinkedHashMap();
1✔
1871
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
1872
            if (entry.getKey().equals(oldKey)) {
1✔
1873
                outMap.put(newKey, makeObjectForRename(entry.getValue(), oldKey, newKey));
1✔
1874
            } else {
1875
                outMap.put(entry.getKey(), makeObjectForRename(entry.getValue(), oldKey, newKey));
1✔
1876
            }
1877
        }
1✔
1878
        return outMap;
1✔
1879
    }
1880

1881
    @SuppressWarnings("unchecked")
1882
    private static Object makeObjectForRename(
1883
            Object value, final String oldKey, final String newKey) {
1884
        final Object result;
1885
        if (value instanceof List) {
1✔
1886
            List<Object> values = newArrayList();
1✔
1887
            for (Object item : (List) value) {
1✔
1888
                values.add(
1✔
1889
                        item instanceof Map
1✔
1890
                                ? rename((Map<String, Object>) item, oldKey, newKey)
1✔
1891
                                : item);
1✔
1892
            }
1✔
1893
            result = values;
1✔
1894
        } else if (value instanceof Map) {
1✔
1895
            result = rename((Map<String, Object>) value, oldKey, newKey);
1✔
1896
        } else {
1897
            result = value;
1✔
1898
        }
1899
        return result;
1✔
1900
    }
1901

1902
    public static Map<String, Object> setValue(
1903
            final Map<String, Object> map, final String key, final Object newValue) {
1904
        return setValue(map, key, (key1, value) -> newValue);
1✔
1905
    }
1906

1907
    public static Map<String, Object> setValue(
1908
            final Map<String, Object> map,
1909
            final String key,
1910
            final BiFunction<String, Object, Object> newValue) {
1911
        Map<String, Object> outMap = newLinkedHashMap();
1✔
1912
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
1913
            if (entry.getKey().equals(key)) {
1✔
1914
                outMap.put(
1✔
1915
                        key,
1916
                        makeObjectForSetValue(
1✔
1917
                                newValue.apply(key, entry.getValue()), key, newValue));
1✔
1918
            } else {
1919
                outMap.put(entry.getKey(), makeObjectForSetValue(entry.getValue(), key, newValue));
1✔
1920
            }
1921
        }
1✔
1922
        return outMap;
1✔
1923
    }
1924

1925
    @SuppressWarnings("unchecked")
1926
    private static Object makeObjectForSetValue(
1927
            Object value, final String key, final BiFunction<String, Object, Object> newValue) {
1928
        final Object result;
1929
        if (value instanceof List) {
1✔
1930
            List<Object> values = newArrayList();
1✔
1931
            for (Object item : (List) value) {
1✔
1932
                values.add(
1✔
1933
                        item instanceof Map
1✔
1934
                                ? setValue((Map<String, Object>) item, key, newValue)
1✔
1935
                                : item);
1✔
1936
            }
1✔
1937
            result = values;
1✔
1938
        } else if (value instanceof Map) {
1✔
1939
            result = setValue((Map<String, Object>) value, key, newValue);
1✔
1940
        } else {
1941
            result = value;
1✔
1942
        }
1943
        return result;
1✔
1944
    }
1945

1946
    public static Map<String, Object> update(
1947
            final Map<String, Object> map1, final Map<String, Object> map2) {
1948
        Map<String, Object> outMap = newLinkedHashMap();
1✔
1949
        for (Map.Entry<String, Object> entry : map1.entrySet()) {
1✔
1950
            String key = entry.getKey();
1✔
1951
            Object value2 = entry.getValue();
1✔
1952
            if (map2.containsKey(key)) {
1✔
1953
                createKey(map2, key, value2, outMap);
1✔
1954
            } else {
1955
                outMap.put(key, value2);
1✔
1956
            }
1957
        }
1✔
1958
        for (Map.Entry<String, Object> entry : map2.entrySet()) {
1✔
1959
            String key = entry.getKey();
1✔
1960
            Object value2 = entry.getValue();
1✔
1961
            if (map1.containsKey(key)) {
1✔
1962
                createKey(map1, key, value2, outMap);
1✔
1963
            } else {
1964
                outMap.put(key, value2);
1✔
1965
            }
1966
        }
1✔
1967
        return outMap;
1✔
1968
    }
1969

1970
    @SuppressWarnings("unchecked")
1971
    private static void createKey(
1972
            final Map<String, Object> map, String key, Object value2, Map<String, Object> outMap) {
1973
        Object value1 = map.get(key);
1✔
1974
        if (value1 instanceof Map && value2 instanceof Map) {
1✔
1975
            outMap.put(key, update((Map<String, Object>) value1, (Map<String, Object>) value2));
1✔
1976
        } else if (value1 instanceof List && value2 instanceof List) {
1✔
1977
            outMap.put(key, merge((List<Object>) value1, (List<Object>) value2));
1✔
1978
        } else if (value1 instanceof List) {
1✔
1979
            outMap.put(key, merge((List<Object>) value1, newArrayList(value2)));
1✔
1980
        } else if (value2 instanceof List) {
1✔
1981
            outMap.put(key, merge(newArrayList(value1), (List<Object>) value2));
1✔
1982
        } else {
1983
            outMap.put(key, value2);
1✔
1984
        }
1985
    }
1✔
1986

1987
    public static List<Object> merge(List<Object> list1, List<Object> list2) {
1988
        List<Object> outList1 = newArrayList(list1);
1✔
1989
        List<Object> outList2 = newArrayList(list2);
1✔
1990
        outList2.removeAll(list1);
1✔
1991
        outList1.addAll(outList2);
1✔
1992
        return outList1;
1✔
1993
    }
1994

1995
    public static class FetchResponse {
1996
        private final boolean ok;
1997
        private final int status;
1998
        private final Map<String, List<String>> headerFields;
1999
        private final java.io.ByteArrayOutputStream stream;
2000

2001
        public FetchResponse(
2002
                final boolean ok,
2003
                final int status,
2004
                final Map<String, List<String>> headerFields,
2005
                final java.io.ByteArrayOutputStream stream) {
1✔
2006
            this.ok = ok;
1✔
2007
            this.status = status;
1✔
2008
            this.stream = stream;
1✔
2009
            this.headerFields = headerFields;
1✔
2010
        }
1✔
2011

2012
        public boolean isOk() {
2013
            return ok;
1✔
2014
        }
2015

2016
        public int getStatus() {
2017
            return status;
1✔
2018
        }
2019

2020
        public Map<String, List<String>> getHeaderFields() {
2021
            return headerFields;
1✔
2022
        }
2023

2024
        public byte[] blob() {
2025
            return stream.toByteArray();
1✔
2026
        }
2027

2028
        public String text() {
2029
            return stream.toString(StandardCharsets.UTF_8);
1✔
2030
        }
2031

2032
        public Object json() {
2033
            return Json.fromJson(text());
1✔
2034
        }
2035

2036
        public Map<String, Object> jsonMap() {
2037
            return fromJsonMap(text());
1✔
2038
        }
2039

2040
        public Object xml() {
2041
            return Xml.fromXml(text());
1✔
2042
        }
2043

2044
        public Map<String, Object> xmlMap() {
2045
            return fromXmlMap(text());
1✔
2046
        }
2047
    }
2048

2049
    public static long downloadUrl(final String url, final String fileName)
2050
            throws IOException, URISyntaxException {
2051
        final URL website = new URI(url).toURL();
1✔
2052
        try (ReadableByteChannel rbc = Channels.newChannel(website.openStream());
1✔
2053
                final FileOutputStream fos = new FileOutputStream(fileName)) {
1✔
2054
            return fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
1✔
2055
        }
2056
    }
2057

2058
    public static void decompressGzip(final String sourceFileName, final String targetFileName)
2059
            throws IOException {
2060
        try (GZIPInputStream gis =
1✔
2061
                new GZIPInputStream(new FileInputStream(new File(sourceFileName)))) {
2062
            Files.copy(gis, Paths.get(targetFileName));
1✔
2063
        }
2064
    }
1✔
2065

2066
    public static FetchResponse fetch(final String url) {
2067
        return fetch(url, null, null, DEFAULT_HEADER_FIELDS, null, null);
1✔
2068
    }
2069

2070
    public static FetchResponse fetch(
2071
            final String url, final Integer connectTimeout, final Integer readTimeout) {
2072
        return fetch(url, null, null, DEFAULT_HEADER_FIELDS, connectTimeout, readTimeout);
1✔
2073
    }
2074

2075
    public static FetchResponse fetch(
2076
            final String url,
2077
            final Integer connectTimeout,
2078
            final Integer readTimeout,
2079
            final Integer retryCount,
2080
            final Integer timeBetweenRetry) {
2081
        return Fetch.fetch(
1✔
2082
                url,
2083
                null,
2084
                null,
2085
                DEFAULT_HEADER_FIELDS,
2086
                connectTimeout,
2087
                readTimeout,
2088
                retryCount,
2089
                timeBetweenRetry);
2090
    }
2091

2092
    public static FetchResponse fetch(final String url, final String method, final String body) {
2093
        return fetch(url, method, body, DEFAULT_HEADER_FIELDS, null, null);
1✔
2094
    }
2095

2096
    public static class BaseHttpSslSocketFactory extends javax.net.ssl.SSLSocketFactory {
2097
        private javax.net.ssl.SSLContext getSslContext() {
2098
            return createEasySslContext();
2099
        }
2100

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

2108
        @Override
2109
        public java.net.Socket createSocket(
2110
                String arg0, int arg1, java.net.InetAddress arg2, int arg3)
2111
                throws java.io.IOException {
2112
            return getSslContext().getSocketFactory().createSocket(arg0, arg1, arg2, arg3);
2113
        }
2114

2115
        @Override
2116
        public java.net.Socket createSocket(java.net.InetAddress arg0, int arg1)
2117
                throws java.io.IOException {
2118
            return getSslContext().getSocketFactory().createSocket(arg0, arg1);
2119
        }
2120

2121
        @Override
2122
        public java.net.Socket createSocket(String arg0, int arg1) throws java.io.IOException {
2123
            return getSslContext().getSocketFactory().createSocket(arg0, arg1);
2124
        }
2125

2126
        @Override
2127
        public String[] getSupportedCipherSuites() {
2128
            return new String[] {};
2129
        }
2130

2131
        @Override
2132
        public String[] getDefaultCipherSuites() {
2133
            return new String[] {};
2134
        }
2135

2136
        @Override
2137
        public java.net.Socket createSocket(
2138
                java.net.Socket arg0, String arg1, int arg2, boolean arg3)
2139
                throws java.io.IOException {
2140
            return getSslContext().getSocketFactory().createSocket(arg0, arg1, arg2, arg3);
2141
        }
2142

2143
        private javax.net.ssl.SSLContext createEasySslContext() {
2144
            try {
2145
                javax.net.ssl.SSLContext context = javax.net.ssl.SSLContext.getInstance("SSL");
2146
                context.init(
2147
                        null, new javax.net.ssl.TrustManager[] {MyX509TrustManager.manger}, null);
2148
                return context;
2149
            } catch (Exception ex) {
2150
                throw new UnsupportedOperationException(ex);
2151
            }
2152
        }
2153

2154
        public static class MyX509TrustManager implements javax.net.ssl.X509TrustManager {
2155

2156
            static MyX509TrustManager manger = new MyX509TrustManager();
2157

2158
            public MyX509TrustManager() {
2159
                // ignore MyX509TrustManager
2160
            }
2161

2162
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
2163
                return new java.security.cert.X509Certificate[] {};
2164
            }
2165

2166
            public void checkClientTrusted(
2167
                    java.security.cert.X509Certificate[] chain, String authType) {
2168
                // ignore checkClientTrusted
2169
            }
2170

2171
            public void checkServerTrusted(
2172
                    java.security.cert.X509Certificate[] chain, String authType) {
2173
                // ignore checkServerTrusted
2174
            }
2175
        }
2176
    }
2177

2178
    public static void setupConnection(
2179
            final java.net.HttpURLConnection connection,
2180
            final String method,
2181
            final Map<String, List<String>> headerFields,
2182
            final Integer connectTimeout,
2183
            final Integer readTimeout)
2184
            throws java.io.IOException {
2185
        final String localMethod;
2186
        if (SUPPORTED_HTTP_METHODS.contains(method)) {
1✔
2187
            localMethod = method;
1✔
2188
        } else {
2189
            localMethod = "GET";
1✔
2190
        }
2191
        connection.setRequestMethod(localMethod);
1✔
2192
        if (connectTimeout != null) {
1✔
2193
            connection.setConnectTimeout(connectTimeout);
1✔
2194
        }
2195
        if (readTimeout != null) {
1✔
2196
            connection.setReadTimeout(readTimeout);
1✔
2197
        }
2198
        if (connection instanceof javax.net.ssl.HttpsURLConnection) {
1✔
2199
            ((javax.net.ssl.HttpsURLConnection) connection)
1✔
2200
                    .setSSLSocketFactory(new BaseHttpSslSocketFactory());
1✔
2201
        }
2202
        if (headerFields != null) {
1✔
2203
            for (final Map.Entry<String, List<String>> header : headerFields.entrySet()) {
1✔
2204
                connection.setRequestProperty(header.getKey(), join(header.getValue(), ";"));
1✔
2205
            }
1✔
2206
        }
2207
    }
1✔
2208

2209
    public static FetchResponse fetch(
2210
            final String url,
2211
            final String method,
2212
            final String body,
2213
            final Map<String, List<String>> headerFields,
2214
            final Integer connectTimeout,
2215
            final Integer readTimeout) {
2216
        try {
2217
            final java.net.URL localUrl = new java.net.URI(url).toURL();
1✔
2218
            final java.net.HttpURLConnection connection =
1✔
2219
                    (java.net.HttpURLConnection) localUrl.openConnection();
1✔
2220
            setupConnection(connection, method, headerFields, connectTimeout, readTimeout);
1✔
2221
            if (body != null) {
1✔
2222
                connection.setDoOutput(true);
1✔
2223
                final java.io.DataOutputStream outputStream =
1✔
2224
                        new java.io.DataOutputStream(connection.getOutputStream());
1✔
2225
                outputStream.write(body.getBytes(StandardCharsets.UTF_8));
1✔
2226
                outputStream.close();
1✔
2227
            }
2228
            final int responseCode = connection.getResponseCode();
1✔
2229
            final java.io.InputStream inputStream;
2230
            if (responseCode < RESPONSE_CODE_400) {
1✔
2231
                inputStream = connection.getInputStream();
1✔
2232
            } else {
2233
                inputStream = connection.getErrorStream();
1✔
2234
            }
2235
            final java.io.ByteArrayOutputStream result = new java.io.ByteArrayOutputStream();
1✔
2236
            final byte[] buffer = new byte[BUFFER_LENGTH_1024];
1✔
2237
            int length;
2238
            while ((length = inputStream.read(buffer)) != -1) {
1✔
2239
                result.write(buffer, 0, length);
1✔
2240
            }
2241
            inputStream.close();
1✔
2242
            return new FetchResponse(
1✔
2243
                    responseCode < RESPONSE_CODE_400,
2244
                    responseCode,
2245
                    connection.getHeaderFields(),
1✔
2246
                    result);
2247
        } catch (java.io.IOException | java.net.URISyntaxException ex) {
1✔
2248
            throw new UnsupportedOperationException(ex);
1✔
2249
        }
2250
    }
2251

2252
    public static class Fetch {
2253
        private Fetch() {}
2254

2255
        @SuppressWarnings("java:S107")
2256
        public static FetchResponse fetch(
2257
                final String url,
2258
                final String method,
2259
                final String body,
2260
                final Map<String, List<String>> headerFields,
2261
                final Integer connectTimeout,
2262
                final Integer readTimeout,
2263
                final Integer retryCount,
2264
                final Integer timeBetweenRetry) {
2265
            if (nonNull(retryCount)
2266
                    && retryCount > 0
2267
                    && retryCount <= 10
2268
                    && nonNull(timeBetweenRetry)
2269
                    && timeBetweenRetry > 0) {
2270
                int localRetryCount = 0;
2271
                UnsupportedOperationException saveException;
2272
                do {
2273
                    try {
2274
                        final FetchResponse fetchResponse =
2275
                                U.fetch(
2276
                                        url,
2277
                                        method,
2278
                                        body,
2279
                                        headerFields,
2280
                                        connectTimeout,
2281
                                        readTimeout);
2282
                        if (fetchResponse.getStatus() == 429) {
2283
                            saveException = new UnsupportedOperationException("Too Many Requests");
2284
                        } else {
2285
                            return fetchResponse;
2286
                        }
2287
                    } catch (UnsupportedOperationException ex) {
2288
                        saveException = ex;
2289
                    }
2290
                    localRetryCount += 1;
2291
                    try {
2292
                        java.util.concurrent.TimeUnit.MILLISECONDS.sleep(timeBetweenRetry);
2293
                    } catch (InterruptedException ex) {
2294
                        saveException = new UnsupportedOperationException(ex);
2295
                        Thread.currentThread().interrupt();
2296
                    }
2297
                } while (localRetryCount <= retryCount);
2298
                throw saveException;
2299
            }
2300
            return U.fetch(url, method, body, headerFields, connectTimeout, readTimeout);
2301
        }
2302
    }
2303

2304
    public static List<String> explode(final String input) {
2305
        List<String> result = newArrayList();
1✔
2306
        if (isNull(input)) {
1✔
2307
            return result;
1✔
2308
        }
2309
        for (char character : input.toCharArray()) {
1✔
2310
            result.add(String.valueOf(character));
1✔
2311
        }
2312
        return result;
1✔
2313
    }
2314

2315
    public static String implode(final String[] input) {
2316
        StringBuilder builder = new StringBuilder();
1✔
2317
        for (String character : input) {
1✔
2318
            if (nonNull(character)) {
1✔
2319
                builder.append(character);
1✔
2320
            }
2321
        }
2322
        return builder.toString();
1✔
2323
    }
2324

2325
    public static String implode(final Iterable<String> input) {
2326
        StringBuilder builder = new StringBuilder();
1✔
2327
        for (String character : input) {
1✔
2328
            if (nonNull(character)) {
1✔
2329
                builder.append(character);
1✔
2330
            }
2331
        }
1✔
2332
        return builder.toString();
1✔
2333
    }
2334

2335
    public String camelCase() {
2336
        return camelCase(getString().get());
1✔
2337
    }
2338

2339
    public String lowerFirst() {
2340
        return lowerFirst(getString().get());
1✔
2341
    }
2342

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

2347
    public String capitalize() {
2348
        return capitalize(getString().get());
1✔
2349
    }
2350

2351
    public String deburr() {
2352
        return deburr(getString().get());
1✔
2353
    }
2354

2355
    public boolean endsWith(final String target) {
2356
        return endsWith(getString().get(), target);
1✔
2357
    }
2358

2359
    public boolean endsWith(final String target, final Integer position) {
2360
        return endsWith(getString().get(), target, position);
1✔
2361
    }
2362

2363
    public String kebabCase() {
2364
        return kebabCase(getString().get());
1✔
2365
    }
2366

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

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

2375
    public String pad(final int length, final String chars) {
2376
        return pad(getString().get(), length, chars);
1✔
2377
    }
2378

2379
    public String padStart(final int length) {
2380
        return padStart(getString().get(), length);
1✔
2381
    }
2382

2383
    public String padStart(final int length, final String chars) {
2384
        return padStart(getString().get(), length, chars);
1✔
2385
    }
2386

2387
    public String padEnd(final int length) {
2388
        return padEnd(getString().get(), length);
1✔
2389
    }
2390

2391
    public String padEnd(final int length, final String chars) {
2392
        return padEnd(getString().get(), length, chars);
1✔
2393
    }
2394

2395
    public String snakeCase() {
2396
        return snakeCase(getString().get());
1✔
2397
    }
2398

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

2403
    public boolean startsWith(final String target) {
2404
        return startsWith(getString().get(), target);
1✔
2405
    }
2406

2407
    public boolean startsWith(final String target, final Integer position) {
2408
        return startsWith(getString().get(), target, position);
1✔
2409
    }
2410

2411
    public String trim() {
2412
        return trim(getString().get());
1✔
2413
    }
2414

2415
    public String trimWith(final String chars) {
2416
        return trim(getString().get(), chars);
1✔
2417
    }
2418

2419
    public String trimStart() {
2420
        return trimStart(getString().get());
1✔
2421
    }
2422

2423
    public String trimStartWith(final String chars) {
2424
        return trimStart(getString().get(), chars);
1✔
2425
    }
2426

2427
    public String trimEnd() {
2428
        return trimEnd(getString().get());
1✔
2429
    }
2430

2431
    public String trimEndWith(final String chars) {
2432
        return trimEnd(getString().get(), chars);
1✔
2433
    }
2434

2435
    public String trunc() {
2436
        return trunc(getString().get());
1✔
2437
    }
2438

2439
    public String trunc(final int length) {
2440
        return trunc(getString().get(), length);
1✔
2441
    }
2442

2443
    public String uncapitalize() {
2444
        return uncapitalize(getString().get());
1✔
2445
    }
2446

2447
    public List<String> words() {
2448
        return words(getString().get());
1✔
2449
    }
2450

2451
    public static class LruCache<K, V> {
2452
        private static final boolean SORT_BY_ACCESS = true;
2453
        private static final float LOAD_FACTOR = 0.75F;
2454
        private final Map<K, V> lruCacheMap;
2455
        private final int capacity;
2456

2457
        public LruCache(int capacity) {
1✔
2458
            this.capacity = capacity;
1✔
2459
            this.lruCacheMap = new LinkedHashMap<>(capacity, LOAD_FACTOR, SORT_BY_ACCESS);
1✔
2460
        }
1✔
2461

2462
        public V get(K key) {
2463
            return lruCacheMap.get(key);
1✔
2464
        }
2465

2466
        public void put(K key, V value) {
2467
            if (lruCacheMap.containsKey(key)) {
1✔
2468
                lruCacheMap.remove(key);
1✔
2469
            } else if (lruCacheMap.size() >= capacity) {
1✔
2470
                lruCacheMap.remove(lruCacheMap.keySet().iterator().next());
1✔
2471
            }
2472
            lruCacheMap.put(key, value);
1✔
2473
        }
1✔
2474
    }
2475

2476
    public static <K, V> LruCache<K, V> createLruCache(final int capacity) {
2477
        return new LruCache<>(capacity);
1✔
2478
    }
2479

2480
    public static <T> List<List<T>> createPermutationWithRepetition(
2481
            final List<T> list, final int permutationLength) {
2482
        final long resultSize = (long) Math.pow(list.size(), permutationLength);
1✔
2483
        final List<List<T>> result = new ArrayList<>((int) resultSize);
1✔
2484
        final int[] bitVector = new int[permutationLength];
1✔
2485
        for (int index = 0; index < resultSize; index += 1) {
1✔
2486
            List<T> result2 = new ArrayList<>(permutationLength);
1✔
2487
            for (int index2 = 0; index2 < permutationLength; index2 += 1) {
1✔
2488
                result2.add(list.get(bitVector[index2]));
1✔
2489
            }
2490
            int index3 = 0;
1✔
2491
            while (index3 < permutationLength && bitVector[index3] == list.size() - 1) {
1✔
2492
                bitVector[index3] = 0;
1✔
2493
                index3 += 1;
1✔
2494
            }
2495
            if (index3 < permutationLength) {
1✔
2496
                bitVector[index3] += 1;
1✔
2497
            }
2498
            result.add(result2);
1✔
2499
        }
2500
        return result;
1✔
2501
    }
2502

2503
    public List<List<T>> createPermutationWithRepetition(final int permutationLength) {
2504
        return createPermutationWithRepetition((List<T>) value(), permutationLength);
1✔
2505
    }
2506

2507
    protected static <T> List<T> newArrayList() {
2508
        return Underscore.newArrayList();
1✔
2509
    }
2510

2511
    protected static <T> List<T> newArrayList(final Iterable<T> iterable) {
2512
        return Underscore.newArrayList(iterable);
1✔
2513
    }
2514

2515
    protected static <T> Set<T> newLinkedHashSet() {
2516
        return Underscore.newLinkedHashSet();
1✔
2517
    }
2518

2519
    protected static <K, E> Map<K, E> newLinkedHashMap() {
2520
        return Underscore.newLinkedHashMap();
1✔
2521
    }
2522

2523
    public static <T> String join(final Iterable<T> iterable, final String separator) {
2524
        return Underscore.join(iterable, separator);
1✔
2525
    }
2526

2527
    public static String toJson(Collection collection) {
2528
        return Json.toJson(collection);
1✔
2529
    }
2530

2531
    public static String toJson(Map map) {
2532
        return Json.toJson(map);
1✔
2533
    }
2534

2535
    public String toJson() {
2536
        return Json.toJson((Collection) getIterable());
1✔
2537
    }
2538

2539
    @SuppressWarnings("unchecked")
2540
    public static <T> T fromXml(final String xml) {
2541
        return (T) Xml.fromXml(xml);
1✔
2542
    }
2543

2544
    public static Map<String, Object> fromXmlMap(final String xml) {
2545
        return fromXmlMap(xml, Xml.FromType.FOR_CONVERT);
1✔
2546
    }
2547

2548
    public static Map<String, Object> fromXmlMap(final String xml, final Xml.FromType fromType) {
2549
        final Object object = Xml.fromXml(xml, fromType);
1✔
2550
        return getStringObjectMap(object);
1✔
2551
    }
2552

2553
    @SuppressWarnings("unchecked")
2554
    public static <T> T fromXml(final String xml, final Xml.FromType fromType) {
2555
        return (T) Xml.fromXml(xml, fromType);
1✔
2556
    }
2557

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

2563
    @SuppressWarnings("unchecked")
2564
    public static <T> T fromXmlWithoutNamespaces(final String xml) {
2565
        return (T) Xml.fromXmlWithoutNamespaces(xml);
1✔
2566
    }
2567

2568
    public static Map<String, Object> fromXmlWithoutNamespacesMap(final String xml) {
2569
        final Object object = Xml.fromXmlWithoutNamespaces(xml);
1✔
2570
        return getStringObjectMap(object);
1✔
2571
    }
2572

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

2578
    @SuppressWarnings("unchecked")
2579
    public static <T> T fromXmlWithoutNamespacesAndAttributes(final String xml) {
2580
        return (T) Xml.fromXmlWithoutNamespacesAndAttributes(xml);
1✔
2581
    }
2582

2583
    public static String toXml(Collection collection) {
2584
        return Xml.toXml(collection);
1✔
2585
    }
2586

2587
    public static String toXml(Map map) {
2588
        return Xml.toXml(map);
1✔
2589
    }
2590

2591
    @SuppressWarnings("unchecked")
2592
    public static <T> T fromJson(String string) {
2593
        return (T) Json.fromJson(string);
1✔
2594
    }
2595

2596
    public Object fromJson() {
2597
        return Json.fromJson(getString().get());
1✔
2598
    }
2599

2600
    public static Map<String, Object> fromJsonMap(final String string) {
2601
        final Object object = Json.fromJson(string);
1✔
2602
        return getStringObjectMap(object);
1✔
2603
    }
2604

2605
    @SuppressWarnings("unchecked")
2606
    private static Map<String, Object> getStringObjectMap(Object object) {
2607
        final Map<String, Object> result;
2608
        if (object instanceof Map) {
1✔
2609
            result = (Map<String, Object>) object;
1✔
2610
        } else {
2611
            result = newLinkedHashMap();
1✔
2612
            result.put("value", object);
1✔
2613
        }
2614
        return result;
1✔
2615
    }
2616

2617
    public String toXml() {
2618
        return Xml.toXml((Collection) getIterable());
1✔
2619
    }
2620

2621
    public Object fromXml() {
2622
        return Xml.fromXml(getString().get());
1✔
2623
    }
2624

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

2668
    public static String jsonToXml(String json, Xml.XmlStringBuilder.Step identStep) {
2669
        return jsonToXml(json, identStep, null, ROOT);
1✔
2670
    }
2671

2672
    public static String jsonToXml(String json, JsonToXmlMode mode) {
2673
        return jsonToXml(json, Xml.XmlStringBuilder.Step.TWO_SPACES, mode, ROOT);
1✔
2674
    }
2675

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

2680
    public static String jsonToXml(String json, String newRootName) {
2681
        return jsonToXml(
1✔
2682
                json,
2683
                Xml.XmlStringBuilder.Step.TWO_SPACES,
2684
                JsonToXmlMode.DEFINE_ROOT_NAME,
2685
                newRootName);
2686
    }
2687

2688
    public static String jsonToXml(String json) {
2689
        return jsonToXml(json, Xml.XmlStringBuilder.Step.TWO_SPACES, null, null);
1✔
2690
    }
2691

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

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

2732
    public static String xmlToJson(String xml, Json.JsonStringBuilder.Step identStep) {
2733
        return xmlToJson(xml, identStep, null);
1✔
2734
    }
2735

2736
    public static String xmlToJson(String xml, XmlToJsonMode mode) {
2737
        return xmlToJson(xml, Json.JsonStringBuilder.Step.TWO_SPACES, mode);
1✔
2738
    }
2739

2740
    public static String xmlOrJsonToJson(String xmlOrJson, Json.JsonStringBuilder.Step identStep) {
2741
        TextType textType = getTextType(xmlOrJson);
1✔
2742
        final String result;
2743
        if (textType == TextType.JSON) {
1✔
2744
            result = getJsonString(identStep, fromJson(xmlOrJson));
1✔
2745
        } else if (textType == TextType.XML) {
1✔
2746
            result = getJsonString(identStep, fromXml(xmlOrJson));
1✔
2747
        } else {
2748
            result = xmlOrJson;
1✔
2749
        }
2750
        return result;
1✔
2751
    }
2752

2753
    public static String xmlOrJsonToJson(String xmlOrJson) {
2754
        return xmlOrJsonToJson(xmlOrJson, Json.JsonStringBuilder.Step.TWO_SPACES);
1✔
2755
    }
2756

2757
    @SuppressWarnings("unchecked")
2758
    private static String getJsonString(Json.JsonStringBuilder.Step identStep, Object object) {
2759
        final String result;
2760
        if (object instanceof Map) {
1✔
2761
            result = Json.toJson((Map) object, identStep);
1✔
2762
        } else {
2763
            result = Json.toJson((List) object, identStep);
1✔
2764
        }
2765
        return result;
1✔
2766
    }
2767

2768
    public static String xmlOrJsonToXml(String xmlOrJson, Xml.XmlStringBuilder.Step identStep) {
2769
        TextType textType = getTextType(xmlOrJson);
1✔
2770
        final String result;
2771
        if (textType == TextType.JSON) {
1✔
2772
            result = getXmlString(identStep, fromJson(xmlOrJson));
1✔
2773
        } else if (textType == TextType.XML) {
1✔
2774
            result = getXmlString(identStep, fromXml(xmlOrJson));
1✔
2775
        } else {
2776
            result = xmlOrJson;
1✔
2777
        }
2778
        return result;
1✔
2779
    }
2780

2781
    public static String xmlOrJsonToXml(String xmlOrJson) {
2782
        return xmlOrJsonToXml(xmlOrJson, Xml.XmlStringBuilder.Step.TWO_SPACES);
1✔
2783
    }
2784

2785
    @SuppressWarnings("unchecked")
2786
    private static String getXmlString(Xml.XmlStringBuilder.Step identStep, Object object) {
2787
        final String result;
2788
        if (object instanceof Map) {
1✔
2789
            result = Xml.toXml((Map) object, identStep);
1✔
2790
        } else {
2791
            result = Xml.toXml((List) object, identStep);
1✔
2792
        }
2793
        return result;
1✔
2794
    }
2795

2796
    public enum TextType {
1✔
2797
        JSON,
1✔
2798
        XML,
1✔
2799
        OTHER
1✔
2800
    }
2801

2802
    public static TextType getTextType(String text) {
2803
        String trimmed = trim(text);
1✔
2804
        final TextType textType;
2805
        if (trimmed.startsWith("{") && trimmed.endsWith("}")
1✔
2806
                || trimmed.startsWith("[") && trimmed.endsWith("]")) {
1✔
2807
            textType = TextType.JSON;
1✔
2808
        } else if (trimmed.startsWith("<") && trimmed.endsWith(">")) {
1✔
2809
            textType = TextType.XML;
1✔
2810
        } else {
2811
            textType = TextType.OTHER;
1✔
2812
        }
2813
        return textType;
1✔
2814
    }
2815

2816
    public static String formatJsonOrXml(String jsonOrXml, String identStep) {
2817
        TextType textType = getTextType(jsonOrXml);
1✔
2818
        final String result;
2819
        if (textType == TextType.JSON) {
1✔
2820
            result = formatJson(jsonOrXml, Json.JsonStringBuilder.Step.valueOf(identStep));
1✔
2821
        } else if (textType == TextType.XML) {
1✔
2822
            result = formatXml(jsonOrXml, Xml.XmlStringBuilder.Step.valueOf(identStep));
1✔
2823
        } else {
2824
            result = jsonOrXml;
1✔
2825
        }
2826
        return result;
1✔
2827
    }
2828

2829
    public static String formatJsonOrXml(String jsonOrXml) {
2830
        return formatJsonOrXml(jsonOrXml, "TWO_SPACES");
1✔
2831
    }
2832

2833
    public static String formatJson(String json, Json.JsonStringBuilder.Step identStep) {
2834
        return Json.formatJson(json, identStep);
1✔
2835
    }
2836

2837
    public static String formatJson(String json) {
2838
        return Json.formatJson(json);
1✔
2839
    }
2840

2841
    public static String formatXml(String xml, Xml.XmlStringBuilder.Step identStep) {
2842
        return Xml.formatXml(xml, identStep);
1✔
2843
    }
2844

2845
    public static String formatXml(String xml) {
2846
        return Xml.formatXml(xml);
1✔
2847
    }
2848

2849
    public static String changeXmlEncoding(
2850
            String xml, Xml.XmlStringBuilder.Step identStep, String encoding) {
2851
        return Xml.changeXmlEncoding(xml, identStep, encoding);
1✔
2852
    }
2853

2854
    public static String changeXmlEncoding(String xml, String encoding) {
2855
        return Xml.changeXmlEncoding(xml, encoding);
1✔
2856
    }
2857

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

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

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

2927
    @SuppressWarnings("unchecked")
2928
    public static Map<String, Object> replaceSelfClosingWithNull(Map<String, Object> map) {
2929
        return (Map<String, Object>) replaceSelfClosingWithValue(map, null);
1✔
2930
    }
2931

2932
    @SuppressWarnings("unchecked")
2933
    public static Map<String, Object> replaceSelfClosingWithEmpty(Map<String, Object> map) {
2934
        Object result = replaceSelfClosingWithValue(map, "");
1✔
2935
        if (result instanceof Map) {
1✔
2936
            return (Map<String, Object>) result;
1✔
2937
        }
2938
        return Collections.emptyMap();
1✔
2939
    }
2940

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

2960
    @SuppressWarnings("unchecked")
2961
    private static Object makeObjectSelfClose(Object value, String newValue) {
2962
        final Object result;
2963
        if (value instanceof List) {
1✔
2964
            List<Object> values = newArrayList();
1✔
2965
            for (Object item : (List) value) {
1✔
2966
                values.add(
1✔
2967
                        item instanceof Map
1✔
2968
                                ? replaceSelfClosingWithValue((Map) item, newValue)
1✔
2969
                                : item);
1✔
2970
            }
1✔
2971
            result = values;
1✔
2972
        } else if (value instanceof Map) {
1✔
2973
            result = replaceSelfClosingWithValue((Map) value, newValue);
1✔
2974
        } else {
2975
            result = value;
1✔
2976
        }
2977
        return result;
1✔
2978
    }
2979

2980
    public static Map<String, Object> replaceEmptyValueWithNull(Map<String, Object> map) {
2981
        if (map == null || map.isEmpty()) {
1✔
2982
            return null;
1✔
2983
        }
2984
        Map<String, Object> outMap = newLinkedHashMap();
1✔
2985
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
2986
            outMap.put(String.valueOf(entry.getKey()), makeObjectEmptyValue(entry.getValue()));
1✔
2987
        }
1✔
2988
        return outMap;
1✔
2989
    }
2990

2991
    @SuppressWarnings("unchecked")
2992
    private static Object makeObjectEmptyValue(Object value) {
2993
        final Object result;
2994
        if (value instanceof List) {
1✔
2995
            List<Object> values = newArrayList();
1✔
2996
            for (Object item : (List) value) {
1✔
2997
                values.add(item instanceof Map ? replaceEmptyValueWithNull((Map) item) : item);
1✔
2998
            }
1✔
2999
            result = values;
1✔
3000
        } else if (value instanceof Map) {
1✔
3001
            result = replaceEmptyValueWithNull((Map) value);
1✔
3002
        } else {
3003
            result = value;
1✔
3004
        }
3005
        return result;
1✔
3006
    }
3007

3008
    public static Object replaceEmptyValueWithEmptyString(Map<String, Object> map) {
3009
        if (map.isEmpty()) {
1✔
3010
            return "";
1✔
3011
        }
3012
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3013
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3014
            outMap.put(String.valueOf(entry.getKey()), makeObjectEmptyString(entry.getValue()));
1✔
3015
        }
1✔
3016
        return outMap;
1✔
3017
    }
3018

3019
    @SuppressWarnings("unchecked")
3020
    private static Object makeObjectEmptyString(Object value) {
3021
        final Object result;
3022
        if (value instanceof List) {
1✔
3023
            List<Object> values = newArrayList();
1✔
3024
            for (Object item : (List) value) {
1✔
3025
                values.add(
1✔
3026
                        item instanceof Map ? replaceEmptyValueWithEmptyString((Map) item) : item);
1✔
3027
            }
1✔
3028
            result = values;
1✔
3029
        } else if (value instanceof Map) {
1✔
3030
            result = replaceEmptyValueWithEmptyString((Map) value);
1✔
3031
        } else {
3032
            result = value;
1✔
3033
        }
3034
        return result;
1✔
3035
    }
3036

3037
    public static Map<String, Object> forceAttributeUsage(Map<String, Object> map) {
3038
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3039
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3040
            outMap.put(
1✔
3041
                    entry.getValue() instanceof Map
1✔
3042
                                    || entry.getValue() instanceof List
1✔
3043
                                    || String.valueOf(entry.getKey()).startsWith("-")
1✔
3044
                            ? String.valueOf(entry.getKey())
1✔
3045
                            : "-" + entry.getKey(),
1✔
3046
                    makeAttributeUsage(entry.getValue()));
1✔
3047
        }
1✔
3048
        return outMap;
1✔
3049
    }
3050

3051
    @SuppressWarnings("unchecked")
3052
    private static Object makeAttributeUsage(Object value) {
3053
        final Object result;
3054
        if (value instanceof List) {
1✔
3055
            List<Object> values = newArrayList();
1✔
3056
            for (Object item : (List) value) {
1✔
3057
                values.add(item instanceof Map ? forceAttributeUsage((Map) item) : item);
1✔
3058
            }
1✔
3059
            result = values;
1✔
3060
        } else if (value instanceof Map) {
1✔
3061
            result = forceAttributeUsage((Map) value);
1✔
3062
        } else {
3063
            result = value;
1✔
3064
        }
3065
        return result;
1✔
3066
    }
3067

3068
    public static Map<String, Object> replaceNullWithEmptyValue(Map<String, Object> map) {
3069
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3070
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3071
            outMap.put(
1✔
3072
                    entry.getKey(),
1✔
3073
                    entry.getValue() == null
1✔
3074
                            ? newLinkedHashMap()
1✔
3075
                            : makeReplaceNullValue(entry.getValue()));
1✔
3076
        }
1✔
3077
        return outMap;
1✔
3078
    }
3079

3080
    @SuppressWarnings("unchecked")
3081
    private static Object makeReplaceNullValue(Object value) {
3082
        final Object result;
3083
        if (value instanceof List) {
1✔
3084
            List<Object> values = newArrayList();
1✔
3085
            for (Object item : (List) value) {
1✔
3086
                values.add(item instanceof Map ? replaceNullWithEmptyValue((Map) item) : item);
1✔
3087
            }
1✔
3088
            result = values;
1✔
3089
        } else if (value instanceof Map) {
1✔
3090
            result = replaceNullWithEmptyValue((Map) value);
1✔
3091
        } else {
3092
            result = value;
1✔
3093
        }
3094
        return result;
1✔
3095
    }
3096

3097
    public static Map<String, Object> replaceEmptyStringWithEmptyValue(Map<String, Object> map) {
3098
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3099
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3100
            outMap.put(
1✔
3101
                    entry.getKey(),
1✔
3102
                    "".equals(entry.getValue())
1✔
3103
                            ? newLinkedHashMap()
1✔
3104
                            : makeReplaceEmptyString(entry.getValue()));
1✔
3105
        }
1✔
3106
        return outMap;
1✔
3107
    }
3108

3109
    @SuppressWarnings("unchecked")
3110
    private static Object makeReplaceEmptyString(Object value) {
3111
        final Object result;
3112
        if (value instanceof List) {
1✔
3113
            List<Object> values = newArrayList();
1✔
3114
            for (Object item : (List) value) {
1✔
3115
                values.add(
1✔
3116
                        item instanceof Map ? replaceEmptyStringWithEmptyValue((Map) item) : item);
1✔
3117
            }
1✔
3118
            result = values;
1✔
3119
        } else if (value instanceof Map) {
1✔
3120
            result = replaceEmptyStringWithEmptyValue((Map) value);
1✔
3121
        } else {
3122
            result = value;
1✔
3123
        }
3124
        return result;
1✔
3125
    }
3126

3127
    public static Map<String, Object> replaceNumberAndBooleanWithString(Map<String, Object> map) {
3128
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3129
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3130
            outMap.put(
1✔
3131
                    entry.getKey(),
1✔
3132
                    entry.getValue() instanceof Boolean || entry.getValue() instanceof Number
1✔
3133
                            ? String.valueOf(entry.getValue())
1✔
3134
                            : makeReplaceNumberAndBoolean(entry.getValue()));
1✔
3135
        }
1✔
3136
        return outMap;
1✔
3137
    }
3138

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

3164
    public static Map<String, Object> replaceFirstLevel(Map<String, Object> map) {
3165
        return replaceFirstLevel(map, 0);
1✔
3166
    }
3167

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

3185
    @SuppressWarnings("unchecked")
3186
    private static Object makeReplaceFirstLevel(Object value, int level) {
3187
        final Object result;
3188
        if (value instanceof List) {
1✔
3189
            List<Object> values = newArrayList();
1✔
3190
            for (Object item : (List) value) {
1✔
3191
                values.add(item instanceof Map ? replaceFirstLevel((Map) item, level + 1) : item);
1✔
3192
            }
1✔
3193
            result = values;
1✔
3194
        } else if (value instanceof Map) {
1✔
3195
            result = replaceFirstLevel((Map) value, level + 1);
1✔
3196
        } else {
3197
            result = value;
1✔
3198
        }
3199
        return result;
1✔
3200
    }
3201

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

3219
    @SuppressWarnings("unchecked")
3220
    private static Object makeReplaceNilWithNull(Object value) {
3221
        final Object result;
3222
        if (value instanceof List) {
1✔
3223
            List<Object> values = newArrayList();
1✔
3224
            for (Object item : (List) value) {
1✔
3225
                values.add(item instanceof Map ? replaceNilWithNull((Map) item) : item);
1✔
3226
            }
1✔
3227
            result = values;
1✔
3228
        } else if (value instanceof Map) {
1✔
3229
            result = replaceNilWithNull((Map) value);
1✔
3230
        } else {
3231
            result = value;
1✔
3232
        }
3233
        return result;
1✔
3234
    }
3235

3236
    public static Map<String, Object> deepCopyMap(Map<String, Object> map) {
3237
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3238
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3239
            outMap.put(entry.getKey(), makeDeepCopyMap(entry.getValue()));
1✔
3240
        }
1✔
3241
        return outMap;
1✔
3242
    }
3243

3244
    @SuppressWarnings("unchecked")
3245
    private static Object makeDeepCopyMap(Object value) {
3246
        final Object result;
3247
        if (value instanceof List) {
1✔
3248
            List<Object> values = newArrayList();
1✔
3249
            for (Object item : (List) value) {
1✔
3250
                values.add(item instanceof Map ? deepCopyMap((Map) item) : item);
1✔
3251
            }
1✔
3252
            result = values;
1✔
3253
        } else if (value instanceof Map) {
1✔
3254
            result = deepCopyMap((Map) value);
1✔
3255
        } else {
3256
            result = value;
1✔
3257
        }
3258
        return result;
1✔
3259
    }
3260

3261
    public static Builder objectBuilder() {
3262
        return new U.Builder();
1✔
3263
    }
3264

3265
    public static class Builder {
3266
        private final Map<String, Object> data;
3267

3268
        public Builder() {
1✔
3269
            data = newLinkedHashMap();
1✔
3270
        }
1✔
3271

3272
        public Builder add(final String key, final Object value) {
3273
            data.put(key, value);
1✔
3274
            return this;
1✔
3275
        }
3276

3277
        public Builder add(final Object value) {
3278
            data.put(String.valueOf(data.size()), value);
1✔
3279
            return this;
1✔
3280
        }
3281

3282
        public <T> T get(final String path) {
3283
            return U.get(data, path);
1✔
3284
        }
3285

3286
        public <T> T get(final List<String> paths) {
3287
            return U.get(data, paths);
1✔
3288
        }
3289

3290
        public Builder set(final String path, final Object value) {
3291
            U.set(data, path, value);
1✔
3292
            return this;
1✔
3293
        }
3294

3295
        public Builder set(final List<String> paths, final Object value) {
3296
            U.set(data, paths, value);
1✔
3297
            return this;
1✔
3298
        }
3299

3300
        public Builder remove(final String key) {
3301
            U.remove(data, key);
1✔
3302
            return this;
1✔
3303
        }
3304

3305
        public Builder remove(final List<String> keys) {
3306
            U.remove(data, keys);
1✔
3307
            return this;
1✔
3308
        }
3309

3310
        public Builder clear() {
3311
            data.clear();
1✔
3312
            return this;
1✔
3313
        }
3314

3315
        public boolean isEmpty() {
3316
            return data.isEmpty();
1✔
3317
        }
3318

3319
        public int size() {
3320
            return data.size();
1✔
3321
        }
3322

3323
        public Builder add(final Builder builder) {
3324
            data.put(String.valueOf(data.size()), builder.build());
1✔
3325
            return this;
1✔
3326
        }
3327

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

3333
        public Builder add(final String key, final Builder builder) {
3334
            data.put(key, builder.build());
1✔
3335
            return this;
1✔
3336
        }
3337

3338
        public Builder add(final Map<String, Object> map) {
3339
            data.putAll(deepCopyMap(map));
1✔
3340
            return this;
1✔
3341
        }
3342

3343
        public Builder update(final Map<String, Object> map) {
3344
            U.update(data, deepCopyMap(map));
1✔
3345
            return this;
1✔
3346
        }
3347

3348
        public Builder addNull(final String key) {
3349
            data.put(key, null);
1✔
3350
            return this;
1✔
3351
        }
3352

3353
        @SuppressWarnings("unchecked")
3354
        public Map<String, Object> build() {
3355
            return (Map<String, Object>) ((LinkedHashMap) data).clone();
1✔
3356
        }
3357

3358
        public String toXml() {
3359
            return Xml.toXml(data);
1✔
3360
        }
3361

3362
        public static Builder fromXml(final String xml) {
3363
            final Builder builder = new Builder();
1✔
3364
            builder.data.putAll(fromXmlMap(xml));
1✔
3365
            return builder;
1✔
3366
        }
3367

3368
        public static Builder fromMap(final Map<String, Object> map) {
3369
            final Builder builder = new Builder();
1✔
3370
            builder.data.putAll(deepCopyMap(map));
1✔
3371
            return builder;
1✔
3372
        }
3373

3374
        public String toJson() {
3375
            return Json.toJson(data);
1✔
3376
        }
3377

3378
        public static Builder fromJson(final String json) {
3379
            final Builder builder = new Builder();
1✔
3380
            builder.data.putAll(fromJsonMap(json));
1✔
3381
            return builder;
1✔
3382
        }
3383

3384
        public Chain<Object> toChain() {
3385
            return new U.Chain<>(data.entrySet());
1✔
3386
        }
3387

3388
        @Override
3389
        public String toString() {
3390
            return data.toString();
1✔
3391
        }
3392
    }
3393

3394
    public static ArrayBuilder arrayBuilder() {
3395
        return new U.ArrayBuilder();
1✔
3396
    }
3397

3398
    public static class ArrayBuilder {
3399
        private final List<Object> data;
3400

3401
        public ArrayBuilder() {
1✔
3402
            data = newArrayList();
1✔
3403
        }
1✔
3404

3405
        public ArrayBuilder add(final Object value) {
3406
            data.add(value);
1✔
3407
            return this;
1✔
3408
        }
3409

3410
        public ArrayBuilder addNull() {
3411
            data.add(null);
1✔
3412
            return this;
1✔
3413
        }
3414

3415
        public <T> T get(final String path) {
3416
            return U.get(U.getStringObjectMap(data), "value." + path);
1✔
3417
        }
3418

3419
        public <T> T get(final List<String> paths) {
3420
            List<String> newPaths = new ArrayList<>();
1✔
3421
            newPaths.add("value");
1✔
3422
            newPaths.addAll(paths);
1✔
3423
            return U.get(U.getStringObjectMap(data), newPaths);
1✔
3424
        }
3425

3426
        public ArrayBuilder set(final int index, final Object value) {
3427
            data.set(index, value);
1✔
3428
            return this;
1✔
3429
        }
3430

3431
        public ArrayBuilder remove(final int index) {
3432
            data.remove(index);
1✔
3433
            return this;
1✔
3434
        }
3435

3436
        public ArrayBuilder clear() {
3437
            data.clear();
1✔
3438
            return this;
1✔
3439
        }
3440

3441
        public boolean isEmpty() {
3442
            return data.isEmpty();
1✔
3443
        }
3444

3445
        public int size() {
3446
            return data.size();
1✔
3447
        }
3448

3449
        public ArrayBuilder add(final ArrayBuilder builder) {
3450
            data.addAll(builder.build());
1✔
3451
            return this;
1✔
3452
        }
3453

3454
        public ArrayBuilder add(final Builder builder) {
3455
            data.add(builder.build());
1✔
3456
            return this;
1✔
3457
        }
3458

3459
        @SuppressWarnings("unchecked")
3460
        public ArrayBuilder merge(final List<Object> list) {
3461
            U.merge(data, (List<Object>) ((ArrayList) list).clone());
1✔
3462
            return this;
1✔
3463
        }
3464

3465
        @SuppressWarnings("unchecked")
3466
        public List<Object> build() {
3467
            return (List<Object>) ((ArrayList) data).clone();
1✔
3468
        }
3469

3470
        public String toXml() {
3471
            return Xml.toXml(data);
1✔
3472
        }
3473

3474
        public static ArrayBuilder fromXml(final String xml) {
3475
            final ArrayBuilder builder = new ArrayBuilder();
1✔
3476
            builder.data.addAll(U.<List<Object>>fromXml(xml));
1✔
3477
            return builder;
1✔
3478
        }
3479

3480
        public String toJson() {
3481
            return Json.toJson(data);
1✔
3482
        }
3483

3484
        public static ArrayBuilder fromJson(final String json) {
3485
            final ArrayBuilder builder = new ArrayBuilder();
1✔
3486
            builder.data.addAll(U.<List<Object>>fromJson(json));
1✔
3487
            return builder;
1✔
3488
        }
3489

3490
        public Chain<Object> toChain() {
3491
            return new U.Chain<>(data);
1✔
3492
        }
3493

3494
        @Override
3495
        public String toString() {
3496
            return data.toString();
1✔
3497
        }
3498
    }
3499
}
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