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

javadev / underscore-java / #3583

22 Apr 2023 04:34AM CUT coverage: 100.0%. Remained the same
#3583

push

web-flow
Update README.md

4424 of 4424 relevant lines covered (100.0%)

1.0 hits per line

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1800
    private static Map.Entry getMapEntry(Map map) {
1801
        return map.isEmpty() ? null : (Map.Entry) map.entrySet().iterator().next();
1✔
1802
    }
1803

1804
    public static <T> T get(final Map<String, Object> object, final String path) {
1805
        return get(object, stringToPath(path));
1✔
1806
    }
1807

1808
    public static <T> T get(final Map<String, Object> object, final List<String> paths) {
1809
        return baseGetOrSetOrRemove(object, paths, null, OperationType.GET);
1✔
1810
    }
1811

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

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

1846
    public static <T> T set(final Map<String, Object> object, final String path, Object value) {
1847
        return set(object, stringToPath(path), value);
1✔
1848
    }
1849

1850
    public static <T> T set(
1851
            final Map<String, Object> object, final List<String> paths, Object value) {
1852
        return baseGetOrSetOrRemove(object, paths, value, OperationType.SET);
1✔
1853
    }
1854

1855
    public static <T> T update(final Map<String, Object> object, final String path, Object value) {
1856
        return update(object, stringToPath(path), value);
1✔
1857
    }
1858

1859
    public static <T> T update(
1860
            final Map<String, Object> object, final List<String> paths, Object value) {
1861
        return baseGetOrSetOrRemove(object, paths, value, OperationType.UPDATE);
1✔
1862
    }
1863

1864
    public static <T> T remove(final Map<String, Object> object, final String path) {
1865
        return remove(object, stringToPath(path));
1✔
1866
    }
1867

1868
    public static <T> T remove(final Map<String, Object> object, final List<String> paths) {
1869
        return baseGetOrSetOrRemove(object, paths, null, OperationType.REMOVE);
1✔
1870
    }
1871

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

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

1906
    public static Map<String, Object> setValue(
1907
            final Map<String, Object> map, final String key, final Object newValue) {
1908
        return setValue(map, key, (key1, value) -> newValue);
1✔
1909
    }
1910

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

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

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

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

1991
    public static List<Object> merge(List<Object> list1, List<Object> list2) {
1992
        List<Object> outList1 = newArrayList(list1);
1✔
1993
        List<Object> outList2 = newArrayList(list2);
1✔
1994
        outList2.removeAll(list1);
1✔
1995
        outList1.addAll(outList2);
1✔
1996
        return outList1;
1✔
1997
    }
1998

1999
    public static class FetchResponse {
2000
        private final boolean ok;
2001
        private final int status;
2002
        private final Map<String, List<String>> headerFields;
2003
        private final java.io.ByteArrayOutputStream stream;
2004

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

2016
        public boolean isOk() {
2017
            return ok;
1✔
2018
        }
2019

2020
        public int getStatus() {
2021
            return status;
1✔
2022
        }
2023

2024
        public Map<String, List<String>> getHeaderFields() {
2025
            return headerFields;
1✔
2026
        }
2027

2028
        public byte[] blob() {
2029
            return stream.toByteArray();
1✔
2030
        }
2031

2032
        public String text() {
2033
            return stream.toString(StandardCharsets.UTF_8);
1✔
2034
        }
2035

2036
        public Object json() {
2037
            return Json.fromJson(text());
1✔
2038
        }
2039

2040
        public Map<String, Object> jsonMap() {
2041
            return fromJsonMap(text());
1✔
2042
        }
2043

2044
        public Object xml() {
2045
            return Xml.fromXml(text());
1✔
2046
        }
2047

2048
        public Map<String, Object> xmlMap() {
2049
            return fromXmlMap(text());
1✔
2050
        }
2051
    }
2052

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

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

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

2074
    public static FetchResponse fetch(
2075
            final String url, final Integer connectTimeout, final Integer readTimeout) {
2076
        return fetch(url, null, null, DEFAULT_HEADER_FIELDS, connectTimeout, readTimeout);
1✔
2077
    }
2078

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

2096
    public static FetchResponse fetch(final String url, final String method, final String body) {
2097
        return fetch(url, method, body, DEFAULT_HEADER_FIELDS, null, null);
1✔
2098
    }
2099

2100
    public static class BaseHttpSslSocketFactory extends javax.net.ssl.SSLSocketFactory {
2101
        private javax.net.ssl.SSLContext getSslContext() {
2102
            return createEasySslContext();
2103
        }
2104

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

2112
        @Override
2113
        public java.net.Socket createSocket(
2114
                String arg0, int arg1, java.net.InetAddress arg2, int arg3)
2115
                throws java.io.IOException {
2116
            return getSslContext().getSocketFactory().createSocket(arg0, arg1, arg2, arg3);
2117
        }
2118

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

2125
        @Override
2126
        public java.net.Socket createSocket(String arg0, int arg1) throws java.io.IOException {
2127
            return getSslContext().getSocketFactory().createSocket(arg0, arg1);
2128
        }
2129

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

2135
        @Override
2136
        public String[] getDefaultCipherSuites() {
2137
            return new String[] {};
2138
        }
2139

2140
        @Override
2141
        public java.net.Socket createSocket(
2142
                java.net.Socket arg0, String arg1, int arg2, boolean arg3)
2143
                throws java.io.IOException {
2144
            return getSslContext().getSocketFactory().createSocket(arg0, arg1, arg2, arg3);
2145
        }
2146

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

2158
        public static class MyX509TrustManager implements javax.net.ssl.X509TrustManager {
2159

2160
            static MyX509TrustManager manger = new MyX509TrustManager();
2161

2162
            public MyX509TrustManager() {
2163
                // ignore MyX509TrustManager
2164
            }
2165

2166
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
2167
                return new java.security.cert.X509Certificate[] {};
2168
            }
2169

2170
            public void checkClientTrusted(
2171
                    java.security.cert.X509Certificate[] chain, String authType) {
2172
                // ignore checkClientTrusted
2173
            }
2174

2175
            public void checkServerTrusted(
2176
                    java.security.cert.X509Certificate[] chain, String authType) {
2177
                // ignore checkServerTrusted
2178
            }
2179
        }
2180
    }
2181

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

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

2256
    public static class Fetch {
2257
        private Fetch() {}
2258

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

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

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

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

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

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

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

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

2355
    public String deburr() {
2356
        return deburr(getString().get());
1✔
2357
    }
2358

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

2363
    public boolean endsWith(final String target, final Integer position) {
2364
        return endsWith(getString().get(), target, position);
1✔
2365
    }
2366

2367
    public String kebabCase() {
2368
        return kebabCase(getString().get());
1✔
2369
    }
2370

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

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

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

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

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

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

2395
    public String padEnd(final int length, final String chars) {
2396
        return padEnd(getString().get(), length, chars);
1✔
2397
    }
2398

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

2403
    public String startCase() {
2404
        return startCase(getString().get());
1✔
2405
    }
2406

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

2411
    public boolean startsWith(final String target, final Integer position) {
2412
        return startsWith(getString().get(), target, position);
1✔
2413
    }
2414

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

2419
    public String trimWith(final String chars) {
2420
        return trim(getString().get(), chars);
1✔
2421
    }
2422

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

2427
    public String trimStartWith(final String chars) {
2428
        return trimStart(getString().get(), chars);
1✔
2429
    }
2430

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

2435
    public String trimEndWith(final String chars) {
2436
        return trimEnd(getString().get(), chars);
1✔
2437
    }
2438

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

2443
    public String trunc(final int length) {
2444
        return trunc(getString().get(), length);
1✔
2445
    }
2446

2447
    public String uncapitalize() {
2448
        return uncapitalize(getString().get());
1✔
2449
    }
2450

2451
    public List<String> words() {
2452
        return words(getString().get());
1✔
2453
    }
2454

2455
    public static class LruCache<K, V> {
2456
        private static final boolean SORT_BY_ACCESS = true;
2457
        private static final float LOAD_FACTOR = 0.75F;
2458
        private final Map<K, V> lruCacheMap;
2459
        private final int capacity;
2460

2461
        public LruCache(int capacity) {
1✔
2462
            this.capacity = capacity;
1✔
2463
            this.lruCacheMap = new LinkedHashMap<>(capacity, LOAD_FACTOR, SORT_BY_ACCESS);
1✔
2464
        }
1✔
2465

2466
        public V get(K key) {
2467
            return lruCacheMap.get(key);
1✔
2468
        }
2469

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

2480
    public static <K, V> LruCache<K, V> createLruCache(final int capacity) {
2481
        return new LruCache<>(capacity);
1✔
2482
    }
2483

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

2507
    public List<List<T>> createPermutationWithRepetition(final int permutationLength) {
2508
        return createPermutationWithRepetition((List<T>) value(), permutationLength);
1✔
2509
    }
2510

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

2515
    protected static <T> List<T> newArrayList(final Iterable<T> iterable) {
2516
        return Underscore.newArrayList(iterable);
1✔
2517
    }
2518

2519
    protected static <T> Set<T> newLinkedHashSet() {
2520
        return Underscore.newLinkedHashSet();
1✔
2521
    }
2522

2523
    protected static <K, E> Map<K, E> newLinkedHashMap() {
2524
        return Underscore.newLinkedHashMap();
1✔
2525
    }
2526

2527
    public static <T> String join(final Iterable<T> iterable, final String separator) {
2528
        return Underscore.join(iterable, separator);
1✔
2529
    }
2530

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

2535
    public static String toJson(Map map) {
2536
        return Json.toJson(map);
1✔
2537
    }
2538

2539
    public String toJson() {
2540
        return Json.toJson((Collection) getIterable());
1✔
2541
    }
2542

2543
    public static String toJsonJavaString(Collection collection) {
2544
        return Json.toJsonJavaString(collection);
1✔
2545
    }
2546

2547
    public static String toJsonJavaString(Map map) {
2548
        return Json.toJsonJavaString(map);
1✔
2549
    }
2550

2551
    public String toJsonJavaString() {
2552
        return Json.toJsonJavaString((Collection) getIterable());
1✔
2553
    }
2554

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

2560
    public static Map<String, Object> fromXmlMap(final String xml) {
2561
        return fromXmlMap(xml, Xml.FromType.FOR_CONVERT);
1✔
2562
    }
2563

2564
    public static Map<String, Object> fromXmlMap(final String xml, final Xml.FromType fromType) {
2565
        final Object object = Xml.fromXml(xml, fromType);
1✔
2566
        return getStringObjectMap(object);
1✔
2567
    }
2568

2569
    @SuppressWarnings("unchecked")
2570
    public static <T> T fromXml(final String xml, final Xml.FromType fromType) {
2571
        return (T) Xml.fromXml(xml, fromType);
1✔
2572
    }
2573

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

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

2584
    public static Map<String, Object> fromXmlWithoutNamespacesMap(final String xml) {
2585
        final Object object = Xml.fromXmlWithoutNamespaces(xml);
1✔
2586
        return getStringObjectMap(object);
1✔
2587
    }
2588

2589
    @SuppressWarnings("unchecked")
2590
    public static <T> T fromXmlWithoutAttributes(final String xml) {
2591
        return (T) Xml.fromXmlWithoutAttributes(xml);
1✔
2592
    }
2593

2594
    @SuppressWarnings("unchecked")
2595
    public static <T> T fromXmlWithoutNamespacesAndAttributes(final String xml) {
2596
        return (T) Xml.fromXmlWithoutNamespacesAndAttributes(xml);
1✔
2597
    }
2598

2599
    public static String toXml(Collection collection) {
2600
        return Xml.toXml(collection);
1✔
2601
    }
2602

2603
    public static String toXml(Map map) {
2604
        return Xml.toXml(map);
1✔
2605
    }
2606

2607
    @SuppressWarnings("unchecked")
2608
    public static <T> T fromJson(String string) {
2609
        return (T) Json.fromJson(string);
1✔
2610
    }
2611

2612
    public Object fromJson() {
2613
        return Json.fromJson(getString().get());
1✔
2614
    }
2615

2616
    public static Map<String, Object> fromJsonMap(final String string) {
2617
        final Object object = Json.fromJson(string);
1✔
2618
        return getStringObjectMap(object);
1✔
2619
    }
2620

2621
    @SuppressWarnings("unchecked")
2622
    private static Map<String, Object> getStringObjectMap(Object object) {
2623
        final Map<String, Object> result;
2624
        if (object instanceof Map) {
1✔
2625
            result = (Map<String, Object>) object;
1✔
2626
        } else {
2627
            result = newLinkedHashMap();
1✔
2628
            result.put("value", object);
1✔
2629
        }
2630
        return result;
1✔
2631
    }
2632

2633
    public String toXml() {
2634
        return Xml.toXml((Collection) getIterable());
1✔
2635
    }
2636

2637
    public Object fromXml() {
2638
        return Xml.fromXml(getString().get());
1✔
2639
    }
2640

2641
    @SuppressWarnings("unchecked")
2642
    public static String jsonToXml(
2643
            String json,
2644
            Xml.XmlStringBuilder.Step identStep,
2645
            JsonToXmlMode mode,
2646
            String newRootName) {
2647
        Object object = Json.fromJson(json);
1✔
2648
        final String result;
2649
        if (object instanceof Map) {
1✔
2650
            if (mode == JsonToXmlMode.FORCE_ATTRIBUTE_USAGE) {
1✔
2651
                result = Xml.toXml(forceAttributeUsage((Map) object), identStep, newRootName);
1✔
2652
            } else if (mode == JsonToXmlMode.DEFINE_ROOT_NAME) {
1✔
2653
                result = Xml.toXml((Map) object, identStep, newRootName);
1✔
2654
            } else if (mode == JsonToXmlMode.REPLACE_NULL_WITH_EMPTY_VALUE) {
1✔
2655
                result = Xml.toXml(replaceNullWithEmptyValue((Map) object), identStep, newRootName);
1✔
2656
            } else if (mode == JsonToXmlMode.REPLACE_EMPTY_STRING_WITH_EMPTY_VALUE) {
1✔
2657
                result =
1✔
2658
                        Xml.toXml(
1✔
2659
                                replaceEmptyStringWithEmptyValue((Map) object),
1✔
2660
                                identStep,
2661
                                newRootName);
2662
            } else if (mode == JsonToXmlMode.ADD_ROOT
1✔
2663
                    && !Xml.XmlValue.getMapKey(object).equals(ROOT)) {
1✔
2664
                final Map<String, Object> map = U.newLinkedHashMap();
1✔
2665
                map.put(newRootName, object);
1✔
2666
                result = Xml.toXml(map, identStep);
1✔
2667
            } else if (mode == JsonToXmlMode.REMOVE_ARRAY_ATTRIBUTE) {
1✔
2668
                result = Xml.toXml((Map) object, identStep, newRootName, Xml.ArrayTrue.SKIP);
1✔
2669
            } else if (mode == JsonToXmlMode.REMOVE_ATTRIBUTES) {
1✔
2670
                result =
1✔
2671
                        Xml.toXml(
1✔
2672
                                replaceNumberAndBooleanWithString((Map) object),
1✔
2673
                                identStep,
2674
                                newRootName,
2675
                                Xml.ArrayTrue.SKIP);
2676
            } else {
2677
                result = Xml.toXml((Map) object, identStep);
1✔
2678
            }
2679
            return result;
1✔
2680
        }
2681
        return Xml.toXml((List) object, identStep);
1✔
2682
    }
2683

2684
    public static String jsonToXml(String json, Xml.XmlStringBuilder.Step identStep) {
2685
        return jsonToXml(json, identStep, null, ROOT);
1✔
2686
    }
2687

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

2692
    public static String jsonToXml(String json, JsonToXmlMode mode, String newRootName) {
2693
        return jsonToXml(json, Xml.XmlStringBuilder.Step.TWO_SPACES, mode, newRootName);
1✔
2694
    }
2695

2696
    public static String jsonToXml(String json, String newRootName) {
2697
        return jsonToXml(
1✔
2698
                json,
2699
                Xml.XmlStringBuilder.Step.TWO_SPACES,
2700
                JsonToXmlMode.DEFINE_ROOT_NAME,
2701
                newRootName);
2702
    }
2703

2704
    public static String jsonToXml(String json) {
2705
        return jsonToXml(json, Xml.XmlStringBuilder.Step.TWO_SPACES, null, null);
1✔
2706
    }
2707

2708
    @SuppressWarnings("unchecked")
2709
    public static String xmlToJson(
2710
            String xml, Json.JsonStringBuilder.Step identStep, XmlToJsonMode mode) {
2711
        Object object = Xml.fromXml(xml);
1✔
2712
        final String result;
2713
        if (object instanceof Map) {
1✔
2714
            if (mode == XmlToJsonMode.REPLACE_SELF_CLOSING_WITH_NULL) {
1✔
2715
                result = Json.toJson(replaceSelfClosingWithNull((Map) object), identStep);
1✔
2716
            } else if (mode == XmlToJsonMode.REPLACE_SELF_CLOSING_WITH_STRING) {
1✔
2717
                result = Json.toJson(replaceSelfClosingWithEmpty((Map) object), identStep);
1✔
2718
            } else if (mode == XmlToJsonMode.REPLACE_EMPTY_VALUE_WITH_NULL) {
1✔
2719
                result = Json.toJson(replaceEmptyValueWithNull((Map) object), identStep);
1✔
2720
            } else if (mode == XmlToJsonMode.REPLACE_EMPTY_TAG_WITH_NULL) {
1✔
2721
                result =
1✔
2722
                        Json.toJson(
1✔
2723
                                replaceEmptyValueWithNull(replaceSelfClosingWithNull((Map) object)),
1✔
2724
                                identStep);
2725
            } else if (mode == XmlToJsonMode.REPLACE_EMPTY_TAG_WITH_STRING) {
1✔
2726
                result =
1✔
2727
                        Json.toJson(
1✔
2728
                                (Map<String, Object>)
2729
                                        replaceEmptyValueWithEmptyString(
1✔
2730
                                                replaceSelfClosingWithEmpty((Map) object)),
1✔
2731
                                identStep);
2732
            } else if (mode == XmlToJsonMode.REMOVE_FIRST_LEVEL) {
1✔
2733
                result = Json.toJson(replaceFirstLevel((Map) object), identStep);
1✔
2734
            } else if (mode == XmlToJsonMode.WITHOUT_NAMESPACES) {
1✔
2735
                result = Json.toJson((Map) Xml.fromXmlWithoutNamespaces(xml), identStep);
1✔
2736
            } else {
2737
                result = Json.toJson((Map) object, identStep);
1✔
2738
            }
2739
            return result;
1✔
2740
        }
2741
        return Json.toJson((List) object, identStep);
1✔
2742
    }
2743

2744
    public static String xmlToJson(String xml) {
2745
        return xmlToJson(xml, Json.JsonStringBuilder.Step.TWO_SPACES, null);
1✔
2746
    }
2747

2748
    public static String xmlToJson(String xml, Json.JsonStringBuilder.Step identStep) {
2749
        return xmlToJson(xml, identStep, null);
1✔
2750
    }
2751

2752
    public static String xmlToJson(String xml, XmlToJsonMode mode) {
2753
        return xmlToJson(xml, Json.JsonStringBuilder.Step.TWO_SPACES, mode);
1✔
2754
    }
2755

2756
    public static String xmlOrJsonToJson(String xmlOrJson, Json.JsonStringBuilder.Step identStep) {
2757
        TextType textType = getTextType(xmlOrJson);
1✔
2758
        final String result;
2759
        if (textType == TextType.JSON) {
1✔
2760
            result = getJsonString(identStep, fromJson(xmlOrJson));
1✔
2761
        } else if (textType == TextType.XML) {
1✔
2762
            result = getJsonString(identStep, fromXml(xmlOrJson));
1✔
2763
        } else {
2764
            result = xmlOrJson;
1✔
2765
        }
2766
        return result;
1✔
2767
    }
2768

2769
    public static String xmlOrJsonToJson(String xmlOrJson) {
2770
        return xmlOrJsonToJson(xmlOrJson, Json.JsonStringBuilder.Step.TWO_SPACES);
1✔
2771
    }
2772

2773
    @SuppressWarnings("unchecked")
2774
    private static String getJsonString(Json.JsonStringBuilder.Step identStep, Object object) {
2775
        final String result;
2776
        if (object instanceof Map) {
1✔
2777
            result = Json.toJson((Map) object, identStep);
1✔
2778
        } else {
2779
            result = Json.toJson((List) object, identStep);
1✔
2780
        }
2781
        return result;
1✔
2782
    }
2783

2784
    public static String xmlOrJsonToXml(String xmlOrJson, Xml.XmlStringBuilder.Step identStep) {
2785
        TextType textType = getTextType(xmlOrJson);
1✔
2786
        final String result;
2787
        if (textType == TextType.JSON) {
1✔
2788
            result = getXmlString(identStep, fromJson(xmlOrJson));
1✔
2789
        } else if (textType == TextType.XML) {
1✔
2790
            result = getXmlString(identStep, fromXml(xmlOrJson));
1✔
2791
        } else {
2792
            result = xmlOrJson;
1✔
2793
        }
2794
        return result;
1✔
2795
    }
2796

2797
    public static String xmlOrJsonToXml(String xmlOrJson) {
2798
        return xmlOrJsonToXml(xmlOrJson, Xml.XmlStringBuilder.Step.TWO_SPACES);
1✔
2799
    }
2800

2801
    @SuppressWarnings("unchecked")
2802
    private static String getXmlString(Xml.XmlStringBuilder.Step identStep, Object object) {
2803
        final String result;
2804
        if (object instanceof Map) {
1✔
2805
            result = Xml.toXml((Map) object, identStep);
1✔
2806
        } else {
2807
            result = Xml.toXml((List) object, identStep);
1✔
2808
        }
2809
        return result;
1✔
2810
    }
2811

2812
    public enum TextType {
1✔
2813
        JSON,
1✔
2814
        XML,
1✔
2815
        OTHER
1✔
2816
    }
2817

2818
    public static TextType getTextType(String text) {
2819
        String trimmed = trim(text);
1✔
2820
        final TextType textType;
2821
        if (trimmed.startsWith("{") && trimmed.endsWith("}")
1✔
2822
                || trimmed.startsWith("[") && trimmed.endsWith("]")) {
1✔
2823
            textType = TextType.JSON;
1✔
2824
        } else if (trimmed.startsWith("<") && trimmed.endsWith(">")) {
1✔
2825
            textType = TextType.XML;
1✔
2826
        } else {
2827
            textType = TextType.OTHER;
1✔
2828
        }
2829
        return textType;
1✔
2830
    }
2831

2832
    public static String formatJsonOrXml(String jsonOrXml, String identStep) {
2833
        TextType textType = getTextType(jsonOrXml);
1✔
2834
        final String result;
2835
        if (textType == TextType.JSON) {
1✔
2836
            result = formatJson(jsonOrXml, Json.JsonStringBuilder.Step.valueOf(identStep));
1✔
2837
        } else if (textType == TextType.XML) {
1✔
2838
            result = formatXml(jsonOrXml, Xml.XmlStringBuilder.Step.valueOf(identStep));
1✔
2839
        } else {
2840
            result = jsonOrXml;
1✔
2841
        }
2842
        return result;
1✔
2843
    }
2844

2845
    public static String formatJsonOrXml(String jsonOrXml) {
2846
        return formatJsonOrXml(jsonOrXml, "TWO_SPACES");
1✔
2847
    }
2848

2849
    public static String formatJson(String json, Json.JsonStringBuilder.Step identStep) {
2850
        return Json.formatJson(json, identStep);
1✔
2851
    }
2852

2853
    public static String formatJson(String json) {
2854
        return Json.formatJson(json);
1✔
2855
    }
2856

2857
    public static String formatXml(String xml, Xml.XmlStringBuilder.Step identStep) {
2858
        return Xml.formatXml(xml, identStep);
1✔
2859
    }
2860

2861
    public static String formatXml(String xml) {
2862
        return Xml.formatXml(xml);
1✔
2863
    }
2864

2865
    public static String changeXmlEncoding(
2866
            String xml, Xml.XmlStringBuilder.Step identStep, String encoding) {
2867
        return Xml.changeXmlEncoding(xml, identStep, encoding);
1✔
2868
    }
2869

2870
    public static String changeXmlEncoding(String xml, String encoding) {
2871
        return Xml.changeXmlEncoding(xml, encoding);
1✔
2872
    }
2873

2874
    public static Map<String, Object> removeMinusesAndConvertNumbers(Map<String, Object> map) {
2875
        Map<String, Object> outMap = newLinkedHashMap();
1✔
2876
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
2877
            final String newKey;
2878
            if (entry.getKey().startsWith("-")) {
1✔
2879
                newKey = entry.getKey().substring(1);
1✔
2880
            } else {
2881
                newKey = entry.getKey();
1✔
2882
            }
2883
            if (!entry.getKey().equals(selfClosing)
1✔
2884
                    && !entry.getKey().equals("#omit-xml-declaration")) {
1✔
2885
                outMap.put(newKey, makeObject(entry.getValue()));
1✔
2886
            }
2887
        }
1✔
2888
        return outMap;
1✔
2889
    }
2890

2891
    @SuppressWarnings("unchecked")
2892
    private static Object makeObject(Object value) {
2893
        final Object result;
2894
        if (value instanceof List) {
1✔
2895
            List<Object> values = newArrayList();
1✔
2896
            for (Object item : (List) value) {
1✔
2897
                values.add(
1✔
2898
                        item instanceof Map
1✔
2899
                                ? removeMinusesAndConvertNumbers((Map<String, Object>) item)
1✔
2900
                                : item);
1✔
2901
            }
1✔
2902
            result = values;
1✔
2903
        } else if (value instanceof Map) {
1✔
2904
            result = removeMinusesAndConvertNumbers((Map) value);
1✔
2905
        } else {
2906
            String stringValue = String.valueOf(value);
1✔
2907
            result = isJsonNumber(stringValue) ? Xml.stringToNumber(stringValue) : value;
1✔
2908
        }
2909
        return result;
1✔
2910
    }
2911

2912
    public static boolean isJsonNumber(final String string) {
2913
        boolean eFound = false;
1✔
2914
        boolean periodValid = true;
1✔
2915
        boolean pmValid = true;
1✔
2916
        boolean numberEncountered = false;
1✔
2917
        for (char ch : string.toCharArray()) {
1✔
2918
            if (pmValid) {
1✔
2919
                pmValid = false;
1✔
2920
                if (ch == '-') {
1✔
2921
                    continue;
1✔
2922
                }
2923
            }
2924
            if (!eFound && (ch == 'e' || ch == 'E')) {
1✔
2925
                eFound = true;
1✔
2926
                periodValid = false;
1✔
2927
                pmValid = true;
1✔
2928
                numberEncountered = false;
1✔
2929
                continue;
1✔
2930
            }
2931
            if (periodValid && ch == '.') {
1✔
2932
                periodValid = false;
1✔
2933
                continue;
1✔
2934
            }
2935
            if (ch < '0' || ch > '9') {
1✔
2936
                return false;
1✔
2937
            }
2938
            numberEncountered = true;
1✔
2939
        }
2940
        return numberEncountered;
1✔
2941
    }
2942

2943
    @SuppressWarnings("unchecked")
2944
    public static Map<String, Object> replaceSelfClosingWithNull(Map<String, Object> map) {
2945
        return (Map<String, Object>) replaceSelfClosingWithValue(map, null);
1✔
2946
    }
2947

2948
    @SuppressWarnings("unchecked")
2949
    public static Map<String, Object> replaceSelfClosingWithEmpty(Map<String, Object> map) {
2950
        Object result = replaceSelfClosingWithValue(map, "");
1✔
2951
        if (result instanceof Map) {
1✔
2952
            return (Map<String, Object>) result;
1✔
2953
        }
2954
        return Collections.emptyMap();
1✔
2955
    }
2956

2957
    @SuppressWarnings("unchecked")
2958
    public static Object replaceSelfClosingWithValue(Map<String, Object> map, String value) {
2959
        Object outMap = newLinkedHashMap();
1✔
2960
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
2961
            if (selfClosing.equals(entry.getKey()) && "true".equals(entry.getValue())) {
1✔
2962
                if (map.size() == 1) {
1✔
2963
                    outMap = value;
1✔
2964
                    break;
1✔
2965
                }
2966
            } else {
2967
                ((Map<String, Object>) outMap)
1✔
2968
                        .put(
1✔
2969
                                String.valueOf(entry.getKey()),
1✔
2970
                                makeObjectSelfClose(entry.getValue(), value));
1✔
2971
            }
2972
        }
1✔
2973
        return outMap;
1✔
2974
    }
2975

2976
    @SuppressWarnings("unchecked")
2977
    private static Object makeObjectSelfClose(Object value, String newValue) {
2978
        final Object result;
2979
        if (value instanceof List) {
1✔
2980
            List<Object> values = newArrayList();
1✔
2981
            for (Object item : (List) value) {
1✔
2982
                values.add(
1✔
2983
                        item instanceof Map
1✔
2984
                                ? replaceSelfClosingWithValue((Map) item, newValue)
1✔
2985
                                : item);
1✔
2986
            }
1✔
2987
            result = values;
1✔
2988
        } else if (value instanceof Map) {
1✔
2989
            result = replaceSelfClosingWithValue((Map) value, newValue);
1✔
2990
        } else {
2991
            result = value;
1✔
2992
        }
2993
        return result;
1✔
2994
    }
2995

2996
    public static Map<String, Object> replaceEmptyValueWithNull(Map<String, Object> map) {
2997
        if (map == null || map.isEmpty()) {
1✔
2998
            return null;
1✔
2999
        }
3000
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3001
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3002
            outMap.put(String.valueOf(entry.getKey()), makeObjectEmptyValue(entry.getValue()));
1✔
3003
        }
1✔
3004
        return outMap;
1✔
3005
    }
3006

3007
    @SuppressWarnings("unchecked")
3008
    private static Object makeObjectEmptyValue(Object value) {
3009
        final Object result;
3010
        if (value instanceof List) {
1✔
3011
            List<Object> values = newArrayList();
1✔
3012
            for (Object item : (List) value) {
1✔
3013
                values.add(item instanceof Map ? replaceEmptyValueWithNull((Map) item) : item);
1✔
3014
            }
1✔
3015
            result = values;
1✔
3016
        } else if (value instanceof Map) {
1✔
3017
            result = replaceEmptyValueWithNull((Map) value);
1✔
3018
        } else {
3019
            result = value;
1✔
3020
        }
3021
        return result;
1✔
3022
    }
3023

3024
    public static Object replaceEmptyValueWithEmptyString(Map<String, Object> map) {
3025
        if (map.isEmpty()) {
1✔
3026
            return "";
1✔
3027
        }
3028
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3029
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3030
            outMap.put(String.valueOf(entry.getKey()), makeObjectEmptyString(entry.getValue()));
1✔
3031
        }
1✔
3032
        return outMap;
1✔
3033
    }
3034

3035
    @SuppressWarnings("unchecked")
3036
    private static Object makeObjectEmptyString(Object value) {
3037
        final Object result;
3038
        if (value instanceof List) {
1✔
3039
            List<Object> values = newArrayList();
1✔
3040
            for (Object item : (List) value) {
1✔
3041
                values.add(
1✔
3042
                        item instanceof Map ? replaceEmptyValueWithEmptyString((Map) item) : item);
1✔
3043
            }
1✔
3044
            result = values;
1✔
3045
        } else if (value instanceof Map) {
1✔
3046
            result = replaceEmptyValueWithEmptyString((Map) value);
1✔
3047
        } else {
3048
            result = value;
1✔
3049
        }
3050
        return result;
1✔
3051
    }
3052

3053
    public static Map<String, Object> forceAttributeUsage(Map<String, Object> map) {
3054
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3055
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3056
            outMap.put(
1✔
3057
                    entry.getValue() instanceof Map
1✔
3058
                                    || entry.getValue() instanceof List
1✔
3059
                                    || String.valueOf(entry.getKey()).startsWith("-")
1✔
3060
                            ? String.valueOf(entry.getKey())
1✔
3061
                            : "-" + entry.getKey(),
1✔
3062
                    makeAttributeUsage(entry.getValue()));
1✔
3063
        }
1✔
3064
        return outMap;
1✔
3065
    }
3066

3067
    @SuppressWarnings("unchecked")
3068
    private static Object makeAttributeUsage(Object value) {
3069
        final Object result;
3070
        if (value instanceof List) {
1✔
3071
            List<Object> values = newArrayList();
1✔
3072
            for (Object item : (List) value) {
1✔
3073
                values.add(item instanceof Map ? forceAttributeUsage((Map) item) : item);
1✔
3074
            }
1✔
3075
            result = values;
1✔
3076
        } else if (value instanceof Map) {
1✔
3077
            result = forceAttributeUsage((Map) value);
1✔
3078
        } else {
3079
            result = value;
1✔
3080
        }
3081
        return result;
1✔
3082
    }
3083

3084
    public static Map<String, Object> replaceNullWithEmptyValue(Map<String, Object> map) {
3085
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3086
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3087
            outMap.put(
1✔
3088
                    entry.getKey(),
1✔
3089
                    entry.getValue() == null
1✔
3090
                            ? newLinkedHashMap()
1✔
3091
                            : makeReplaceNullValue(entry.getValue()));
1✔
3092
        }
1✔
3093
        return outMap;
1✔
3094
    }
3095

3096
    @SuppressWarnings("unchecked")
3097
    private static Object makeReplaceNullValue(Object value) {
3098
        final Object result;
3099
        if (value instanceof List) {
1✔
3100
            List<Object> values = newArrayList();
1✔
3101
            for (Object item : (List) value) {
1✔
3102
                values.add(item instanceof Map ? replaceNullWithEmptyValue((Map) item) : item);
1✔
3103
            }
1✔
3104
            result = values;
1✔
3105
        } else if (value instanceof Map) {
1✔
3106
            result = replaceNullWithEmptyValue((Map) value);
1✔
3107
        } else {
3108
            result = value;
1✔
3109
        }
3110
        return result;
1✔
3111
    }
3112

3113
    public static Map<String, Object> replaceEmptyStringWithEmptyValue(Map<String, Object> map) {
3114
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3115
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3116
            outMap.put(
1✔
3117
                    entry.getKey(),
1✔
3118
                    "".equals(entry.getValue())
1✔
3119
                            ? newLinkedHashMap()
1✔
3120
                            : makeReplaceEmptyString(entry.getValue()));
1✔
3121
        }
1✔
3122
        return outMap;
1✔
3123
    }
3124

3125
    @SuppressWarnings("unchecked")
3126
    private static Object makeReplaceEmptyString(Object value) {
3127
        final Object result;
3128
        if (value instanceof List) {
1✔
3129
            List<Object> values = newArrayList();
1✔
3130
            for (Object item : (List) value) {
1✔
3131
                values.add(
1✔
3132
                        item instanceof Map ? replaceEmptyStringWithEmptyValue((Map) item) : item);
1✔
3133
            }
1✔
3134
            result = values;
1✔
3135
        } else if (value instanceof Map) {
1✔
3136
            result = replaceEmptyStringWithEmptyValue((Map) value);
1✔
3137
        } else {
3138
            result = value;
1✔
3139
        }
3140
        return result;
1✔
3141
    }
3142

3143
    public static Map<String, Object> replaceNumberAndBooleanWithString(Map<String, Object> map) {
3144
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3145
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3146
            outMap.put(
1✔
3147
                    entry.getKey(),
1✔
3148
                    entry.getValue() instanceof Boolean || entry.getValue() instanceof Number
1✔
3149
                            ? String.valueOf(entry.getValue())
1✔
3150
                            : makeReplaceNumberAndBoolean(entry.getValue()));
1✔
3151
        }
1✔
3152
        return outMap;
1✔
3153
    }
3154

3155
    @SuppressWarnings("unchecked")
3156
    private static Object makeReplaceNumberAndBoolean(Object value) {
3157
        final Object result;
3158
        if (value instanceof List) {
1✔
3159
            List<Object> values = newArrayList();
1✔
3160
            for (Object item : (List) value) {
1✔
3161
                if (item instanceof Map) {
1✔
3162
                    values.add(replaceNumberAndBooleanWithString((Map) item));
1✔
3163
                } else if (item instanceof Number || item instanceof Boolean || isNull(item)) {
1✔
3164
                    values.add(String.valueOf(item));
1✔
3165
                } else {
3166
                    values.add(item);
1✔
3167
                }
3168
            }
1✔
3169
            result = values;
1✔
3170
        } else if (value instanceof Map) {
1✔
3171
            result = replaceNumberAndBooleanWithString((Map) value);
1✔
3172
        } else if (isNull(value)) {
1✔
3173
            result = "null";
1✔
3174
        } else {
3175
            result = value;
1✔
3176
        }
3177
        return result;
1✔
3178
    }
3179

3180
    public static Map<String, Object> replaceFirstLevel(Map<String, Object> map) {
3181
        return replaceFirstLevel(map, 0);
1✔
3182
    }
3183

3184
    @SuppressWarnings("unchecked")
3185
    public static Map<String, Object> replaceFirstLevel(Map<String, Object> map, int level) {
3186
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3187
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3188
            outMap.put(entry.getKey(), makeReplaceFirstLevel(entry.getValue(), level + 1));
1✔
3189
        }
1✔
3190
        if (level == 0 && Xml.XmlValue.getMapValue(outMap) instanceof Map) {
1✔
3191
            Map<String, Object> outMap2 = (Map<String, Object>) Xml.XmlValue.getMapValue(outMap);
1✔
3192
            if (selfClosing.equals(Xml.XmlValue.getMapKey(outMap2))
1✔
3193
                    && "true".equals(Xml.XmlValue.getMapValue(outMap2))) {
1✔
3194
                outMap2.remove(selfClosing);
1✔
3195
            }
3196
            return outMap2;
1✔
3197
        }
3198
        return outMap;
1✔
3199
    }
3200

3201
    @SuppressWarnings("unchecked")
3202
    private static Object makeReplaceFirstLevel(Object value, int level) {
3203
        final Object result;
3204
        if (value instanceof List) {
1✔
3205
            List<Object> values = newArrayList();
1✔
3206
            for (Object item : (List) value) {
1✔
3207
                values.add(item instanceof Map ? replaceFirstLevel((Map) item, level + 1) : item);
1✔
3208
            }
1✔
3209
            result = values;
1✔
3210
        } else if (value instanceof Map) {
1✔
3211
            result = replaceFirstLevel((Map) value, level + 1);
1✔
3212
        } else {
3213
            result = value;
1✔
3214
        }
3215
        return result;
1✔
3216
    }
3217

3218
    public static Map<String, Object> replaceNilWithNull(Map<String, Object> map) {
3219
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3220
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3221
            Object outValue = makeReplaceNilWithNull(entry.getValue());
1✔
3222
            if (outValue instanceof Map
1✔
3223
                    && (nilKey.equals(Xml.XmlValue.getMapKey(outValue))
1✔
3224
                            || Xml.XmlValue.getMapKey(outValue).endsWith(":nil"))
1✔
3225
                    && "true".equals(Xml.XmlValue.getMapValue(outValue))
1✔
3226
                    && ((Map) outValue).containsKey(selfClosing)
1✔
3227
                    && "true".equals(((Map) outValue).get(selfClosing))) {
1✔
3228
                outValue = null;
1✔
3229
            }
3230
            outMap.put(entry.getKey(), outValue);
1✔
3231
        }
1✔
3232
        return outMap;
1✔
3233
    }
3234

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

3252
    public static Map<String, Object> deepCopyMap(Map<String, Object> map) {
3253
        Map<String, Object> outMap = newLinkedHashMap();
1✔
3254
        for (Map.Entry<String, Object> entry : map.entrySet()) {
1✔
3255
            outMap.put(entry.getKey(), makeDeepCopyMap(entry.getValue()));
1✔
3256
        }
1✔
3257
        return outMap;
1✔
3258
    }
3259

3260
    @SuppressWarnings("unchecked")
3261
    private static Object makeDeepCopyMap(Object value) {
3262
        final Object result;
3263
        if (value instanceof List) {
1✔
3264
            List<Object> values = newArrayList();
1✔
3265
            for (Object item : (List) value) {
1✔
3266
                values.add(item instanceof Map ? deepCopyMap((Map) item) : item);
1✔
3267
            }
1✔
3268
            result = values;
1✔
3269
        } else if (value instanceof Map) {
1✔
3270
            result = deepCopyMap((Map) value);
1✔
3271
        } else {
3272
            result = value;
1✔
3273
        }
3274
        return result;
1✔
3275
    }
3276

3277
    public static Builder objectBuilder() {
3278
        return new U.Builder();
1✔
3279
    }
3280

3281
    public static class Builder {
3282
        private final Map<String, Object> data;
3283

3284
        public Builder() {
1✔
3285
            data = newLinkedHashMap();
1✔
3286
        }
1✔
3287

3288
        public Builder add(final String key, final Object value) {
3289
            data.put(key, value);
1✔
3290
            return this;
1✔
3291
        }
3292

3293
        public Builder add(final Object value) {
3294
            data.put(String.valueOf(data.size()), value);
1✔
3295
            return this;
1✔
3296
        }
3297

3298
        public <T> T get(final String path) {
3299
            return U.get(data, path);
1✔
3300
        }
3301

3302
        public <T> T get(final List<String> paths) {
3303
            return U.get(data, paths);
1✔
3304
        }
3305

3306
        public Builder set(final String path, final Object value) {
3307
            U.set(data, path, value);
1✔
3308
            return this;
1✔
3309
        }
3310

3311
        public Builder set(final List<String> paths, final Object value) {
3312
            U.set(data, paths, value);
1✔
3313
            return this;
1✔
3314
        }
3315

3316
        public Builder remove(final String key) {
3317
            U.remove(data, key);
1✔
3318
            return this;
1✔
3319
        }
3320

3321
        public Builder remove(final List<String> keys) {
3322
            U.remove(data, keys);
1✔
3323
            return this;
1✔
3324
        }
3325

3326
        public Builder clear() {
3327
            data.clear();
1✔
3328
            return this;
1✔
3329
        }
3330

3331
        public boolean isEmpty() {
3332
            return data.isEmpty();
1✔
3333
        }
3334

3335
        public int size() {
3336
            return data.size();
1✔
3337
        }
3338

3339
        public Builder add(final Builder builder) {
3340
            data.put(String.valueOf(data.size()), builder.build());
1✔
3341
            return this;
1✔
3342
        }
3343

3344
        public Builder add(final String key, final ArrayBuilder builder) {
3345
            data.put(key, builder.build());
1✔
3346
            return this;
1✔
3347
        }
3348

3349
        public Builder add(final String key, final Builder builder) {
3350
            data.put(key, builder.build());
1✔
3351
            return this;
1✔
3352
        }
3353

3354
        public Builder add(final Map<String, Object> map) {
3355
            data.putAll(deepCopyMap(map));
1✔
3356
            return this;
1✔
3357
        }
3358

3359
        public Builder update(final Map<String, Object> map) {
3360
            U.update(data, deepCopyMap(map));
1✔
3361
            return this;
1✔
3362
        }
3363

3364
        public Builder addNull(final String key) {
3365
            data.put(key, null);
1✔
3366
            return this;
1✔
3367
        }
3368

3369
        @SuppressWarnings("unchecked")
3370
        public Map<String, Object> build() {
3371
            return (Map<String, Object>) ((LinkedHashMap) data).clone();
1✔
3372
        }
3373

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

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

3384
        public static Builder fromMap(final Map<String, Object> map) {
3385
            final Builder builder = new Builder();
1✔
3386
            builder.data.putAll(deepCopyMap(map));
1✔
3387
            return builder;
1✔
3388
        }
3389

3390
        public String toJson() {
3391
            return Json.toJson(data);
1✔
3392
        }
3393

3394
        public static Builder fromJson(final String json) {
3395
            final Builder builder = new Builder();
1✔
3396
            builder.data.putAll(fromJsonMap(json));
1✔
3397
            return builder;
1✔
3398
        }
3399

3400
        public Chain<Object> toChain() {
3401
            return new U.Chain<>(data.entrySet());
1✔
3402
        }
3403

3404
        @Override
3405
        public String toString() {
3406
            return data.toString();
1✔
3407
        }
3408
    }
3409

3410
    public static ArrayBuilder arrayBuilder() {
3411
        return new U.ArrayBuilder();
1✔
3412
    }
3413

3414
    public static class ArrayBuilder {
3415
        private final List<Object> data;
3416

3417
        public ArrayBuilder() {
1✔
3418
            data = newArrayList();
1✔
3419
        }
1✔
3420

3421
        public ArrayBuilder add(final Object value) {
3422
            data.add(value);
1✔
3423
            return this;
1✔
3424
        }
3425

3426
        public ArrayBuilder addNull() {
3427
            data.add(null);
1✔
3428
            return this;
1✔
3429
        }
3430

3431
        public <T> T get(final String path) {
3432
            return U.get(U.getStringObjectMap(data), "value." + path);
1✔
3433
        }
3434

3435
        public <T> T get(final List<String> paths) {
3436
            List<String> newPaths = new ArrayList<>();
1✔
3437
            newPaths.add("value");
1✔
3438
            newPaths.addAll(paths);
1✔
3439
            return U.get(U.getStringObjectMap(data), newPaths);
1✔
3440
        }
3441

3442
        public ArrayBuilder set(final int index, final Object value) {
3443
            data.set(index, value);
1✔
3444
            return this;
1✔
3445
        }
3446

3447
        public ArrayBuilder remove(final int index) {
3448
            data.remove(index);
1✔
3449
            return this;
1✔
3450
        }
3451

3452
        public ArrayBuilder clear() {
3453
            data.clear();
1✔
3454
            return this;
1✔
3455
        }
3456

3457
        public boolean isEmpty() {
3458
            return data.isEmpty();
1✔
3459
        }
3460

3461
        public int size() {
3462
            return data.size();
1✔
3463
        }
3464

3465
        public ArrayBuilder add(final ArrayBuilder builder) {
3466
            data.addAll(builder.build());
1✔
3467
            return this;
1✔
3468
        }
3469

3470
        public ArrayBuilder add(final Builder builder) {
3471
            data.add(builder.build());
1✔
3472
            return this;
1✔
3473
        }
3474

3475
        @SuppressWarnings("unchecked")
3476
        public ArrayBuilder merge(final List<Object> list) {
3477
            U.merge(data, (List<Object>) ((ArrayList) list).clone());
1✔
3478
            return this;
1✔
3479
        }
3480

3481
        @SuppressWarnings("unchecked")
3482
        public List<Object> build() {
3483
            return (List<Object>) ((ArrayList) data).clone();
1✔
3484
        }
3485

3486
        public String toXml() {
3487
            return Xml.toXml(data);
1✔
3488
        }
3489

3490
        public static ArrayBuilder fromXml(final String xml) {
3491
            final ArrayBuilder builder = new ArrayBuilder();
1✔
3492
            builder.data.addAll(U.<List<Object>>fromXml(xml));
1✔
3493
            return builder;
1✔
3494
        }
3495

3496
        public String toJson() {
3497
            return Json.toJson(data);
1✔
3498
        }
3499

3500
        public static ArrayBuilder fromJson(final String json) {
3501
            final ArrayBuilder builder = new ArrayBuilder();
1✔
3502
            builder.data.addAll(U.<List<Object>>fromJson(json));
1✔
3503
            return builder;
1✔
3504
        }
3505

3506
        public Chain<Object> toChain() {
3507
            return new U.Chain<>(data);
1✔
3508
        }
3509

3510
        @Override
3511
        public String toString() {
3512
            return data.toString();
1✔
3513
        }
3514
    }
3515
}
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