Codebase list libcommons-lang3-java / 906d274
New upstream version 3.12.0 Emmanuel Bourg 1 year, 11 months ago
200 changed file(s) with 15994 addition(s) and 13772 deletion(s). Raw diff Collapse all Expand all
0 # Licensed to the Apache Software Foundation (ASF) under one or more
1 # contributor license agreements. See the NOTICE file distributed with
2 # this work for additional information regarding copyright ownership.
3 # The ASF licenses this file to You under the Apache License, Version 2.0
4 # (the "License"); you may not use this file except in compliance with
5 # the License. You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 version: 2
16 updates:
17 - package-ecosystem: "maven"
18 directory: "/"
19 schedule:
20 interval: "daily"
21 - package-ecosystem: "github-actions"
22 directory: "/"
23 schedule:
24 interval: "daily"
1414
1515 name: Java CI
1616
17 on: [push]
17 on: [push, pull_request]
1818
1919 jobs:
2020 build:
2121
2222 runs-on: ubuntu-latest
23 continue-on-error: ${{ matrix.experimental }}
2324 strategy:
2425 matrix:
25 java: [ 8, 11, 12, 13, 14 ]
26 java: [ 8, 11, 15 ]
27 experimental: [false]
28 include:
29 - java: 16-ea
30 experimental: true
31 - java: 17-ea
32 experimental: true
2633
2734 steps:
28 - uses: actions/checkout@v1
35 - uses: actions/checkout@v2.3.4
36 - uses: actions/cache@v2.1.4
37 with:
38 path: ~/.m2/repository
39 key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
40 restore-keys: |
41 ${{ runner.os }}-maven-
2942 - name: Set up JDK ${{ matrix.java }}
30 uses: actions/setup-java@v1
43 uses: actions/setup-java@v1.4.3
3144 with:
3245 java-version: ${{ matrix.java }}
3346 - name: Build with Maven
34 run: mvn -V apache-rat:check spotbugs:check javadoc:javadoc -Ddoclint=all package --file pom.xml
47 run: mvn -V -Ddoclint=all --file pom.xml --no-transfer-progress
1313 # limitations under the License.
1414
1515 language: java
16
1617 cache:
1718 directories:
1819 - $HOME/.m2
20
1921 jdk:
2022 - openjdk8
2123 - openjdk11
22 - openjdk14
24 - openjdk15
2325 - openjdk-ea
26
2427 matrix:
25 include:
26 - os: linux-ppc64le
27 jdk: openjdk8
2828 allow_failures:
2929 - jdk: openjdk-ea
30
3031 script:
31 - mvn
32 - mvn -V --no-transfer-progress
33
3234 after_success:
33 - mvn clean test jacoco:report coveralls:report -Ptravis-jacoco javadoc:javadoc -Ddoclint=all
35 - mvn -V --no-transfer-progress clean test jacoco:report coveralls:report -Ptravis-jacoco javadoc:javadoc -Ddoclint=all
00 Apache Commons Lang
1 Copyright 2001-2020 The Apache Software Foundation
1 Copyright 2001-2021 The Apache Software Foundation
22
33 This product includes software developed at
44 The Apache Software Foundation (https://www.apache.org/).
4242 Apache Commons Lang
4343 ===================
4444
45 [![Build Status](https://travis-ci.org/apache/commons-lang.svg)](https://travis-ci.org/apache/commons-lang)
45 [![Travis-CI Status](https://travis-ci.org/apache/commons-lang.svg)](https://travis-ci.org/apache/commons-lang)
46 [![GitHub Actions Status](https://github.com/apache/commons-lang/workflows/Java%20CI/badge.svg)](https://github.com/apache/commons-lang/actions)
4647 [![Coverage Status](https://coveralls.io/repos/apache/commons-lang/badge.svg)](https://coveralls.io/r/apache/commons-lang)
4748 [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-lang3/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-lang3/)
48 [![Javadocs](https://javadoc.io/badge/org.apache.commons/commons-lang3/3.11.svg)](https://javadoc.io/doc/org.apache.commons/commons-lang3/3.11)
49 [![Javadocs](https://javadoc.io/badge/org.apache.commons/commons-lang3/3.12.0.svg)](https://javadoc.io/doc/org.apache.commons/commons-lang3/3.12.0)
4950
5051 Apache Commons Lang, a package of Java utility classes for the
5152 classes that are in java.lang's hierarchy, or are considered to be so
6869 <dependency>
6970 <groupId>org.apache.commons</groupId>
7071 <artifactId>commons-lang3</artifactId>
71 <version>3.11</version>
72 <version>3.12.0</version>
7273 </dependency>
7374 ```
7475
0 Apache Commons Lang
1 Version 3.12.0
2 Release Notes
3
4 INTRODUCTION:
5
6 This document contains the release notes for the 3.12.0-SNAPSHOT version of Apache Commons Lang.
7 Commons Lang is a set of utility functions and reusable components that should be of use in any
8 Java environment.
9
10 Lang 3.9 and onwards now targets Java 8, making use of features that arrived with Java 8.
11
12 For the advice on upgrading from 2.x to 3.x, see the following page:
13
14 https://commons.apache.org/lang/article3_0.html
15
16 Apache Commons Lang, a package of Java utility classes for the
17 classes that are in java.lang's hierarchy, or are considered to be so
18 standard as to justify existence in java.lang.
19
20 New features and bug fixes.
21
22 Changes in this version include:
23
24 New features:
25 o Add BooleanUtils.booleanValues(). Thanks to Gary Gregory.
26 o Add BooleanUtils.primitiveValues(). Thanks to Gary Gregory.
27 o LANG-1535: Add StringUtils.containsAnyIgnoreCase(CharSequence, CharSequence...). Thanks to Gary Gregory, Isira Seneviratne.
28 o LANG-1359: Add StopWatch.getStopTime(). Thanks to Gary Gregory, Keegan Witt.
29 o More test coverage for CharSequenceUtils. #631. Thanks to Edgar Asatryan.
30 o Add fluent-style ArraySorter. Thanks to Gary Gregory.
31 o Add and use LocaleUtils.toLocale(Locale) to avoid NPEs. Thanks to Gary Gregory.
32 o Add FailableShortSupplier, handy for JDBC APIs. Thanks to Gary Gregory.
33 o Add JavaVersion.JAVA_17. Thanks to Gary Gregory.
34 o LANG-1636: Add missing boolean[] join method #686. Thanks to .
35 o Add StringUtils.substringBefore(String, int). Thanks to Gary Gregory.
36 o Add Range.INTEGER. Thanks to Gary Gregory.
37 o Add DurationUtils. Thanks to Gary Gregory.
38 o Introduce the use of @Nonnull, and @Nullable, and the Objects class as a helper tool.
39 o Add and use true and false String constants #714. Thanks to Arturo Bernal, Gary Gregory.
40 o Add and use ObjectUtils.requireNonEmpty() #716. Thanks to Arturo Bernal, Gary Gregory.
41
42 Fixed Bugs:
43 o LANG-1592: Correct implementation of RandomUtils.nextLong(long, long) Thanks to Huang Pingcai, Alex Herbert.
44 o LANG-1600: Restore handling of collections for non-JSON ToStringStyle #610. Thanks to Michael F.
45 o ContextedException Javadoc add missing semicolon #581. Thanks to iamchao1129.
46 o LANG-1608: Resolve JUnit pioneer transitive dependencies using JUnit BOM. Thanks to Edgar Asatryan.
47 o NumberUtilsTest - incorrect types in min/max tests #634. Thanks to HubertWo, Gary Gregory.
48 o LANG-1579: Improve StringUtils.stripAccents conversion of remaining accents. Thanks to XenoAmess.
49 o LANG-1606: StringUtils.countMatches - clarify Javadoc. Thanks to Rustem Galiev.
50 o LANG-1591: Remove redundant argument from substring call. Thanks to bhawna94.
51 o LANG-1613: BigDecimal is created when you pass it the min and max values, #642. Thanks to Arturo Bernal, Gary Gregory.
52 o LANG-1541: ArrayUtils.contains() and indexOf() fail to handle Double.NaN #647. Thanks to Arturo Bernal, Gary Gregory.
53 o LANG-1615: ArrayUtils contains() and indexOf() fail to handle Float.NaN # #561. Thanks to Arturo Bernal, Gary Gregory.
54 o Fix potential NPE in TypeUtils.isAssignable(Type, ParameterizedType, Map, Type>). Thanks to Gary Gregory.
55 o LANG-1420: TypeUtils.isAssignable returns wrong result for GenericArrayType and ParameterizedType, #643. Thanks to Gordon Fraser, Rostislav Krasny, Arturo Bernal, Gary Gregory.
56 o LANG-1612: testGetAllFields and testGetFieldsWithAnnotation sometimes fail. Thanks to XinT, Gary Gregory.
57 o Fix Javadoc for SystemUtils.isJavaVersionAtMost() #638. Thanks to John R. D'Orazio.
58 o LANG-1610: Fix StringUtils.unwrap throws StringIndexOutOfBoundsException #636. Thanks to Tony Liang.
59 o Fix formatting of isAnyBlank() and isAnyEmpty(). #513. Thanks to Isira Seneviratne.
60 o LANG-1618: TypeUtils. containsTypeVariables does not support GenericArrayType #661. Thanks to Arturo Bernal.
61 o LANG-1622: Javadoc of some methods incorrectly refers to another method, #667, #668. #670. Thanks to Kanak Sony, anomen-s.
62 o LANG-1620: Refine StringUtils.lastIndexOfIgnoreCase #664. Thanks to Arturo Bernal.
63 o LANG-1619: Refine StringUtils.abbreviate #663. Thanks to Arturo Bernal.
64 o LANG-1584: Refine StringUtils.isNumericSpace #573. Thanks to Arturo Bernal.
65 o LANG-1580: Refine StringUtils.deleteWhitespace #569. Thanks to Arturo Bernal.
66 o LANG-1626: Correction in Javadoc of some methods. #673 Thanks to Kanak Sony.
67 o LANG-1628: Javadoc for RandomStringUtils.random() letters, numbers parameters is wrong. Thanks to Jarkko Rantavuori.
68 o Correct markup in Javadoc for unbalanced braces #679. Thanks to Felix Schumacher.
69 o LANG-1544: MethodUtils.invokeMethod NullPointerException in case of null in args list #680. Thanks to Peter Nagy, Michael Buck, Gary Gregory.
70 o LANG-1637: Fix 2 digit week year formatting #688. Thanks to Uri Gonen, Gary Gregory, Michael Osipov.
71 o Fix broken Javadoc links to commons-text #712. Thanks to Chris Smowton.
72 o Add and use ThreadUtils.sleep(Duration). Thanks to Gary Gregory.
73 o Add and use ThreadUtils.join(Thread, Duration). Thanks to Gary Gregory.
74 o Add ObjectUtils.wait(Duration). Thanks to Gary Gregory.
75
76 Changes:
77 o LANG-1596: ArrayUtils.toPrimitive(Object) does not support boolean and other types #607. Thanks to Richard Eckart de Castilho.
78 o Enable Dependabot #587. Thanks to Gary Gregory.
79 o Bump junit-jupiter from 5.6.2 to 5.7.0.
80 o Bump spotbugs from 4.1.2 to 4.2.1, #627, #671, #708. Thanks to chtompki, Dependabot.
81 o Bump spotbugs-maven-plugin from 4.0.0 to 4.2.0, #593, #596, #609, #623, #632, #692. Thanks to Dependabot.
82 o Bump biz.aQute.bndlib from 5.1.1 to 5.3.0 #592, #628, #715. Thanks to Dependabot.
83 o Bump junit-pioneer from 0.6.0 to 1.1.0, #589, #597, #600, #624, #625, #662. Thanks to Dependabot.
84 o Bump checkstyle from 8.34 to 8.40, #594, #614, #637, #665, #706. Thanks to Dependabot.
85 o Bump actions/checkout from v2.3.1 to v2.3.4 #601, #639. Thanks to Dependabot.
86 o Bump actions/setup-java from v1.4.0 to v1.4.2 #612. Thanks to Dependabot.
87 o Update commons.jacoco.version 0.8.5 to 0.8.6 (Fixes Java 15 builds). Thanks to Gary Gregory.
88 o Update maven-surefire-plugin 2.22.2 -> 3.0.0-M5. Thanks to Gary Gregory.
89 o Bump maven-pmd-plugin from 3.13.0 to 3.14.0 #660. Thanks to Dependabot.
90 o Bump jmh.version from 1.21 to 1.27 #674. Thanks to Dependabot.
91 o Update commons.japicmp.version 0.14.3 -> 0.15.2. Thanks to Gary Gregory.
92 o Processor.java: check enum equality with == instead of .equals() method #690. Thanks to Ali K. Nouri.
93 o Bump junit-pioneer from 1.1.0 to 1.3.0 #702. Thanks to Dependabot.
94 o Bump maven-checkstyle-plugin from 3.1.1 to 3.1.2 #705. Thanks to Dependabot.
95 o Bump actions/cache from v2 to v2.1.4 #710. Thanks to Dependabot.
96 o Bump junit-bom from 5.7.0 to 5.7.1 #707. Thanks to Dependabot.
97 o Minor Improvements #701. Thanks to Arturo Bernal.
98 o Minor Improvement: Add final variable.try to make the code read-only #700. Thanks to Arturo Bernal.
99 o Minor Improvement: Remove redundant initializer #699. Thanks to Arturo Bernal.
100 o Use own validator ObjectUtils.anyNull to check null String input #718. Thanks to Arturo Bernal.
101
102
103 Historical list of changes: https://commons.apache.org/proper/commons-lang/changes-report.html
104
105 For complete information on Apache Commons Lang, including instructions on how to submit bug reports,
106 patches, or suggestions for improvement, see the Apache Apache Commons Lang website:
107
108 https://commons.apache.org/proper/commons-lang/
109
110 Download page: https://commons.apache.org/proper/commons-lang/download_lang.cgi
111
112 Have fun!
113 -Apache Commons Team
114
115 =============================================================================
116
0117 Apache Commons Lang
1118 Version 3.11
2119 Release Notes
0 <!---
1 Licensed to the Apache Software Foundation (ASF) under one or more
2 contributor license agreements. See the NOTICE file distributed with
3 this work for additional information regarding copyright ownership.
4 The ASF licenses this file to You under the Apache License, Version 2.0
5 (the "License"); you may not use this file except in compliance with
6 the License. You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 -->
16 The Apache Commons security page is [https://commons.apache.org/security.html](https://commons.apache.org/security.html).
2121 <parent>
2222 <groupId>org.apache.commons</groupId>
2323 <artifactId>commons-parent</artifactId>
24 <version>51</version>
24 <version>52</version>
2525 </parent>
2626 <modelVersion>4.0.0</modelVersion>
2727 <artifactId>commons-lang3</artifactId>
28 <version>3.11</version>
28 <version>3.12.0</version>
2929 <name>Apache Commons Lang</name>
3030
3131 <inceptionYear>2001</inceptionYear>
4646 <connection>scm:git:http://gitbox.apache.org/repos/asf/commons-lang.git</connection>
4747 <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/commons-lang.git</developerConnection>
4848 <url>https://gitbox.apache.org/repos/asf?p=commons-lang.git</url>
49 <tag>commons-lang-3.11</tag>
49 <tag>commons-lang-3.12.0</tag>
5050 </scm>
5151
5252 <developers>
511511 <name>Jin Xu</name>
512512 </contributor>
513513 </contributors>
514
515 <dependencyManagement>
516 <dependencies>
517 <dependency>
518 <groupId>org.junit</groupId>
519 <artifactId>junit-bom</artifactId>
520 <version>5.7.1</version>
521 <type>pom</type>
522 <scope>import</scope>
523 </dependency>
524 </dependencies>
525 </dependencyManagement>
514526
515527 <!-- Lang should depend on very little -->
516528 <dependencies>
518530 <dependency>
519531 <groupId>org.junit.jupiter</groupId>
520532 <artifactId>junit-jupiter</artifactId>
521 <version>5.6.2</version>
522533 <scope>test</scope>
523534 </dependency>
524535 <dependency>
525536 <groupId>org.junit-pioneer</groupId>
526537 <artifactId>junit-pioneer</artifactId>
527 <version>0.6.0</version>
538 <version>1.3.0</version>
528539 <scope>test</scope>
529540 </dependency>
530541 <dependency>
554565 <version>${jmh.version}</version>
555566 <scope>test</scope>
556567 </dependency>
557
568 <dependency>
569 <groupId>com.google.code.findbugs</groupId>
570 <artifactId>jsr305</artifactId>
571 <version>3.0.2</version>
572 <scope>test</scope>
573 </dependency>
558574 </dependencies>
559575
560576 <distributionManagement>
586602 <commons.packageId>lang3</commons.packageId>
587603 <commons.module.name>org.apache.commons.lang3</commons.module.name>
588604 <!-- Current 3.x release series -->
589 <commons.release.version>3.11</commons.release.version>
605 <commons.release.version>3.12.0</commons.release.version>
590606 <commons.release.desc>(Java 8+)</commons.release.desc>
591607 <!-- Previous 2.x release series -->
592608 <commons.release.2.version>2.6</commons.release.2.version>
601617 <commons.scmPubCheckoutDirectory>site-content</commons.scmPubCheckoutDirectory>
602618 <commons.encoding>utf-8</commons.encoding>
603619
604 <checkstyle.plugin.version>3.1.1</checkstyle.plugin.version>
605 <checkstyle.version>8.34</checkstyle.version>
620 <checkstyle.plugin.version>3.1.2</checkstyle.plugin.version>
621 <checkstyle.version>8.40</checkstyle.version>
606622 <checkstyle.configdir>src/site/resources/checkstyle</checkstyle.configdir>
607623
608 <spotbugs.plugin.version>4.0.0</spotbugs.plugin.version>
609 <spotbugs.impl.version>4.0.6</spotbugs.impl.version>
624 <spotbugs.plugin.version>4.2.0</spotbugs.plugin.version>
625 <spotbugs.impl.version>4.2.1</spotbugs.impl.version>
610626 <japicmp.skip>false</japicmp.skip>
611627 <clirr.skip>true</clirr.skip>
612628
613629 <!-- JMH Benchmark related properties, version, target compiler and name of the benchmarking uber jar. -->
614 <jmh.version>1.21</jmh.version>
630 <jmh.version>1.27</jmh.version>
615631 <uberjar.name>benchmarks</uberjar.name>
616632
617 <commons.jacoco.version>0.8.5</commons.jacoco.version>
633 <commons.jacoco.version>0.8.6</commons.jacoco.version>
618634 <commons.surefire.version>3.0.0-M5</commons.surefire.version>
619635 <commons.javadoc.version>3.2.0</commons.javadoc.version>
620
621 <!-- never generate report if there are binary incompatible changes -->
622 <commons.japicmp.breakBuildOnBinaryIncompatibleModifications>true</commons.japicmp.breakBuildOnBinaryIncompatibleModifications>
623 <commons.japicmp.version>0.14.3</commons.japicmp.version>
636 <commons.japicmp.version>0.15.2</commons.japicmp.version>
624637
625638 <!-- Commons Release Plugin -->
626 <commons.bc.version>3.10</commons.bc.version>
627 <commons.rc.version>RC2</commons.rc.version>
639 <commons.bc.version>3.11</commons.bc.version>
640 <commons.rc.version>RC1</commons.rc.version>
628641 <commons.release.isDistModule>true</commons.release.isDistModule>
629642 <commons.distSvnStagingUrl>scm:svn:https://dist.apache.org/repos/dist/dev/commons/lang</commons.distSvnStagingUrl>
630643 <commons.releaseManagerName>Gary Gregory</commons.releaseManagerName>
633646
634647
635648 <build>
636 <defaultGoal>clean verify apache-rat:check checkstyle:check japicmp:cmp spotbugs:check javadoc:javadoc</defaultGoal>
649 <defaultGoal>clean package apache-rat:check checkstyle:check japicmp:cmp spotbugs:check javadoc:javadoc</defaultGoal>
637650 <pluginManagement>
638651 <plugins>
639652 <plugin>
647660 <exclude>src/site/resources/release-notes/RELEASE-NOTES-*.txt</exclude>
648661 <exclude>src/test/resources/lang-708-input.txt</exclude>
649662 </excludes>
650 </configuration>
651 </plugin>
652 <!-- override skip property of parent pom -->
653 <plugin>
654 <groupId>com.github.siom79.japicmp</groupId>
655 <artifactId>japicmp-maven-plugin</artifactId>
656 <configuration>
657 <skip>false</skip>
658663 </configuration>
659664 </plugin>
660665 </plugins>
691696 <plugin>
692697 <groupId>org.apache.maven.plugins</groupId>
693698 <artifactId>maven-surefire-plugin</artifactId>
699 <version>${commons.surefire.version}</version>
694700 <executions>
695701 <execution>
696702 <id>plain</id>
781787 <dependency>
782788 <groupId>biz.aQute.bnd</groupId>
783789 <artifactId>biz.aQute.bndlib</artifactId>
784 <version>5.1.1</version>
790 <version>5.3.0</version>
785791 </dependency>
786792 </dependencies>
787793 </plugin>
817823 </plugin>
818824 <plugin>
819825 <artifactId>maven-pmd-plugin</artifactId>
820 <version>3.13.0</version>
826 <version>3.14.0</version>
821827 <configuration>
822828 <targetJdk>${maven.compiler.target}</targetJdk>
823829 </configuration>
937943 <jacoco.skip>true</jacoco.skip>
938944 </properties>
939945 </profile>
946 <profile>
947 <id>java15</id>
948 <activation>
949 <!-- This is ONLY activated for Java 15 -->
950 <jdk>15</jdk>
951 </activation>
952 <build>
953 <plugins>
954 <plugin>
955 <groupId>org.apache.maven.plugins</groupId>
956 <artifactId>maven-surefire-plugin</artifactId>
957 <configuration>
958 <excludes>
959 <exclude>org/apache/commons/lang3/time/Java15BugFastDateParserTest.java</exclude>
960 </excludes>
961 </configuration>
962 </plugin>
963 </plugins>
964 </build>
965 </profile>
940966
941967 <profile>
942968 <id>benchmark</id>
152152 <Method name="compare" />
153153 <Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" />
154154 </Match>
155
156 <!-- Reason: requireNonNull is supposed to take a nullable parameter,
157 whatever Spotbugs thinks of it. -->
158 <Match>
159 <Class name="org.apache.commons.lang3.function.Objects" />
160 <Method name="requireNonNull" />
161 <Bug pattern="NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE" />
162 </Match>
155163 </FindBugsFilter>
1919 This file is also used by the maven-changes-plugin to generate the release notes.
2020 Useful ways of finding items to add to this file are:
2121
22 1. Add items when you fix a bug or add a feature (this makes the
22 1. Add items when you fix a bug or add a feature (this makes the
2323 release process easy :-).
2424
2525 2. Do a JIRA search for tickets closed since the previous release.
3131
3232 mvn changes:announcement-generate -Prelease-notes [-Dchanges.version=nnn]
3333
34 then tweak the formatting if necessary
34 then tweak the formatting if necessary
3535 and commit
3636
3737 The <action> type attribute can be add,update,fix,remove.
4444 </properties>
4545 <body>
4646
47 <release version="3.12.0" date="2020-02-26" description="New features and bug fixes.">
48 <!-- FIX -->
49 <action issue="LANG-1592" type="fix" dev="aherbert" due-to="Huang Pingcai, Alex Herbert">Correct implementation of RandomUtils.nextLong(long, long)</action>
50 <action issue="LANG-1600" type="fix" dev="ggregory" due-to="Michael F">Restore handling of collections for non-JSON ToStringStyle #610.</action>
51 <action type="fix" dev="ggregory" due-to="iamchao1129">ContextedException Javadoc add missing semicolon #581.</action>
52 <action issue="LANG-1608" type="fix" dev="aherbert" due-to="Edgar Asatryan">Resolve JUnit pioneer transitive dependencies using JUnit BOM.</action>
53 <action type="fix" dev="aherbert" due-to="HubertWo, Gary Gregory">NumberUtilsTest - incorrect types in min/max tests #634.</action>
54 <action issue="LANG-1579" type="fix" dev="aherbert" due-to="XenoAmess">Improve StringUtils.stripAccents conversion of remaining accents.</action>
55 <action issue="LANG-1606" type="fix" dev="sebb" due-to="Rustem Galiev">StringUtils.countMatches - clarify Javadoc.</action>
56 <action issue="LANG-1591" type="fix" dev="kinow" due-to="bhawna94">Remove redundant argument from substring call.</action>
57 <action issue="LANG-1613" type="fix" dev="ggregory" due-to="Arturo Bernal, Gary Gregory">BigDecimal is created when you pass it the min and max values, #642.</action>
58 <action issue="LANG-1541" type="fix" dev="ggregory" due-to="Arturo Bernal, Gary Gregory">ArrayUtils.contains() and indexOf() fail to handle Double.NaN #647.</action>
59 <action issue="LANG-1615" type="fix" dev="ggregory" due-to="Arturo Bernal, Gary Gregory">ArrayUtils contains() and indexOf() fail to handle Float.NaN # #561.</action>
60 <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix potential NPE in TypeUtils.isAssignable(Type, ParameterizedType, Map, Type>).</action>
61 <action issue="LANG-1420" type="fix" dev="ggregory" due-to="Gordon Fraser, Rostislav Krasny, Arturo Bernal, Gary Gregory">TypeUtils.isAssignable returns wrong result for GenericArrayType and ParameterizedType, #643.</action>
62 <action issue="LANG-1612" type="fix" dev="ggregory" due-to="XinT, Gary Gregory">testGetAllFields and testGetFieldsWithAnnotation sometimes fail.</action>
63 <action type="fix" dev="ggregory" due-to="John R. D'Orazio">Fix Javadoc for SystemUtils.isJavaVersionAtMost() #638.</action>
64 <action issue="LANG-1610" type="fix" dev="ggregory" due-to="Tony Liang">Fix StringUtils.unwrap throws StringIndexOutOfBoundsException #636.</action>
65 <action type="fix" dev="ggregory" due-to="Isira Seneviratne">Fix formatting of isAnyBlank() and isAnyEmpty(). #513.</action>
66 <action issue="LANG-1618" type="fix" dev="ggregory" due-to="Arturo Bernal">TypeUtils. containsTypeVariables does not support GenericArrayType #661.</action>
67 <action issue="LANG-1622" type="fix" dev="ggregory" due-to="Kanak Sony, anomen-s">Javadoc of some methods incorrectly refers to another method, #667, #668. #670.</action>
68 <action issue="LANG-1620" type="fix" dev="ggregory" due-to="Arturo Bernal">Refine StringUtils.lastIndexOfIgnoreCase #664.</action>
69 <action issue="LANG-1619" type="fix" dev="ggregory" due-to="Arturo Bernal">Refine StringUtils.abbreviate #663.</action>
70 <action issue="LANG-1584" type="fix" dev="ggregory" due-to="Arturo Bernal">Refine StringUtils.isNumericSpace #573.</action>
71 <action issue="LANG-1580" type="fix" dev="ggregory" due-to="Arturo Bernal">Refine StringUtils.deleteWhitespace #569.</action>
72 <action issue="LANG-1626" type="fix" dev="ggregory" due-to="Kanak Sony">Correction in Javadoc of some methods. #673</action>
73 <action issue="LANG-1628" type="fix" dev="kinow" due-to="Jarkko Rantavuori">Javadoc for RandomStringUtils.random() letters, numbers parameters is wrong.</action>
74 <action type="fix" dev="ggregory" due-to="Felix Schumacher">Correct markup in Javadoc for unbalanced braces #679.</action>
75 <action issue="LANG-1544" type="fix" dev="kinow" due-to="Peter Nagy, Michael Buck, Gary Gregory">MethodUtils.invokeMethod NullPointerException in case of null in args list #680.</action>
76 <action issue="LANG-1637" type="fix" dev="ggregory" due-to="Uri Gonen, Gary Gregory, Michael Osipov">Fix 2 digit week year formatting #688.</action>
77 <action type="fix" dev="ggregory" due-to="Chris Smowton">Fix broken Javadoc links to commons-text #712.</action>
78 <action type="fix" dev="ggregory" due-to="Gary Gregory">Add and use ThreadUtils.sleep(Duration).</action>
79 <action type="fix" dev="ggregory" due-to="Gary Gregory">Add and use ThreadUtils.join(Thread, Duration).</action>
80 <action type="fix" dev="ggregory" due-to="Gary Gregory">Add ObjectUtils.wait(Duration).</action>
81 <!-- ADD -->
82 <action type="add" dev="ggregory" due-to="Gary Gregory">Add BooleanUtils.booleanValues().</action>
83 <action type="add" dev="ggregory" due-to="Gary Gregory">Add BooleanUtils.primitiveValues().</action>
84 <action issue="LANG-1535" type="add" dev="ggregory" due-to="Gary Gregory, Isira Seneviratne">Add StringUtils.containsAnyIgnoreCase(CharSequence, CharSequence...).</action>
85 <action issue="LANG-1359" type="add" dev="ggregory" due-to="Gary Gregory, Keegan Witt">Add StopWatch.getStopTime().</action>
86 <action type="add" dev="ggregory" due-to="Edgar Asatryan">More test coverage for CharSequenceUtils. #631.</action>
87 <action issue="LANG-1596" type="update" dev="aherbert" due-to="Richard Eckart de Castilho">ArrayUtils.toPrimitive(Object) does not support boolean and other types #607.</action>
88 <action type="add" dev="ggregory" due-to="Gary Gregory">Add fluent-style ArraySorter.</action>
89 <action type="add" dev="ggregory" due-to="Gary Gregory">Add and use LocaleUtils.toLocale(Locale) to avoid NPEs.</action>
90 <action type="add" dev="ggregory" due-to="Gary Gregory">Add FailableShortSupplier, handy for JDBC APIs.</action>
91 <action type="add" dev="ggregory" due-to="Gary Gregory">Add JavaVersion.JAVA_17.</action>
92 <action issue="LANG-1636" type="add" dev="ggregory" due-to="">Add missing boolean[] join method #686.</action>
93 <action type="add" dev="ggregory" due-to="Gary Gregory">Add StringUtils.substringBefore(String, int).</action>
94 <action type="add" dev="ggregory" due-to="Gary Gregory">Add Range.INTEGER.</action>
95 <action type="add" dev="ggregory" due-to="Gary Gregory">Add DurationUtils.</action>
96 <action type="add" dev="jochen">Introduce the use of @Nonnull, and @Nullable, and the Objects class as a helper tool.</action>
97 <action type="add" dev="ggregory" due-to="Arturo Bernal, Gary Gregory">Add and use true and false String constants #714.</action>
98 <action type="add" dev="ggregory" due-to="Arturo Bernal, Gary Gregory">Add and use ObjectUtils.requireNonEmpty() #716.</action>
99 <!-- UPDATE -->
100 <action type="update" dev="ggregory" due-to="Gary Gregory">Enable Dependabot #587.</action>
101 <action type="update" dev="chtompki">Bump junit-jupiter from 5.6.2 to 5.7.0.</action>
102 <action type="update" dev="chtompki" due-to="chtompki, Dependabot">Bump spotbugs from 4.1.2 to 4.2.1, #627, #671, #708.</action>
103 <action type="update" dev="ggregory" due-to="Dependabot">Bump spotbugs-maven-plugin from 4.0.0 to 4.2.0, #593, #596, #609, #623, #632, #692.</action>
104 <action type="update" dev="ggregory" due-to="Dependabot">Bump biz.aQute.bndlib from 5.1.1 to 5.3.0 #592, #628, #715.</action>
105 <action type="update" dev="ggregory" due-to="Dependabot">Bump junit-pioneer from 0.6.0 to 1.1.0, #589, #597, #600, #624, #625, #662.</action>
106 <action type="update" dev="ggregory" due-to="Dependabot">Bump checkstyle from 8.34 to 8.40, #594, #614, #637, #665, #706.</action>
107 <action type="update" dev="ggregory" due-to="Dependabot">Bump actions/checkout from v2.3.1 to v2.3.4 #601, #639.</action>
108 <action type="update" dev="ggregory" due-to="Dependabot">Bump actions/setup-java from v1.4.0 to v1.4.2 #612.</action>
109 <action type="update" dev="ggregory" due-to="Gary Gregory">Update commons.jacoco.version 0.8.5 to 0.8.6 (Fixes Java 15 builds).</action>
110 <action type="update" dev="ggregory" due-to="Gary Gregory">Update maven-surefire-plugin 2.22.2 -> 3.0.0-M5.</action>
111 <action type="update" dev="ggregory" due-to="Dependabot">Bump maven-pmd-plugin from 3.13.0 to 3.14.0 #660.</action>
112 <action type="update" dev="kinow" due-to="Dependabot">Bump jmh.version from 1.21 to 1.27 #674.</action>
113 <action type="update" dev="ggregory" due-to="Gary Gregory">Update commons.japicmp.version 0.14.3 -> 0.15.2.</action>
114 <action type="update" dev="ggregory" due-to="Ali K. Nouri">Processor.java: check enum equality with == instead of .equals() method #690.</action>
115 <action type="update" dev="ggregory" due-to="Dependabot">Bump junit-pioneer from 1.1.0 to 1.3.0 #702.</action>
116 <action type="update" dev="ggregory" due-to="Dependabot">Bump maven-checkstyle-plugin from 3.1.1 to 3.1.2 #705.</action>
117 <action type="update" dev="ggregory" due-to="Dependabot">Bump actions/cache from v2 to v2.1.4 #710.</action>
118 <action type="update" dev="ggregory" due-to="Dependabot">Bump junit-bom from 5.7.0 to 5.7.1 #707.</action>
119 <action type="update" dev="ggregory" due-to="Arturo Bernal">Minor Improvements #701.</action>
120 <action type="update" dev="ggregory" due-to="Arturo Bernal">Minor Improvement: Add final variable.try to make the code read-only #700.</action>
121 <action type="update" dev="ggregory" due-to="Arturo Bernal">Minor Improvement: Remove redundant initializer #699.</action>
122 <action type="update" dev="ggregory" due-to="Arturo Bernal">Use own validator ObjectUtils.anyNull to check null String input #718.</action>
123 </release>
47124 <release version="3.11" date="2020-07-12" description="New features and bug fixes.">
48125 <action type="update" dev="chtompki" due-to="Jin Xu">Refine test output for FastDateParserTest</action>
49126 <action issue="LANG-1549" type="update" dev="chtompki" due-to="Jin Xu">CharSequenceUtils.lastIndexOf : remake it</action>
175252 <action issue="LANG-1422" type="add" dev="ggregory">Add null-safe StringUtils.valueOf(char[]) to delegate to String.valueOf(char[])</action>
176253 <action issue="LANG-1427" type="add" dev="ggregory">Add API org.apache.commons.lang3.SystemUtils.isJavaVersionAtMost(JavaVersion)</action>
177254 <action issue="LANG-1436" type="update" dev="aherbert">Consolidate the StringUtils equals and equalsIgnoreCase Javadoc and implementation</action>
178 <action type="update" dev="ggregory" due-to="Andrei Troie aft90">(doc) Fix javadoc for 'startIndex' parameter of StringUtils.join() methods. GitHub PR #412.</action>
255 <action type="update" dev="ggregory" due-to="Andrei Troie aft90">(doc) Fix javadoc for 'startIndex' parameter of StringUtils.join() methods. GitHub PR #412.</action>
179256 </release>
180257
181258 <release version="3.8.1" date="2018-09-19" description="This release is a bugfix for Restoring Bundle-SymbolicName in the MANIFEST.mf file.">
200277 <action issue="LANG-1352" type="add" dev="pschumacher" due-to="Ruslan Sibgatullin">EnumUtils.getEnumIgnoreCase and isValidEnumIgnoreCase methods added</action>
201278 <action issue="LANG-1372" type="add" dev="pschumacher" due-to="Sérgio Ozaki">Add ToStringSummary annotation</action>
202279 <action issue="LANG-1356" type="add" dev="pschumacher" due-to="Yathos UG">Add bypass option for classes to recursive and reflective EqualsBuilder</action>
203 <action issue="LANG-1391" type="add" dev="ggregory" due-to="Sauro Matulli, Oleg Chubaryov">Improve Javadoc for StringUtils.isAnyEmpty(null)</action>
204 <action issue="LANG-1393" type="add" dev="ggregory" due-to="Gary Gregory">Add API SystemUtils.String getEnvironmentVariable(final String name, final String defaultValue)</action>
205 <action issue="LANG-1394" type="add" dev="ggregory" due-to="Sebb, Gary Gregory">org.apache.commons.lang3.SystemUtils should not write to System.err.</action>
280 <action issue="LANG-1391" type="add" dev="ggregory" due-to="Sauro Matulli, Oleg Chubaryov">Improve Javadoc for StringUtils.isAnyEmpty(null)</action>
281 <action issue="LANG-1393" type="add" dev="ggregory" due-to="Gary Gregory">Add API SystemUtils.String getEnvironmentVariable(final String name, final String defaultValue)</action>
282 <action issue="LANG-1394" type="add" dev="ggregory" due-to="Sebb, Gary Gregory">org.apache.commons.lang3.SystemUtils should not write to System.err.</action>
206283 <action issue="LANG-1238" type="add" dev="ggregory" due-to="Christopher Cordeiro, Gary Gregory, Bruno P. Kinoshita, Oleg Chubaryov">Add RegexUtils class instead of overloading methods in StringUtils that take a regex to take precompiled Pattern.</action>
207284 <action issue="LANG-1390" type="add" dev="ggregory" due-to="Jochen Schalanda">StringUtils.join() with support for List&lt;?> with configurable start/end indices.</action>
208285 <action issue="LANG-1392" type="add" dev="pschumacher" due-to="Jeff Nelson">Methods for getting first non empty or non blank value</action>
137137
138138 ${project.url}
139139
140 Download page: ${project.url}download_csv.cgi
140 Download page: ${project.url}download_lang.cgi
141141
142142 Have fun!
143143 -Apache Commons Team
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.commons.lang3;
17
18 import java.util.Arrays;
19 import java.util.Comparator;
20
21 /**
22 * Sorts and returns arrays in the fluent style.
23 *
24 * @since 3.12.0
25 */
26 public class ArraySorter {
27
28 /**
29 * Sorts and returns the given array.
30 *
31 * @param array the array to sort.
32 * @return the given array.
33 * @see Arrays#sort(byte[])
34 */
35 public static byte[] sort(final byte[] array) {
36 Arrays.sort(array);
37 return array;
38 }
39
40 /**
41 * Sorts and returns the given array.
42 *
43 * @param array the array to sort.
44 * @return the given array.
45 * @see Arrays#sort(char[])
46 */
47 public static char[] sort(final char[] array) {
48 Arrays.sort(array);
49 return array;
50 }
51
52 /**
53 * Sorts and returns the given array.
54 *
55 * @param array the array to sort.
56 * @return the given array.
57 * @see Arrays#sort(double[])
58 */
59 public static double[] sort(final double[] array) {
60 Arrays.sort(array);
61 return array;
62 }
63
64 /**
65 * Sorts and returns the given array.
66 *
67 * @param array the array to sort.
68 * @return the given array.
69 * @see Arrays#sort(float[])
70 */
71 public static float[] sort(final float[] array) {
72 Arrays.sort(array);
73 return array;
74 }
75
76 /**
77 * Sorts and returns the given array.
78 *
79 * @param array the array to sort.
80 * @return the given array.
81 * @see Arrays#sort(int[])
82 */
83 public static int[] sort(final int[] array) {
84 Arrays.sort(array);
85 return array;
86 }
87
88 /**
89 * Sorts and returns the given array.
90 *
91 * @param array the array to sort.
92 * @return the given array.
93 * @see Arrays#sort(long[])
94 */
95 public static long[] sort(final long[] array) {
96 Arrays.sort(array);
97 return array;
98 }
99
100 /**
101 * Sorts and returns the given array.
102 *
103 * @param array the array to sort.
104 * @return the given array.
105 * @see Arrays#sort(short[])
106 */
107 public static short[] sort(final short[] array) {
108 Arrays.sort(array);
109 return array;
110 }
111
112 /**
113 * Sorts and returns the given array.
114 *
115 * @param <T> the array type.
116 * @param array the array to sort.
117 * @return the given array.
118 * @see Arrays#sort(Object[])
119 */
120 public static <T> T[] sort(final T[] array) {
121 Arrays.sort(array);
122 return array;
123 }
124
125 /**
126 * Sorts and returns the given array.
127 *
128 * @param <T> the array type.
129 * @param array the array to sort.
130 * @param comparator the comparator to determine the order of the array. A {@code null} value uses the elements'
131 * {@link Comparable natural ordering}.
132 * @return the given array.
133 * @see Arrays#sort(Object[])
134 */
135 public static <T> T[] sort(final T[] array, final Comparator<? super T> comparator) {
136 Arrays.sort(array, comparator);
137 return array;
138 }
139
140 }
784784 * @throws IllegalArgumentException if both arguments are null
785785 */
786786 public static <T> T[] add(final T[] array, final T element) {
787 Class<?> type;
787 final Class<?> type;
788788 if (array != null) {
789789 type = array.getClass().getComponentType();
790790 } else if (element != null) {
10981098 * </p>
10991099 *
11001100 * <pre>
1101 * ArrayUtils.add(null, true) = [true]
1102 * ArrayUtils.add([true], false) = [false, true]
1103 * ArrayUtils.add([true, false], true) = [true, true, false]
1101 * ArrayUtils.addFirst(null, true) = [true]
1102 * ArrayUtils.addFirst([true], false) = [false, true]
1103 * ArrayUtils.addFirst([true, false], true) = [true, true, false]
11041104 * </pre>
11051105 *
11061106 * @param array the array to "add" the element to, may be {@code null}.
11271127 * </p>
11281128 *
11291129 * <pre>
1130 * ArrayUtils.add(null, 1) = [1]
1131 * ArrayUtils.add([1], 0) = [0, 1]
1132 * ArrayUtils.add([1, 0], 1) = [1, 1, 0]
1130 * ArrayUtils.addFirst(null, 1) = [1]
1131 * ArrayUtils.addFirst([1], 0) = [0, 1]
1132 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
11331133 * </pre>
11341134 *
11351135 * @param array the array to "add" the element to, may be {@code null}.
11561156 * </p>
11571157 *
11581158 * <pre>
1159 * ArrayUtils.add(null, '1') = ['1']
1160 * ArrayUtils.add(['1'], '0') = ['0', '1']
1161 * ArrayUtils.add(['1', '0'], '1') = ['1', '1', '0']
1159 * ArrayUtils.addFirst(null, '1') = ['1']
1160 * ArrayUtils.addFirst(['1'], '0') = ['0', '1']
1161 * ArrayUtils.addFirst(['1', '0'], '1') = ['1', '1', '0']
11621162 * </pre>
11631163 *
11641164 * @param array the array to "add" the element to, may be {@code null}.
11851185 * </p>
11861186 *
11871187 * <pre>
1188 * ArrayUtils.add(null, 1) = [1]
1189 * ArrayUtils.add([1], 0) = [0, 1]
1190 * ArrayUtils.add([1, 0], 1) = [1, 1, 0]
1188 * ArrayUtils.addFirst(null, 1) = [1]
1189 * ArrayUtils.addFirst([1], 0) = [0, 1]
1190 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
11911191 * </pre>
11921192 *
11931193 * @param array the array to "add" the element to, may be {@code null}.
12141214 * </p>
12151215 *
12161216 * <pre>
1217 * ArrayUtils.add(null, 1) = [1]
1218 * ArrayUtils.add([1], 0) = [0, 1]
1219 * ArrayUtils.add([1, 0], 1) = [1, 1, 0]
1217 * ArrayUtils.addFirst(null, 1) = [1]
1218 * ArrayUtils.addFirst([1], 0) = [0, 1]
1219 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
12201220 * </pre>
12211221 *
12221222 * @param array the array to "add" the element to, may be {@code null}.
12431243 * </p>
12441244 *
12451245 * <pre>
1246 * ArrayUtils.add(null, 1) = [1]
1247 * ArrayUtils.add([1], 0) = [0, 1]
1248 * ArrayUtils.add([1, 0], 1) = [1, 1, 0]
1246 * ArrayUtils.addFirst(null, 1) = [1]
1247 * ArrayUtils.addFirst([1], 0) = [0, 1]
1248 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
12491249 * </pre>
12501250 *
12511251 * @param array the array to "add" the element to, may be {@code null}.
12721272 * </p>
12731273 *
12741274 * <pre>
1275 * ArrayUtils.add(null, 1) = [1]
1276 * ArrayUtils.add([1], 0) = [0, 1]
1277 * ArrayUtils.add([1, 0], 1) = [1, 1, 0]
1275 * ArrayUtils.addFirst(null, 1) = [1]
1276 * ArrayUtils.addFirst([1], 0) = [0, 1]
1277 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
12781278 * </pre>
12791279 *
12801280 * @param array the array to "add" the element to, may be {@code null}.
13011301 * </p>
13021302 *
13031303 * <pre>
1304 * ArrayUtils.add(null, 1) = [1]
1305 * ArrayUtils.add([1], 0) = [0, 1]
1306 * ArrayUtils.add([1, 0], 1) = [1, 1, 0]
1304 * ArrayUtils.addFirst(null, 1) = [1]
1305 * ArrayUtils.addFirst([1], 0) = [0, 1]
1306 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
13071307 * </pre>
13081308 *
13091309 * @param array the array to "add" the element to, may be {@code null}.
13301330 * </p>
13311331 *
13321332 * <pre>
1333 * ArrayUtils.add(null, null) = IllegalArgumentException
1334 * ArrayUtils.add(null, "a") = ["a"]
1335 * ArrayUtils.add(["a"], null) = [null, "a"]
1336 * ArrayUtils.add(["a"], "b") = ["b", "a"]
1337 * ArrayUtils.add(["a", "b"], "c") = ["c", "a", "b"]
1333 * ArrayUtils.addFirst(null, null) = IllegalArgumentException
1334 * ArrayUtils.addFirst(null, "a") = ["a"]
1335 * ArrayUtils.addFirst(["a"], null) = [null, "a"]
1336 * ArrayUtils.addFirst(["a"], "b") = ["b", "a"]
1337 * ArrayUtils.addFirst(["a", "b"], "c") = ["c", "a", "b"]
13381338 * </pre>
13391339 *
13401340 * @param <T> the component type of the array
24362436 if (startIndex < 0) {
24372437 startIndex = 0;
24382438 }
2439 final boolean searchNaN = Double.isNaN(valueToFind);
24392440 for (int i = startIndex; i < array.length; i++) {
2440 if (valueToFind == array[i]) {
2441 final double element = array[i];
2442 if (valueToFind == element || (searchNaN && Double.isNaN(element))) {
24412443 return i;
24422444 }
24432445 }
25152517 if (startIndex < 0) {
25162518 startIndex = 0;
25172519 }
2520 final boolean searchNaN = Float.isNaN(valueToFind);
25182521 for (int i = startIndex; i < array.length; i++) {
2519 if (valueToFind == array[i]) {
2522 final float element = array[i];
2523 if (valueToFind == element || (searchNaN && Float.isNaN(element))) {
25202524 return i;
25212525 }
25222526 }
25232527 return INDEX_NOT_FOUND;
25242528 }
25252529
2526 // int IndexOf
2527 //-----------------------------------------------------------------------
2528 /**
2529 * <p>Finds the index of the given value in the array.
2530 // int IndexOf
2531 //-----------------------------------------------------------------------
2532 /**
2533 * <p>Finds the index of the given value in the array.
2534 *
2535 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2536 *
2537 * @param array the array to search through for the object, may be {@code null}
2538 * @param valueToFind the value to find
2539 * @return the index of the value within the array,
2540 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2541 */
2542 public static int indexOf(final int[] array, final int valueToFind) {
2543 return indexOf(array, valueToFind, 0);
2544 }
2545
2546 /**
2547 * <p>Finds the index of the given value in the array starting at the given index.
25302548 *
25312549 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
25322550 *
2551 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2552 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2553 *
25332554 * @param array the array to search through for the object, may be {@code null}
25342555 * @param valueToFind the value to find
2556 * @param startIndex the index to start searching at
25352557 * @return the index of the value within the array,
25362558 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
25372559 */
2538 public static int indexOf(final int[] array, final int valueToFind) {
2539 return indexOf(array, valueToFind, 0);
2560 public static int indexOf(final int[] array, final int valueToFind, int startIndex) {
2561 if (array == null) {
2562 return INDEX_NOT_FOUND;
2563 }
2564 if (startIndex < 0) {
2565 startIndex = 0;
2566 }
2567 for (int i = startIndex; i < array.length; i++) {
2568 if (valueToFind == array[i]) {
2569 return i;
2570 }
2571 }
2572 return INDEX_NOT_FOUND;
25402573 }
2541
2542 /**
2543 * <p>Finds the index of the given value in the array starting at the given index.
2544 *
2545 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2546 *
2547 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2548 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2549 *
2550 * @param array the array to search through for the object, may be {@code null}
2551 * @param valueToFind the value to find
2552 * @param startIndex the index to start searching at
2553 * @return the index of the value within the array,
2554 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2555 */
2556 public static int indexOf(final int[] array, final int valueToFind, int startIndex) {
2557 if (array == null) {
2558 return INDEX_NOT_FOUND;
2559 }
2560 if (startIndex < 0) {
2561 startIndex = 0;
2562 }
2563 for (int i = startIndex; i < array.length; i++) {
2564 if (valueToFind == array[i]) {
2565 return i;
2566 }
2567 }
2568 return INDEX_NOT_FOUND;
2569 }
25702574
25712575 // long IndexOf
25722576 //-----------------------------------------------------------------------
31323136 return getLength(array) == 0;
31333137 }
31343138
3135 // IndexOf search
3136 // ----------------------------------------------------------------------
3137
31383139 /**
31393140 * <p>Checks if an array of primitive bytes is empty or {@code null}.
31403141 *
31463147 return getLength(array) == 0;
31473148 }
31483149
3150 // IndexOf search
3151 // ----------------------------------------------------------------------
3152
31493153 /**
31503154 * <p>Checks if an array of primitive chars is empty or {@code null}.
31513155 *
31793183 return getLength(array) == 0;
31803184 }
31813185
3182
3183
31843186 /**
31853187 * <p>Checks if an array of primitive ints is empty or {@code null}.
31863188 *
31913193 public static boolean isEmpty(final int[] array) {
31923194 return getLength(array) == 0;
31933195 }
3196
3197
31943198
31953199 /**
31963200 * <p>Checks if an array of primitive longs is empty or {@code null}.
34353439 return getLength(array1) == getLength(array2);
34363440 }
34373441
3438
34393442 /**
34403443 * <p>Checks whether two arrays are the same length, treating
34413444 * {@code null} arrays as length {@code 0}.
34513454 public static boolean isSameLength(final Object array1, final Object array2) {
34523455 return getLength(array1) == getLength(array2);
34533456 }
3457
34543458
34553459 /**
34563460 * <p>Checks whether two arrays are the same length, treating
39773981 return INDEX_NOT_FOUND;
39783982 }
39793983
3980
39813984 /**
39823985 * <p>Finds the last index of the given value within the array.
39833986 *
39913994 public static int lastIndexOf(final float[] array, final float valueToFind) {
39923995 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
39933996 }
3997
39943998
39953999 /**
39964000 * <p>Finds the last index of the given value in the array starting at the given index.
44514455 return array;
44524456 }
44534457
4454 // Primitive/Object array converters
4455 // ----------------------------------------------------------------------
4456
44574458 /**
44584459 * <p>Defensive programming technique to change a {@code null}
44594460 * reference to an empty one.
44734474 }
44744475 return array;
44754476 }
4477
4478 // Primitive/Object array converters
4479 // ----------------------------------------------------------------------
44764480
44774481 /**
44784482 * <p>Defensive programming technique to change a {@code null}
52265230 static Object removeAll(final Object array, final int... indices) {
52275231 final int length = getLength(array);
52285232 int diff = 0; // number of distinct indexes, i.e. number of entries that will be removed
5229 final int[] clonedIndices = clone(indices);
5230 Arrays.sort(clonedIndices);
5233 final int[] clonedIndices = ArraySorter.sort(clone(indices));
52315234
52325235 // identify length of result array
52335236 if (isNotEmpty(clonedIndices)) {
68196822 }
68206823 }
68216824
6822 // Reverse
6823 //-----------------------------------------------------------------------
68246825 /**
68256826 * <p>Reverses the order of the given array.
68266827 *
94779478 }
94789479 final Class<?> ct = array.getClass().getComponentType();
94799480 final Class<?> pt = ClassUtils.wrapperToPrimitive(ct);
9481 if (Boolean.TYPE.equals(pt)) {
9482 return toPrimitive((Boolean[]) array);
9483 }
9484 if (Character.TYPE.equals(pt)) {
9485 return toPrimitive((Character[]) array);
9486 }
9487 if (Byte.TYPE.equals(pt)) {
9488 return toPrimitive((Byte[]) array);
9489 }
94809490 if (Integer.TYPE.equals(pt)) {
94819491 return toPrimitive((Integer[]) array);
94829492 }
96399649 * to operate.
96409650 */
96419651 public ArrayUtils() {
9642 super();
96439652 }
96449653 }
2828 * @since 2.0
2929 */
3030 public class BooleanUtils {
31
32 /**
33 * <p>{@code BooleanUtils} instances should NOT be constructed in standard programming.
34 * Instead, the class should be used as {@code BooleanUtils.negate(true);}.</p>
35 *
36 * <p>This constructor is public to permit tools that require a JavaBean instance
37 * to operate.</p>
38 */
39 public BooleanUtils() {
40 super();
41 }
42
43 // Boolean utilities
44 //--------------------------------------------------------------------------
31 /**
32 * The false String {@code "false"}.
33 *
34 * @since 3.12.0
35 */
36 public static final String FALSE = "false";
37
38 /**
39 * The no String {@code "no"}.
40 *
41 * @since 3.12.0
42 */
43 public static final String NO = "no";
44
45 /**
46 * The off String {@code "off"}.
47 *
48 * @since 3.12.0
49 */
50 public static final String OFF = "off";
51
52 /**
53 * The on String {@code "on"}.
54 *
55 * @since 3.12.0
56 */
57 public static final String ON = "on";
58
59 /**
60 * The true String {@code "true"}.
61 *
62 * @since 3.12.0
63 */
64 public static final String TRUE = "true";
65
66 /**
67 * The yes String {@code "yes"}.
68 *
69 * @since 3.12.0
70 */
71 public static final String YES = "yes";
72
73 /**
74 * <p>Performs an 'and' operation on a set of booleans.</p>
75 *
76 * <pre>
77 * BooleanUtils.and(true, true) = true
78 * BooleanUtils.and(false, false) = false
79 * BooleanUtils.and(true, false) = false
80 * BooleanUtils.and(true, true, false) = false
81 * BooleanUtils.and(true, true, true) = true
82 * </pre>
83 *
84 * @param array an array of {@code boolean}s
85 * @return the result of the logical 'and' operation. That is {@code false}
86 * if any of the parameters is {@code false} and {@code true} otherwise.
87 * @throws NullPointerException if {@code array} is {@code null}
88 * @throws IllegalArgumentException if {@code array} is empty.
89 * @since 3.0.1
90 */
91 public static boolean and(final boolean... array) {
92 ObjectUtils.requireNonEmpty(array, "array");
93 for (final boolean element : array) {
94 if (!element) {
95 return false;
96 }
97 }
98 return true;
99 }
100
101 /**
102 * <p>Performs an 'and' operation on an array of Booleans.</p>
103 *
104 * <pre>
105 * BooleanUtils.and(Boolean.TRUE, Boolean.TRUE) = Boolean.TRUE
106 * BooleanUtils.and(Boolean.FALSE, Boolean.FALSE) = Boolean.FALSE
107 * BooleanUtils.and(Boolean.TRUE, Boolean.FALSE) = Boolean.FALSE
108 * BooleanUtils.and(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE) = Boolean.TRUE
109 * BooleanUtils.and(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE) = Boolean.FALSE
110 * BooleanUtils.and(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE) = Boolean.FALSE
111 * </pre>
112 *
113 * @param array an array of {@code Boolean}s
114 * @return the result of the logical 'and' operation. That is {@code false}
115 * if any of the parameters is {@code false} and {@code true} otherwise.
116 * @throws NullPointerException if {@code array} is {@code null}
117 * @throws IllegalArgumentException if {@code array} is empty.
118 * @throws IllegalArgumentException if {@code array} contains a {@code null}
119 * @since 3.0.1
120 */
121 public static Boolean and(final Boolean... array) {
122 ObjectUtils.requireNonEmpty(array, "array");
123 try {
124 final boolean[] primitive = ArrayUtils.toPrimitive(array);
125 return and(primitive) ? Boolean.TRUE : Boolean.FALSE;
126 } catch (final NullPointerException ex) {
127 throw new IllegalArgumentException("The array must not contain any null elements");
128 }
129 }
130
131 /**
132 * Returns a new array of possible values (like an enum would).
133 * @return a new array of possible values (like an enum would).
134 * @since 3.12.0
135 */
136 public static Boolean[] booleanValues() {
137 return new Boolean[] {Boolean.FALSE, Boolean.TRUE};
138 }
139
140 /**
141 * <p>Compares two {@code boolean} values. This is the same functionality as provided in Java 7.</p>
142 *
143 * @param x the first {@code boolean} to compare
144 * @param y the second {@code boolean} to compare
145 * @return the value {@code 0} if {@code x == y};
146 * a value less than {@code 0} if {@code !x && y}; and
147 * a value greater than {@code 0} if {@code x && !y}
148 * @since 3.4
149 */
150 public static int compare(final boolean x, final boolean y) {
151 if (x == y) {
152 return 0;
153 }
154 return x ? 1 : -1;
155 }
156
157 /**
158 * <p>Checks if a {@code Boolean} value is {@code false},
159 * handling {@code null} by returning {@code false}.</p>
160 *
161 * <pre>
162 * BooleanUtils.isFalse(Boolean.TRUE) = false
163 * BooleanUtils.isFalse(Boolean.FALSE) = true
164 * BooleanUtils.isFalse(null) = false
165 * </pre>
166 *
167 * @param bool the boolean to check, null returns {@code false}
168 * @return {@code true} only if the input is non-{@code null} and {@code false}
169 * @since 2.1
170 */
171 public static boolean isFalse(final Boolean bool) {
172 return Boolean.FALSE.equals(bool);
173 }
174
175 /**
176 * <p>Checks if a {@code Boolean} value is <i>not</i> {@code false},
177 * handling {@code null} by returning {@code true}.</p>
178 *
179 * <pre>
180 * BooleanUtils.isNotFalse(Boolean.TRUE) = true
181 * BooleanUtils.isNotFalse(Boolean.FALSE) = false
182 * BooleanUtils.isNotFalse(null) = true
183 * </pre>
184 *
185 * @param bool the boolean to check, null returns {@code true}
186 * @return {@code true} if the input is {@code null} or {@code true}
187 * @since 2.3
188 */
189 public static boolean isNotFalse(final Boolean bool) {
190 return !isFalse(bool);
191 }
192
193 /**
194 * <p>Checks if a {@code Boolean} value is <i>not</i> {@code true},
195 * handling {@code null} by returning {@code true}.</p>
196 *
197 * <pre>
198 * BooleanUtils.isNotTrue(Boolean.TRUE) = false
199 * BooleanUtils.isNotTrue(Boolean.FALSE) = true
200 * BooleanUtils.isNotTrue(null) = true
201 * </pre>
202 *
203 * @param bool the boolean to check, null returns {@code true}
204 * @return {@code true} if the input is null or false
205 * @since 2.3
206 */
207 public static boolean isNotTrue(final Boolean bool) {
208 return !isTrue(bool);
209 }
210
211 /**
212 * <p>Checks if a {@code Boolean} value is {@code true},
213 * handling {@code null} by returning {@code false}.</p>
214 *
215 * <pre>
216 * BooleanUtils.isTrue(Boolean.TRUE) = true
217 * BooleanUtils.isTrue(Boolean.FALSE) = false
218 * BooleanUtils.isTrue(null) = false
219 * </pre>
220 *
221 * @param bool the boolean to check, {@code null} returns {@code false}
222 * @return {@code true} only if the input is non-null and true
223 * @since 2.1
224 */
225 public static boolean isTrue(final Boolean bool) {
226 return Boolean.TRUE.equals(bool);
227 }
228
45229 /**
46230 * <p>Negates the specified boolean.</p>
47231 *
65249 }
66250 return bool.booleanValue() ? Boolean.FALSE : Boolean.TRUE;
67251 }
68
69 // boolean Boolean methods
70 //-----------------------------------------------------------------------
71 /**
72 * <p>Checks if a {@code Boolean} value is {@code true},
73 * handling {@code null} by returning {@code false}.</p>
74 *
75 * <pre>
76 * BooleanUtils.isTrue(Boolean.TRUE) = true
77 * BooleanUtils.isTrue(Boolean.FALSE) = false
78 * BooleanUtils.isTrue(null) = false
79 * </pre>
80 *
81 * @param bool the boolean to check, {@code null} returns {@code false}
82 * @return {@code true} only if the input is non-null and true
83 * @since 2.1
84 */
85 public static boolean isTrue(final Boolean bool) {
86 return Boolean.TRUE.equals(bool);
87 }
88
89 /**
90 * <p>Checks if a {@code Boolean} value is <i>not</i> {@code true},
91 * handling {@code null} by returning {@code true}.</p>
92 *
93 * <pre>
94 * BooleanUtils.isNotTrue(Boolean.TRUE) = false
95 * BooleanUtils.isNotTrue(Boolean.FALSE) = true
96 * BooleanUtils.isNotTrue(null) = true
97 * </pre>
98 *
99 * @param bool the boolean to check, null returns {@code true}
100 * @return {@code true} if the input is null or false
101 * @since 2.3
102 */
103 public static boolean isNotTrue(final Boolean bool) {
104 return !isTrue(bool);
105 }
106
107 /**
108 * <p>Checks if a {@code Boolean} value is {@code false},
109 * handling {@code null} by returning {@code false}.</p>
110 *
111 * <pre>
112 * BooleanUtils.isFalse(Boolean.TRUE) = false
113 * BooleanUtils.isFalse(Boolean.FALSE) = true
114 * BooleanUtils.isFalse(null) = false
115 * </pre>
116 *
117 * @param bool the boolean to check, null returns {@code false}
118 * @return {@code true} only if the input is non-{@code null} and {@code false}
119 * @since 2.1
120 */
121 public static boolean isFalse(final Boolean bool) {
122 return Boolean.FALSE.equals(bool);
123 }
124
125 /**
126 * <p>Checks if a {@code Boolean} value is <i>not</i> {@code false},
127 * handling {@code null} by returning {@code true}.</p>
128 *
129 * <pre>
130 * BooleanUtils.isNotFalse(Boolean.TRUE) = true
131 * BooleanUtils.isNotFalse(Boolean.FALSE) = false
132 * BooleanUtils.isNotFalse(null) = true
133 * </pre>
134 *
135 * @param bool the boolean to check, null returns {@code true}
136 * @return {@code true} if the input is {@code null} or {@code true}
137 * @since 2.3
138 */
139 public static boolean isNotFalse(final Boolean bool) {
140 return !isFalse(bool);
141 }
142
143 //-----------------------------------------------------------------------
252 /**
253 * <p>Performs an 'or' operation on a set of booleans.</p>
254 *
255 * <pre>
256 * BooleanUtils.or(true, true) = true
257 * BooleanUtils.or(false, false) = false
258 * BooleanUtils.or(true, false) = true
259 * BooleanUtils.or(true, true, false) = true
260 * BooleanUtils.or(true, true, true) = true
261 * BooleanUtils.or(false, false, false) = false
262 * </pre>
263 *
264 * @param array an array of {@code boolean}s
265 * @return {@code true} if any of the arguments is {@code true}, and it returns {@code false} otherwise.
266 * @throws NullPointerException if {@code array} is {@code null}
267 * @throws IllegalArgumentException if {@code array} is empty.
268 * @since 3.0.1
269 */
270 public static boolean or(final boolean... array) {
271 ObjectUtils.requireNonEmpty(array, "array");
272 for (final boolean element : array) {
273 if (element) {
274 return true;
275 }
276 }
277 return false;
278 }
279
280 /**
281 * <p>Performs an 'or' operation on an array of Booleans.</p>
282 *
283 * <pre>
284 * BooleanUtils.or(Boolean.TRUE, Boolean.TRUE) = Boolean.TRUE
285 * BooleanUtils.or(Boolean.FALSE, Boolean.FALSE) = Boolean.FALSE
286 * BooleanUtils.or(Boolean.TRUE, Boolean.FALSE) = Boolean.TRUE
287 * BooleanUtils.or(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE) = Boolean.TRUE
288 * BooleanUtils.or(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE) = Boolean.TRUE
289 * BooleanUtils.or(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE) = Boolean.TRUE
290 * BooleanUtils.or(Boolean.FALSE, Boolean.FALSE, Boolean.FALSE) = Boolean.FALSE
291 * </pre>
292 *
293 * @param array an array of {@code Boolean}s
294 * @return {@code true} if any of the arguments is {@code true}, and it returns {@code false} otherwise.
295 * @throws NullPointerException if {@code array} is {@code null}
296 * @throws IllegalArgumentException if {@code array} is empty.
297 * @throws IllegalArgumentException if {@code array} contains a {@code null}
298 * @since 3.0.1
299 */
300 public static Boolean or(final Boolean... array) {
301 ObjectUtils.requireNonEmpty(array, "array");
302 try {
303 final boolean[] primitive = ArrayUtils.toPrimitive(array);
304 return or(primitive) ? Boolean.TRUE : Boolean.FALSE;
305 } catch (final NullPointerException ex) {
306 throw new IllegalArgumentException("The array must not contain any null elements");
307 }
308 }
309
310 /**
311 * Returns a new array of possible values (like an enum would).
312 * @return a new array of possible values (like an enum would).
313 * @since 3.12.0
314 */
315 public static boolean[] primitiveValues() {
316 return new boolean[] {false, true};
317 }
318
144319 /**
145320 * <p>Converts a Boolean to a boolean handling {@code null}
146321 * by returning {@code false}.</p>
156331 */
157332 public static boolean toBoolean(final Boolean bool) {
158333 return bool != null && bool.booleanValue();
334 }
335
336 /**
337 * <p>Converts an int to a boolean using the convention that {@code zero}
338 * is {@code false}, everything else is {@code true}.</p>
339 *
340 * <pre>
341 * BooleanUtils.toBoolean(0) = false
342 * BooleanUtils.toBoolean(1) = true
343 * BooleanUtils.toBoolean(2) = true
344 * </pre>
345 *
346 * @param value the int to convert
347 * @return {@code true} if non-zero, {@code false}
348 * if zero
349 */
350 public static boolean toBoolean(final int value) {
351 return value != 0;
352 }
353
354 /**
355 * <p>Converts an int to a boolean specifying the conversion values.</p>
356 *
357 * <p>If the {@code trueValue} and {@code falseValue} are the same number then
358 * the return value will be {@code true} in case {@code value} matches it.</p>
359 *
360 * <pre>
361 * BooleanUtils.toBoolean(0, 1, 0) = false
362 * BooleanUtils.toBoolean(1, 1, 0) = true
363 * BooleanUtils.toBoolean(1, 1, 1) = true
364 * BooleanUtils.toBoolean(2, 1, 2) = false
365 * BooleanUtils.toBoolean(2, 2, 0) = true
366 * </pre>
367 *
368 * @param value the {@code Integer} to convert
369 * @param trueValue the value to match for {@code true}
370 * @param falseValue the value to match for {@code false}
371 * @return {@code true} or {@code false}
372 * @throws IllegalArgumentException if {@code value} does not match neither
373 * {@code trueValue} no {@code falseValue}
374 */
375 public static boolean toBoolean(final int value, final int trueValue, final int falseValue) {
376 if (value == trueValue) {
377 return true;
378 }
379 if (value == falseValue) {
380 return false;
381 }
382 throw new IllegalArgumentException("The Integer did not match either specified value");
383 }
384
385 /**
386 * <p>Converts an Integer to a boolean specifying the conversion values.</p>
387 *
388 * <pre>
389 * BooleanUtils.toBoolean(Integer.valueOf(0), Integer.valueOf(1), Integer.valueOf(0)) = false
390 * BooleanUtils.toBoolean(Integer.valueOf(1), Integer.valueOf(1), Integer.valueOf(0)) = true
391 * BooleanUtils.toBoolean(Integer.valueOf(2), Integer.valueOf(1), Integer.valueOf(2)) = false
392 * BooleanUtils.toBoolean(Integer.valueOf(2), Integer.valueOf(2), Integer.valueOf(0)) = true
393 * BooleanUtils.toBoolean(null, null, Integer.valueOf(0)) = true
394 * </pre>
395 *
396 * @param value the Integer to convert
397 * @param trueValue the value to match for {@code true}, may be {@code null}
398 * @param falseValue the value to match for {@code false}, may be {@code null}
399 * @return {@code true} or {@code false}
400 * @throws IllegalArgumentException if no match
401 */
402 public static boolean toBoolean(final Integer value, final Integer trueValue, final Integer falseValue) {
403 if (value == null) {
404 if (trueValue == null) {
405 return true;
406 }
407 if (falseValue == null) {
408 return false;
409 }
410 } else if (value.equals(trueValue)) {
411 return true;
412 } else if (value.equals(falseValue)) {
413 return false;
414 }
415 throw new IllegalArgumentException("The Integer did not match either specified value");
416 }
417
418 /**
419 * <p>Converts a String to a boolean (optimised for performance).</p>
420 *
421 * <p>{@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'} or {@code 'yes'}
422 * (case insensitive) will return {@code true}. Otherwise,
423 * {@code false} is returned.</p>
424 *
425 * <p>This method performs 4 times faster (JDK1.4) than
426 * {@code Boolean.valueOf(String)}. However, this method accepts
427 * 'on' and 'yes', 't', 'y' as true values.
428 *
429 * <pre>
430 * BooleanUtils.toBoolean(null) = false
431 * BooleanUtils.toBoolean("true") = true
432 * BooleanUtils.toBoolean("TRUE") = true
433 * BooleanUtils.toBoolean("tRUe") = true
434 * BooleanUtils.toBoolean("on") = true
435 * BooleanUtils.toBoolean("yes") = true
436 * BooleanUtils.toBoolean("false") = false
437 * BooleanUtils.toBoolean("x gti") = false
438 * BooleanUtils.toBoolean("y") = true
439 * BooleanUtils.toBoolean("n") = false
440 * BooleanUtils.toBoolean("t") = true
441 * BooleanUtils.toBoolean("f") = false
442 * </pre>
443 *
444 * @param str the String to check
445 * @return the boolean value of the string, {@code false} if no match or the String is null
446 */
447 public static boolean toBoolean(final String str) {
448 return toBooleanObject(str) == Boolean.TRUE;
449 }
450
451 /**
452 * <p>Converts a String to a Boolean throwing an exception if no match found.</p>
453 *
454 * <pre>
455 * BooleanUtils.toBoolean("true", "true", "false") = true
456 * BooleanUtils.toBoolean("false", "true", "false") = false
457 * </pre>
458 *
459 * @param str the String to check
460 * @param trueString the String to match for {@code true} (case sensitive), may be {@code null}
461 * @param falseString the String to match for {@code false} (case sensitive), may be {@code null}
462 * @return the boolean value of the string
463 * @throws IllegalArgumentException if the String doesn't match
464 */
465 public static boolean toBoolean(final String str, final String trueString, final String falseString) {
466 if (str == trueString) {
467 return true;
468 } else if (str == falseString) {
469 return false;
470 } else if (str != null) {
471 if (str.equals(trueString)) {
472 return true;
473 } else if (str.equals(falseString)) {
474 return false;
475 }
476 }
477 throw new IllegalArgumentException("The String did not match either specified value");
159478 }
160479
161480 /**
181500 return bool.booleanValue();
182501 }
183502
184 // Integer to Boolean methods
185 //-----------------------------------------------------------------------
186 /**
187 * <p>Converts an int to a boolean using the convention that {@code zero}
188 * is {@code false}, everything else is {@code true}.</p>
189 *
190 * <pre>
191 * BooleanUtils.toBoolean(0) = false
192 * BooleanUtils.toBoolean(1) = true
193 * BooleanUtils.toBoolean(2) = true
194 * </pre>
195 *
196 * @param value the int to convert
197 * @return {@code true} if non-zero, {@code false}
198 * if zero
199 */
200 public static boolean toBoolean(final int value) {
201 return value != 0;
202 }
203
204503 /**
205504 * <p>Converts an int to a Boolean using the convention that {@code zero}
206505 * is {@code false}, everything else is {@code true}.</p>
217516 */
218517 public static Boolean toBooleanObject(final int value) {
219518 return value == 0 ? Boolean.FALSE : Boolean.TRUE;
220 }
221
222 /**
223 * <p>Converts an Integer to a Boolean using the convention that {@code zero}
224 * is {@code false}, every other numeric value is {@code true}.</p>
225 *
226 * <p>{@code null} will be converted to {@code null}.</p>
227 *
228 * <p>NOTE: This method may return {@code null} and may throw a {@code NullPointerException}
229 * if unboxed to a {@code boolean}.</p>
230 *
231 * <pre>
232 * BooleanUtils.toBoolean(Integer.valueOf(0)) = Boolean.FALSE
233 * BooleanUtils.toBoolean(Integer.valueOf(1)) = Boolean.TRUE
234 * BooleanUtils.toBoolean(Integer.valueOf(null)) = null
235 * </pre>
236 *
237 * @param value the Integer to convert
238 * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
239 * {@code null} if {@code null} input
240 */
241 public static Boolean toBooleanObject(final Integer value) {
242 if (value == null) {
243 return null;
244 }
245 return value.intValue() == 0 ? Boolean.FALSE : Boolean.TRUE;
246 }
247
248 /**
249 * <p>Converts an int to a boolean specifying the conversion values.</p>
250 *
251 * <p>If the {@code trueValue} and {@code falseValue} are the same number then
252 * the return value will be {@code true} in case {@code value} matches it.</p>
253 *
254 * <pre>
255 * BooleanUtils.toBoolean(0, 1, 0) = false
256 * BooleanUtils.toBoolean(1, 1, 0) = true
257 * BooleanUtils.toBoolean(1, 1, 1) = true
258 * BooleanUtils.toBoolean(2, 1, 2) = false
259 * BooleanUtils.toBoolean(2, 2, 0) = true
260 * </pre>
261 *
262 * @param value the {@code Integer} to convert
263 * @param trueValue the value to match for {@code true}
264 * @param falseValue the value to match for {@code false}
265 * @return {@code true} or {@code false}
266 * @throws IllegalArgumentException if {@code value} does not match neither
267 * {@code trueValue} no {@code falseValue}
268 */
269 public static boolean toBoolean(final int value, final int trueValue, final int falseValue) {
270 if (value == trueValue) {
271 return true;
272 }
273 if (value == falseValue) {
274 return false;
275 }
276 throw new IllegalArgumentException("The Integer did not match either specified value");
277 }
278
279 /**
280 * <p>Converts an Integer to a boolean specifying the conversion values.</p>
281 *
282 * <pre>
283 * BooleanUtils.toBoolean(Integer.valueOf(0), Integer.valueOf(1), Integer.valueOf(0)) = false
284 * BooleanUtils.toBoolean(Integer.valueOf(1), Integer.valueOf(1), Integer.valueOf(0)) = true
285 * BooleanUtils.toBoolean(Integer.valueOf(2), Integer.valueOf(1), Integer.valueOf(2)) = false
286 * BooleanUtils.toBoolean(Integer.valueOf(2), Integer.valueOf(2), Integer.valueOf(0)) = true
287 * BooleanUtils.toBoolean(null, null, Integer.valueOf(0)) = true
288 * </pre>
289 *
290 * @param value the Integer to convert
291 * @param trueValue the value to match for {@code true}, may be {@code null}
292 * @param falseValue the value to match for {@code false}, may be {@code null}
293 * @return {@code true} or {@code false}
294 * @throws IllegalArgumentException if no match
295 */
296 public static boolean toBoolean(final Integer value, final Integer trueValue, final Integer falseValue) {
297 if (value == null) {
298 if (trueValue == null) {
299 return true;
300 }
301 if (falseValue == null) {
302 return false;
303 }
304 } else if (value.equals(trueValue)) {
305 return true;
306 } else if (value.equals(falseValue)) {
307 return false;
308 }
309 throw new IllegalArgumentException("The Integer did not match either specified value");
310519 }
311520
312521 /**
348557 }
349558
350559 /**
560 * <p>Converts an Integer to a Boolean using the convention that {@code zero}
561 * is {@code false}, every other numeric value is {@code true}.</p>
562 *
563 * <p>{@code null} will be converted to {@code null}.</p>
564 *
565 * <p>NOTE: This method may return {@code null} and may throw a {@code NullPointerException}
566 * if unboxed to a {@code boolean}.</p>
567 *
568 * <pre>
569 * BooleanUtils.toBooleanObject(Integer.valueOf(0)) = Boolean.FALSE
570 * BooleanUtils.toBooleanObject(Integer.valueOf(1)) = Boolean.TRUE
571 * BooleanUtils.toBooleanObject(Integer.valueOf(null)) = null
572 * </pre>
573 *
574 * @param value the Integer to convert
575 * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
576 * {@code null} if {@code null} input
577 */
578 public static Boolean toBooleanObject(final Integer value) {
579 if (value == null) {
580 return null;
581 }
582 return value.intValue() == 0 ? Boolean.FALSE : Boolean.TRUE;
583 }
584
585 /**
351586 * <p>Converts an Integer to a Boolean specifying the conversion values.</p>
352587 *
353588 * <p>NOTE: This method may return {@code null} and may throw a {@code NullPointerException}
393628 throw new IllegalArgumentException("The Integer did not match any specified value");
394629 }
395630
396 // Boolean to Integer methods
397 //-----------------------------------------------------------------------
398 /**
399 * <p>Converts a boolean to an int using the convention that
400 * {@code true} is {@code 1} and {@code false} is {@code 0}.</p>
401 *
402 * <pre>
403 * BooleanUtils.toInteger(true) = 1
404 * BooleanUtils.toInteger(false) = 0
405 * </pre>
406 *
407 * @param bool the boolean to convert
408 * @return one if {@code true}, zero if {@code false}
409 */
410 public static int toInteger(final boolean bool) {
411 return bool ? 1 : 0;
412 }
413
414 /**
415 * <p>Converts a boolean to an Integer using the convention that
416 * {@code true} is {@code 1} and {@code false} is {@code 0}.</p>
417 *
418 * <pre>
419 * BooleanUtils.toIntegerObject(true) = Integer.valueOf(1)
420 * BooleanUtils.toIntegerObject(false) = Integer.valueOf(0)
421 * </pre>
422 *
423 * @param bool the boolean to convert
424 * @return one if {@code true}, zero if {@code false}
425 */
426 public static Integer toIntegerObject(final boolean bool) {
427 return bool ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
428 }
429
430 /**
431 * <p>Converts a Boolean to a Integer using the convention that
432 * {@code zero} is {@code false}.</p>
433 *
434 * <p>{@code null} will be converted to {@code null}.</p>
435 *
436 * <pre>
437 * BooleanUtils.toIntegerObject(Boolean.TRUE) = Integer.valueOf(1)
438 * BooleanUtils.toIntegerObject(Boolean.FALSE) = Integer.valueOf(0)
439 * </pre>
440 *
441 * @param bool the Boolean to convert
442 * @return one if Boolean.TRUE, zero if Boolean.FALSE, {@code null} if {@code null}
443 */
444 public static Integer toIntegerObject(final Boolean bool) {
445 if (bool == null) {
446 return null;
447 }
448 return bool.booleanValue() ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
449 }
450
451 /**
452 * <p>Converts a boolean to an int specifying the conversion values.</p>
453 *
454 * <pre>
455 * BooleanUtils.toInteger(true, 1, 0) = 1
456 * BooleanUtils.toInteger(false, 1, 0) = 0
457 * </pre>
458 *
459 * @param bool the to convert
460 * @param trueValue the value to return if {@code true}
461 * @param falseValue the value to return if {@code false}
462 * @return the appropriate value
463 */
464 public static int toInteger(final boolean bool, final int trueValue, final int falseValue) {
465 return bool ? trueValue : falseValue;
466 }
467
468 /**
469 * <p>Converts a Boolean to an int specifying the conversion values.</p>
470 *
471 * <pre>
472 * BooleanUtils.toInteger(Boolean.TRUE, 1, 0, 2) = 1
473 * BooleanUtils.toInteger(Boolean.FALSE, 1, 0, 2) = 0
474 * BooleanUtils.toInteger(null, 1, 0, 2) = 2
475 * </pre>
476 *
477 * @param bool the Boolean to convert
478 * @param trueValue the value to return if {@code true}
479 * @param falseValue the value to return if {@code false}
480 * @param nullValue the value to return if {@code null}
481 * @return the appropriate value
482 */
483 public static int toInteger(final Boolean bool, final int trueValue, final int falseValue, final int nullValue) {
484 if (bool == null) {
485 return nullValue;
486 }
487 return bool.booleanValue() ? trueValue : falseValue;
488 }
489
490 /**
491 * <p>Converts a boolean to an Integer specifying the conversion values.</p>
492 *
493 * <pre>
494 * BooleanUtils.toIntegerObject(true, Integer.valueOf(1), Integer.valueOf(0)) = Integer.valueOf(1)
495 * BooleanUtils.toIntegerObject(false, Integer.valueOf(1), Integer.valueOf(0)) = Integer.valueOf(0)
496 * </pre>
497 *
498 * @param bool the to convert
499 * @param trueValue the value to return if {@code true}, may be {@code null}
500 * @param falseValue the value to return if {@code false}, may be {@code null}
501 * @return the appropriate value
502 */
503 public static Integer toIntegerObject(final boolean bool, final Integer trueValue, final Integer falseValue) {
504 return bool ? trueValue : falseValue;
505 }
506
507 /**
508 * <p>Converts a Boolean to an Integer specifying the conversion values.</p>
509 *
510 * <pre>
511 * BooleanUtils.toIntegerObject(Boolean.TRUE, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2)) = Integer.valueOf(1)
512 * BooleanUtils.toIntegerObject(Boolean.FALSE, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2)) = Integer.valueOf(0)
513 * BooleanUtils.toIntegerObject(null, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2)) = Integer.valueOf(2)
514 * </pre>
515 *
516 * @param bool the Boolean to convert
517 * @param trueValue the value to return if {@code true}, may be {@code null}
518 * @param falseValue the value to return if {@code false}, may be {@code null}
519 * @param nullValue the value to return if {@code null}, may be {@code null}
520 * @return the appropriate value
521 */
522 public static Integer toIntegerObject(final Boolean bool, final Integer trueValue, final Integer falseValue, final Integer nullValue) {
523 if (bool == null) {
524 return nullValue;
525 }
526 return bool.booleanValue() ? trueValue : falseValue;
527 }
528
529 // String to Boolean methods
530 //-----------------------------------------------------------------------
531631 /**
532632 * <p>Converts a String to a Boolean.</p>
533633 *
572672 // Optimisation provides same performance as before for interned 'true'.
573673 // Similar performance for null, 'false', and other strings not length 2/3/4.
574674 // 'true'/'TRUE' match 4 times slower, 'tRUE'/'True' 7 times slower.
575 if (str == "true") {
675 if (str == TRUE) {
576676 return Boolean.TRUE;
577677 }
578678 if (str == null) {
705805 throw new IllegalArgumentException("The String did not match any specified value");
706806 }
707807
708 // String to boolean methods
709 //-----------------------------------------------------------------------
710 /**
711 * <p>Converts a String to a boolean (optimised for performance).</p>
712 *
713 * <p>{@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'} or {@code 'yes'}
714 * (case insensitive) will return {@code true}. Otherwise,
715 * {@code false} is returned.</p>
716 *
717 * <p>This method performs 4 times faster (JDK1.4) than
718 * {@code Boolean.valueOf(String)}. However, this method accepts
719 * 'on' and 'yes', 't', 'y' as true values.
720 *
721 * <pre>
722 * BooleanUtils.toBoolean(null) = false
723 * BooleanUtils.toBoolean("true") = true
724 * BooleanUtils.toBoolean("TRUE") = true
725 * BooleanUtils.toBoolean("tRUe") = true
726 * BooleanUtils.toBoolean("on") = true
727 * BooleanUtils.toBoolean("yes") = true
728 * BooleanUtils.toBoolean("false") = false
729 * BooleanUtils.toBoolean("x gti") = false
730 * BooleanUtils.toBooleanObject("y") = true
731 * BooleanUtils.toBooleanObject("n") = false
732 * BooleanUtils.toBooleanObject("t") = true
733 * BooleanUtils.toBooleanObject("f") = false
734 * </pre>
735 *
736 * @param str the String to check
737 * @return the boolean value of the string, {@code false} if no match or the String is null
738 */
739 public static boolean toBoolean(final String str) {
740 return toBooleanObject(str) == Boolean.TRUE;
741 }
742
743 /**
744 * <p>Converts a String to a Boolean throwing an exception if no match found.</p>
745 *
746 * <pre>
747 * BooleanUtils.toBoolean("true", "true", "false") = true
748 * BooleanUtils.toBoolean("false", "true", "false") = false
749 * </pre>
750 *
751 * @param str the String to check
752 * @param trueString the String to match for {@code true} (case sensitive), may be {@code null}
753 * @param falseString the String to match for {@code false} (case sensitive), may be {@code null}
754 * @return the boolean value of the string
755 * @throws IllegalArgumentException if the String doesn't match
756 */
757 public static boolean toBoolean(final String str, final String trueString, final String falseString) {
758 if (str == trueString) {
759 return true;
760 } else if (str == falseString) {
761 return false;
762 } else if (str != null) {
763 if (str.equals(trueString)) {
764 return true;
765 } else if (str.equals(falseString)) {
766 return false;
767 }
768 }
769 throw new IllegalArgumentException("The String did not match either specified value");
770 }
771
772 // Boolean to String methods
773 //-----------------------------------------------------------------------
774 /**
775 * <p>Converts a Boolean to a String returning {@code 'true'},
776 * {@code 'false'}, or {@code null}.</p>
777 *
778 * <pre>
779 * BooleanUtils.toStringTrueFalse(Boolean.TRUE) = "true"
780 * BooleanUtils.toStringTrueFalse(Boolean.FALSE) = "false"
781 * BooleanUtils.toStringTrueFalse(null) = null;
808 /**
809 * <p>Converts a boolean to an int using the convention that
810 * {@code true} is {@code 1} and {@code false} is {@code 0}.</p>
811 *
812 * <pre>
813 * BooleanUtils.toInteger(true) = 1
814 * BooleanUtils.toInteger(false) = 0
815 * </pre>
816 *
817 * @param bool the boolean to convert
818 * @return one if {@code true}, zero if {@code false}
819 */
820 public static int toInteger(final boolean bool) {
821 return bool ? 1 : 0;
822 }
823
824 /**
825 * <p>Converts a boolean to an int specifying the conversion values.</p>
826 *
827 * <pre>
828 * BooleanUtils.toInteger(true, 1, 0) = 1
829 * BooleanUtils.toInteger(false, 1, 0) = 0
830 * </pre>
831 *
832 * @param bool the to convert
833 * @param trueValue the value to return if {@code true}
834 * @param falseValue the value to return if {@code false}
835 * @return the appropriate value
836 */
837 public static int toInteger(final boolean bool, final int trueValue, final int falseValue) {
838 return bool ? trueValue : falseValue;
839 }
840
841 /**
842 * <p>Converts a Boolean to an int specifying the conversion values.</p>
843 *
844 * <pre>
845 * BooleanUtils.toInteger(Boolean.TRUE, 1, 0, 2) = 1
846 * BooleanUtils.toInteger(Boolean.FALSE, 1, 0, 2) = 0
847 * BooleanUtils.toInteger(null, 1, 0, 2) = 2
848 * </pre>
849 *
850 * @param bool the Boolean to convert
851 * @param trueValue the value to return if {@code true}
852 * @param falseValue the value to return if {@code false}
853 * @param nullValue the value to return if {@code null}
854 * @return the appropriate value
855 */
856 public static int toInteger(final Boolean bool, final int trueValue, final int falseValue, final int nullValue) {
857 if (bool == null) {
858 return nullValue;
859 }
860 return bool.booleanValue() ? trueValue : falseValue;
861 }
862
863 /**
864 * <p>Converts a boolean to an Integer using the convention that
865 * {@code true} is {@code 1} and {@code false} is {@code 0}.</p>
866 *
867 * <pre>
868 * BooleanUtils.toIntegerObject(true) = Integer.valueOf(1)
869 * BooleanUtils.toIntegerObject(false) = Integer.valueOf(0)
870 * </pre>
871 *
872 * @param bool the boolean to convert
873 * @return one if {@code true}, zero if {@code false}
874 */
875 public static Integer toIntegerObject(final boolean bool) {
876 return bool ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
877 }
878
879 /**
880 * <p>Converts a boolean to an Integer specifying the conversion values.</p>
881 *
882 * <pre>
883 * BooleanUtils.toIntegerObject(true, Integer.valueOf(1), Integer.valueOf(0)) = Integer.valueOf(1)
884 * BooleanUtils.toIntegerObject(false, Integer.valueOf(1), Integer.valueOf(0)) = Integer.valueOf(0)
885 * </pre>
886 *
887 * @param bool the to convert
888 * @param trueValue the value to return if {@code true}, may be {@code null}
889 * @param falseValue the value to return if {@code false}, may be {@code null}
890 * @return the appropriate value
891 */
892 public static Integer toIntegerObject(final boolean bool, final Integer trueValue, final Integer falseValue) {
893 return bool ? trueValue : falseValue;
894 }
895
896 /**
897 * <p>Converts a Boolean to a Integer using the convention that
898 * {@code zero} is {@code false}.</p>
899 *
900 * <p>{@code null} will be converted to {@code null}.</p>
901 *
902 * <pre>
903 * BooleanUtils.toIntegerObject(Boolean.TRUE) = Integer.valueOf(1)
904 * BooleanUtils.toIntegerObject(Boolean.FALSE) = Integer.valueOf(0)
905 * </pre>
906 *
907 * @param bool the Boolean to convert
908 * @return one if Boolean.TRUE, zero if Boolean.FALSE, {@code null} if {@code null}
909 */
910 public static Integer toIntegerObject(final Boolean bool) {
911 if (bool == null) {
912 return null;
913 }
914 return bool.booleanValue() ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
915 }
916
917 /**
918 * <p>Converts a Boolean to an Integer specifying the conversion values.</p>
919 *
920 * <pre>
921 * BooleanUtils.toIntegerObject(Boolean.TRUE, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2)) = Integer.valueOf(1)
922 * BooleanUtils.toIntegerObject(Boolean.FALSE, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2)) = Integer.valueOf(0)
923 * BooleanUtils.toIntegerObject(null, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2)) = Integer.valueOf(2)
924 * </pre>
925 *
926 * @param bool the Boolean to convert
927 * @param trueValue the value to return if {@code true}, may be {@code null}
928 * @param falseValue the value to return if {@code false}, may be {@code null}
929 * @param nullValue the value to return if {@code null}, may be {@code null}
930 * @return the appropriate value
931 */
932 public static Integer toIntegerObject(final Boolean bool, final Integer trueValue, final Integer falseValue, final Integer nullValue) {
933 if (bool == null) {
934 return nullValue;
935 }
936 return bool.booleanValue() ? trueValue : falseValue;
937 }
938
939 /**
940 * <p>Converts a boolean to a String returning one of the input Strings.</p>
941 *
942 * <pre>
943 * BooleanUtils.toString(true, "true", "false") = "true"
944 * BooleanUtils.toString(false, "true", "false") = "false"
782945 * </pre>
783946 *
784947 * @param bool the Boolean to check
785 * @return {@code 'true'}, {@code 'false'}, or {@code null}
786 */
787 public static String toStringTrueFalse(final Boolean bool) {
788 return toString(bool, "true", "false", null);
789 }
790
791 /**
792 * <p>Converts a Boolean to a String returning {@code 'on'},
793 * {@code 'off'}, or {@code null}.</p>
794 *
795 * <pre>
796 * BooleanUtils.toStringOnOff(Boolean.TRUE) = "on"
797 * BooleanUtils.toStringOnOff(Boolean.FALSE) = "off"
798 * BooleanUtils.toStringOnOff(null) = null;
799 * </pre>
800 *
801 * @param bool the Boolean to check
802 * @return {@code 'on'}, {@code 'off'}, or {@code null}
803 */
804 public static String toStringOnOff(final Boolean bool) {
805 return toString(bool, "on", "off", null);
806 }
807
808 /**
809 * <p>Converts a Boolean to a String returning {@code 'yes'},
810 * {@code 'no'}, or {@code null}.</p>
811 *
812 * <pre>
813 * BooleanUtils.toStringYesNo(Boolean.TRUE) = "yes"
814 * BooleanUtils.toStringYesNo(Boolean.FALSE) = "no"
815 * BooleanUtils.toStringYesNo(null) = null;
816 * </pre>
817 *
818 * @param bool the Boolean to check
819 * @return {@code 'yes'}, {@code 'no'}, or {@code null}
820 */
821 public static String toStringYesNo(final Boolean bool) {
822 return toString(bool, "yes", "no", null);
948 * @param trueString the String to return if {@code true}, may be {@code null}
949 * @param falseString the String to return if {@code false}, may be {@code null}
950 * @return one of the two input Strings
951 */
952 public static String toString(final boolean bool, final String trueString, final String falseString) {
953 return bool ? trueString : falseString;
823954 }
824955
825956 /**
844975 return bool.booleanValue() ? trueString : falseString;
845976 }
846977
847 // boolean to String methods
848 //-----------------------------------------------------------------------
978 /**
979 * <p>Converts a boolean to a String returning {@code 'on'}
980 * or {@code 'off'}.</p>
981 *
982 * <pre>
983 * BooleanUtils.toStringOnOff(true) = "on"
984 * BooleanUtils.toStringOnOff(false) = "off"
985 * </pre>
986 *
987 * @param bool the Boolean to check
988 * @return {@code 'on'}, {@code 'off'}, or {@code null}
989 */
990 public static String toStringOnOff(final boolean bool) {
991 return toString(bool, ON, OFF);
992 }
993
994 /**
995 * <p>Converts a Boolean to a String returning {@code 'on'},
996 * {@code 'off'}, or {@code null}.</p>
997 *
998 * <pre>
999 * BooleanUtils.toStringOnOff(Boolean.TRUE) = "on"
1000 * BooleanUtils.toStringOnOff(Boolean.FALSE) = "off"
1001 * BooleanUtils.toStringOnOff(null) = null;
1002 * </pre>
1003 *
1004 * @param bool the Boolean to check
1005 * @return {@code 'on'}, {@code 'off'}, or {@code null}
1006 */
1007 public static String toStringOnOff(final Boolean bool) {
1008 return toString(bool, ON, OFF, null);
1009 }
1010
8491011 /**
8501012 * <p>Converts a boolean to a String returning {@code 'true'}
8511013 * or {@code 'false'}.</p>
8591021 * @return {@code 'true'}, {@code 'false'}, or {@code null}
8601022 */
8611023 public static String toStringTrueFalse(final boolean bool) {
862 return toString(bool, "true", "false");
863 }
864
865 /**
866 * <p>Converts a boolean to a String returning {@code 'on'}
867 * or {@code 'off'}.</p>
868 *
869 * <pre>
870 * BooleanUtils.toStringOnOff(true) = "on"
871 * BooleanUtils.toStringOnOff(false) = "off"
1024 return toString(bool, TRUE, FALSE);
1025 }
1026
1027 /**
1028 * <p>Converts a Boolean to a String returning {@code 'true'},
1029 * {@code 'false'}, or {@code null}.</p>
1030 *
1031 * <pre>
1032 * BooleanUtils.toStringTrueFalse(Boolean.TRUE) = "true"
1033 * BooleanUtils.toStringTrueFalse(Boolean.FALSE) = "false"
1034 * BooleanUtils.toStringTrueFalse(null) = null;
8721035 * </pre>
8731036 *
8741037 * @param bool the Boolean to check
875 * @return {@code 'on'}, {@code 'off'}, or {@code null}
876 */
877 public static String toStringOnOff(final boolean bool) {
878 return toString(bool, "on", "off");
1038 * @return {@code 'true'}, {@code 'false'}, or {@code null}
1039 */
1040 public static String toStringTrueFalse(final Boolean bool) {
1041 return toString(bool, TRUE, FALSE, null);
8791042 }
8801043
8811044 /**
8911054 * @return {@code 'yes'}, {@code 'no'}, or {@code null}
8921055 */
8931056 public static String toStringYesNo(final boolean bool) {
894 return toString(bool, "yes", "no");
895 }
896
897 /**
898 * <p>Converts a boolean to a String returning one of the input Strings.</p>
899 *
900 * <pre>
901 * BooleanUtils.toString(true, "true", "false") = "true"
902 * BooleanUtils.toString(false, "true", "false") = "false"
1057 return toString(bool, YES, NO);
1058 }
1059
1060 /**
1061 * <p>Converts a Boolean to a String returning {@code 'yes'},
1062 * {@code 'no'}, or {@code null}.</p>
1063 *
1064 * <pre>
1065 * BooleanUtils.toStringYesNo(Boolean.TRUE) = "yes"
1066 * BooleanUtils.toStringYesNo(Boolean.FALSE) = "no"
1067 * BooleanUtils.toStringYesNo(null) = null;
9031068 * </pre>
9041069 *
9051070 * @param bool the Boolean to check
906 * @param trueString the String to return if {@code true}, may be {@code null}
907 * @param falseString the String to return if {@code false}, may be {@code null}
908 * @return one of the two input Strings
909 */
910 public static String toString(final boolean bool, final String trueString, final String falseString) {
911 return bool ? trueString : falseString;
912 }
913
914 // logical operations
915 // ----------------------------------------------------------------------
916 /**
917 * <p>Performs an 'and' operation on a set of booleans.</p>
918 *
919 * <pre>
920 * BooleanUtils.and(true, true) = true
921 * BooleanUtils.and(false, false) = false
922 * BooleanUtils.and(true, false) = false
923 * BooleanUtils.and(true, true, false) = false
924 * BooleanUtils.and(true, true, true) = true
925 * </pre>
926 *
927 * @param array an array of {@code boolean}s
928 * @return the result of the logical 'and' operation. That is {@code false}
929 * if any of the parameters is {@code false} and {@code true} otherwise.
930 * @throws IllegalArgumentException if {@code array} is {@code null}
931 * @throws IllegalArgumentException if {@code array} is empty.
932 * @since 3.0.1
933 */
934 public static boolean and(final boolean... array) {
935 // Validates input
936 if (array == null) {
937 throw new IllegalArgumentException("The Array must not be null");
938 }
939 if (array.length == 0) {
940 throw new IllegalArgumentException("Array is empty");
941 }
942 for (final boolean element : array) {
943 if (!element) {
944 return false;
945 }
946 }
947 return true;
948 }
949
950 /**
951 * <p>Performs an 'and' operation on an array of Booleans.</p>
952 *
953 * <pre>
954 * BooleanUtils.and(Boolean.TRUE, Boolean.TRUE) = Boolean.TRUE
955 * BooleanUtils.and(Boolean.FALSE, Boolean.FALSE) = Boolean.FALSE
956 * BooleanUtils.and(Boolean.TRUE, Boolean.FALSE) = Boolean.FALSE
957 * BooleanUtils.and(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE) = Boolean.TRUE
958 * BooleanUtils.and(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE) = Boolean.FALSE
959 * BooleanUtils.and(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE) = Boolean.FALSE
960 * </pre>
961 *
962 * @param array an array of {@code Boolean}s
963 * @return the result of the logical 'and' operation. That is {@code false}
964 * if any of the parameters is {@code false} and {@code true} otherwise.
965 * @throws IllegalArgumentException if {@code array} is {@code null}
966 * @throws IllegalArgumentException if {@code array} is empty.
967 * @throws IllegalArgumentException if {@code array} contains a {@code null}
968 * @since 3.0.1
969 */
970 public static Boolean and(final Boolean... array) {
971 if (array == null) {
972 throw new IllegalArgumentException("The Array must not be null");
973 }
974 if (array.length == 0) {
975 throw new IllegalArgumentException("Array is empty");
976 }
977 try {
978 final boolean[] primitive = ArrayUtils.toPrimitive(array);
979 return and(primitive) ? Boolean.TRUE : Boolean.FALSE;
980 } catch (final NullPointerException ex) {
981 throw new IllegalArgumentException("The array must not contain any null elements");
982 }
983 }
984
985 /**
986 * <p>Performs an 'or' operation on a set of booleans.</p>
987 *
988 * <pre>
989 * BooleanUtils.or(true, true) = true
990 * BooleanUtils.or(false, false) = false
991 * BooleanUtils.or(true, false) = true
992 * BooleanUtils.or(true, true, false) = true
993 * BooleanUtils.or(true, true, true) = true
994 * BooleanUtils.or(false, false, false) = false
995 * </pre>
996 *
997 * @param array an array of {@code boolean}s
998 * @return {@code true} if any of the arguments is {@code true}, and it returns {@code false} otherwise.
999 * @throws IllegalArgumentException if {@code array} is {@code null}
1000 * @throws IllegalArgumentException if {@code array} is empty.
1001 * @since 3.0.1
1002 */
1003 public static boolean or(final boolean... array) {
1004 if (array == null) {
1005 throw new IllegalArgumentException("The Array must not be null");
1006 }
1007 if (array.length == 0) {
1008 throw new IllegalArgumentException("Array is empty");
1009 }
1010 for (final boolean element : array) {
1011 if (element) {
1012 return true;
1013 }
1014 }
1015 return false;
1016 }
1017
1018 /**
1019 * <p>Performs an 'or' operation on an array of Booleans.</p>
1020 *
1021 * <pre>
1022 * BooleanUtils.or(Boolean.TRUE, Boolean.TRUE) = Boolean.TRUE
1023 * BooleanUtils.or(Boolean.FALSE, Boolean.FALSE) = Boolean.FALSE
1024 * BooleanUtils.or(Boolean.TRUE, Boolean.FALSE) = Boolean.TRUE
1025 * BooleanUtils.or(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE) = Boolean.TRUE
1026 * BooleanUtils.or(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE) = Boolean.TRUE
1027 * BooleanUtils.or(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE) = Boolean.TRUE
1028 * BooleanUtils.or(Boolean.FALSE, Boolean.FALSE, Boolean.FALSE) = Boolean.FALSE
1029 * </pre>
1030 *
1031 * @param array an array of {@code Boolean}s
1032 * @return {@code true} if any of the arguments is {@code true}, and it returns {@code false} otherwise.
1033 * @throws IllegalArgumentException if {@code array} is {@code null}
1034 * @throws IllegalArgumentException if {@code array} is empty.
1035 * @throws IllegalArgumentException if {@code array} contains a {@code null}
1036 * @since 3.0.1
1037 */
1038 public static Boolean or(final Boolean... array) {
1039 if (array == null) {
1040 throw new IllegalArgumentException("The Array must not be null");
1041 }
1042 if (array.length == 0) {
1043 throw new IllegalArgumentException("Array is empty");
1044 }
1045 try {
1046 final boolean[] primitive = ArrayUtils.toPrimitive(array);
1047 return or(primitive) ? Boolean.TRUE : Boolean.FALSE;
1048 } catch (final NullPointerException ex) {
1049 throw new IllegalArgumentException("The array must not contain any null elements");
1050 }
1071 * @return {@code 'yes'}, {@code 'no'}, or {@code null}
1072 */
1073 public static String toStringYesNo(final Boolean bool) {
1074 return toString(bool, YES, NO, null);
10511075 }
10521076
10531077 /**
10611085 *
10621086 * @param array an array of {@code boolean}s
10631087 * @return the result of the xor operations
1064 * @throws IllegalArgumentException if {@code array} is {@code null}
1088 * @throws NullPointerException if {@code array} is {@code null}
10651089 * @throws IllegalArgumentException if {@code array} is empty.
10661090 */
10671091 public static boolean xor(final boolean... array) {
1068 if (array == null) {
1069 throw new IllegalArgumentException("The Array must not be null");
1070 }
1071 if (array.length == 0) {
1072 throw new IllegalArgumentException("Array is empty");
1073 }
1074
1092 ObjectUtils.requireNonEmpty(array, "array");
10751093 // false if the neutral element of the xor operator
10761094 boolean result = false;
10771095 for (final boolean element : array) {
10931111 *
10941112 * @param array an array of {@code Boolean}s
10951113 * @return the result of the xor operations
1096 * @throws IllegalArgumentException if {@code array} is {@code null}
1114 * @throws NullPointerException if {@code array} is {@code null}
10971115 * @throws IllegalArgumentException if {@code array} is empty.
10981116 * @throws IllegalArgumentException if {@code array} contains a {@code null}
10991117 */
11001118 public static Boolean xor(final Boolean... array) {
1101 if (array == null) {
1102 throw new IllegalArgumentException("The Array must not be null");
1103 }
1104 if (array.length == 0) {
1105 throw new IllegalArgumentException("Array is empty");
1106 }
1119 ObjectUtils.requireNonEmpty(array, "array");
11071120 try {
11081121 final boolean[] primitive = ArrayUtils.toPrimitive(array);
11091122 return xor(primitive) ? Boolean.TRUE : Boolean.FALSE;
11131126 }
11141127
11151128 /**
1116 * <p>Compares two {@code boolean} values. This is the same functionality as provided in Java 7.</p>
1117 *
1118 * @param x the first {@code boolean} to compare
1119 * @param y the second {@code boolean} to compare
1120 * @return the value {@code 0} if {@code x == y};
1121 * a value less than {@code 0} if {@code !x && y}; and
1122 * a value greater than {@code 0} if {@code x && !y}
1123 * @since 3.4
1124 */
1125 public static int compare(final boolean x, final boolean y) {
1126 if (x == y) {
1127 return 0;
1128 }
1129 return x ? 1 : -1;
1129 * <p>{@code BooleanUtils} instances should NOT be constructed in standard programming.
1130 * Instead, the class should be used as {@code BooleanUtils.negate(true);}.</p>
1131 *
1132 * <p>This constructor is public to permit tools that require a JavaBean instance
1133 * to operate.</p>
1134 */
1135 public BooleanUtils() {
11301136 }
11311137
11321138 }
4848 /** Cached toString. */
4949 private transient String iToString;
5050
51 /** Empty array. */
52 static final CharRange[] EMPTY_ARRAY = new CharRange[0];
53
5154 /**
5255 * <p>Constructs a {@code CharRange} over a set of characters,
5356 * optionally negating the range.</p>
6366 * @param negated true to express everything except the range
6467 */
6568 private CharRange(char start, char end, final boolean negated) {
66 super();
6769 if (start > end) {
6870 final char temp = start;
6971 start = end;
8082 *
8183 * @param ch only character in this range
8284 * @return the new CharRange object
83 * @see CharRange#CharRange(char, char, boolean)
8485 * @since 2.5
8586 */
8687 public static CharRange is(final char ch) {
9091 /**
9192 * <p>Constructs a negated {@code CharRange} over a single character.</p>
9293 *
94 * <p>A negated range includes everything except that defined by the
95 * single character.</p>
96 *
9397 * @param ch only character in this range
9498 * @return the new CharRange object
95 * @see CharRange#CharRange(char, char, boolean)
9699 * @since 2.5
97100 */
98101 public static CharRange isNot(final char ch) {
101104
102105 /**
103106 * <p>Constructs a {@code CharRange} over a set of characters.</p>
107 *
108 * <p>If start and end are in the wrong order, they are reversed.
109 * Thus {@code a-e} is the same as {@code e-a}.</p>
104110 *
105111 * @param start first character, inclusive, in this range
106112 * @param end last character, inclusive, in this range
107113 * @return the new CharRange object
108 * @see CharRange#CharRange(char, char, boolean)
109114 * @since 2.5
110115 */
111116 public static CharRange isIn(final char start, final char end) {
114119
115120 /**
116121 * <p>Constructs a negated {@code CharRange} over a set of characters.</p>
122 *
123 * <p>A negated range includes everything except that defined by the
124 * start and end characters.</p>
125 *
126 * <p>If start and end are in the wrong order, they are reversed.
127 * Thus {@code a-e} is the same as {@code e-a}.</p>
117128 *
118129 * @param start first character, inclusive, in this range
119130 * @param end last character, inclusive, in this range
120131 * @return the new CharRange object
121 * @see CharRange#CharRange(char, char, boolean)
122132 * @since 2.5
123133 */
124134 public static CharRange isNotIn(final char start, final char end) {
178188 * @throws IllegalArgumentException if {@code null} input
179189 */
180190 public boolean contains(final CharRange range) {
181 Validate.notNull(range, "The Range must not be null");
191 Validate.notNull(range, "range");
182192 if (negated) {
183193 if (range.negated) {
184194 return start >= range.start && end <= range.end;
3434 * instance to operate.</p>
3535 */
3636 public CharSequenceUtils() {
37 super();
3837 }
3938
4039 //-----------------------------------------------------------------------
109108 return i;
110109 }
111110 }
111 return NOT_FOUND;
112112 }
113113 //supplementary characters (LANG1300)
114114 if (searchChar <= Character.MAX_CODE_POINT) {
195195 return i;
196196 }
197197 }
198 return NOT_FOUND;
198199 }
199200 //supplementary characters (LANG1300)
200201 //NOTE - we must do a forward traversal for this to avoid duplicating code points
221222 * Used by the lastIndexOf(CharSequence methods) as a green implementation of lastIndexOf
222223 *
223224 * @param cs the {@code CharSequence} to be processed
224 * @param searchChar the {@code CharSequence} to be searched for
225 * @param searchChar the {@code CharSequence} to find
225226 * @param start the start index
226227 * @return the index where the search sequence was found
227228 */
228229 static int lastIndexOf(final CharSequence cs, final CharSequence searchChar, int start) {
230 if (searchChar == null || cs == null) {
231 return NOT_FOUND;
232 }
229233 if (searchChar instanceof String) {
230234 if (cs instanceof String) {
231235 return ((String) cs).lastIndexOf((String) searchChar, start);
244248 }
245249
246250 if (start < 0 || len2 < 0 || len2 > len1) {
247 return -1;
251 return NOT_FOUND;
248252 }
249253
250254 if (len2 == 0) {
272276 while (cs.charAt(i) != char0) {
273277 i--;
274278 if (i < 0) {
275 return -1;
279 return NOT_FOUND;
276280 }
277281 }
278282 if (checkLaterThan1(cs, searchChar, len2, i)) {
280284 }
281285 i--;
282286 if (i < 0) {
283 return -1;
287 return NOT_FOUND;
284288 }
285289 }
286290 }
173173 * @throws NullPointerException if set is {@code null}
174174 */
175175 protected CharSet(final String... set) {
176 super();
177176 for (final String s : set) {
178177 add(s);
179178 }
224223 // NOTE: This is no longer public as CharRange is no longer a public class.
225224 // It may be replaced when CharSet moves to Range.
226225 /*public*/ CharRange[] getCharRanges() {
227 return set.toArray(new CharRange[0]);
226 return set.toArray(CharRange.EMPTY_ARRAY);
228227 }
229228
230229 //-----------------------------------------------------------------------
243243 * to operate.</p>
244244 */
245245 public CharSetUtils() {
246 super();
247246 }
248247 }
7070 * to operate.</p>
7171 */
7272 public CharUtils() {
73 super();
7473 }
7574
7675 //-----------------------------------------------------------------------
133132 * @throws NullPointerException if the Character is null
134133 */
135134 public static char toChar(final Character ch) {
136 Validate.notNull(ch, "The Character must not be null");
135 Validate.notNull(ch, "ch");
137136 return ch.charValue();
138137 }
139138
264263 * @throws IllegalArgumentException if the Character is not ASCII numeric
265264 */
266265 public static int toIntValue(final Character ch) {
267 Validate.notNull(ch, "The character must not be null");
266 Validate.notNull(ch, "ch");
268267 return toIntValue(ch.charValue());
269268 }
270269
3434 * instance to operate.</p>
3535 */
3636 public ClassPathUtils() {
37 super();
3837 }
3938
4039 /**
5453 * @throws java.lang.NullPointerException if either {@code context} or {@code resourceName} is null.
5554 */
5655 public static String toFullyQualifiedName(final Class<?> context, final String resourceName) {
57 Validate.notNull(context, "Parameter '%s' must not be null!", "context" );
58 Validate.notNull(resourceName, "Parameter '%s' must not be null!", "resourceName");
56 Validate.notNull(context, "context" );
57 Validate.notNull(resourceName, "resourceName");
5958 return toFullyQualifiedName(context.getPackage(), resourceName);
6059 }
6160
7675 * @throws java.lang.NullPointerException if either {@code context} or {@code resourceName} is null.
7776 */
7877 public static String toFullyQualifiedName(final Package context, final String resourceName) {
79 Validate.notNull(context, "Parameter '%s' must not be null!", "context" );
80 Validate.notNull(resourceName, "Parameter '%s' must not be null!", "resourceName");
78 Validate.notNull(context, "context" );
79 Validate.notNull(resourceName, "resourceName");
8180 return context.getName() + "." + resourceName;
8281 }
8382
9897 * @throws java.lang.NullPointerException if either {@code context} or {@code resourceName} is null.
9998 */
10099 public static String toFullyQualifiedPath(final Class<?> context, final String resourceName) {
101 Validate.notNull(context, "Parameter '%s' must not be null!", "context" );
102 Validate.notNull(resourceName, "Parameter '%s' must not be null!", "resourceName");
100 Validate.notNull(context, "context" );
101 Validate.notNull(resourceName, "resourceName");
103102 return toFullyQualifiedPath(context.getPackage(), resourceName);
104103 }
105104
121120 * @throws java.lang.NullPointerException if either {@code context} or {@code resourceName} is null.
122121 */
123122 public static String toFullyQualifiedPath(final Package context, final String resourceName) {
124 Validate.notNull(context, "Parameter '%s' must not be null!", "context" );
125 Validate.notNull(resourceName, "Parameter '%s' must not be null!", "resourceName");
123 Validate.notNull(context, "context" );
124 Validate.notNull(resourceName, "resourceName");
126125 return context.getName().replace('.', '/') + "/" + resourceName;
127126 }
128127
160160 * instance to operate.</p>
161161 */
162162 public ClassUtils() {
163 super();
164163 }
165164
166165 // Short class name
10611060 public static Class<?> getClass(
10621061 final ClassLoader classLoader, final String className, final boolean initialize) throws ClassNotFoundException {
10631062 try {
1064 Class<?> clazz;
1063 final Class<?> clazz;
10651064 if (namePrimitiveMap.containsKey(className)) {
10661065 clazz = namePrimitiveMap.get(className);
10671066 } else {
11661165 return declaredMethod;
11671166 }
11681167
1169 final List<Class<?>> candidateClasses = new ArrayList<>();
1170 candidateClasses.addAll(getAllInterfaces(cls));
1168 final List<Class<?>> candidateClasses = new ArrayList<>(getAllInterfaces(cls));
11711169 candidateClasses.addAll(getAllSuperclasses(cls));
11721170
11731171 for (final Class<?> candidateClass : candidateClasses) {
11741172 if (!Modifier.isPublic(candidateClass.getModifiers())) {
11751173 continue;
11761174 }
1177 Method candidateMethod;
1175 final Method candidateMethod;
11781176 try {
11791177 candidateMethod = candidateClass.getMethod(methodName, parameterTypes);
11801178 } catch (final NoSuchMethodException ex) {
11981196 */
11991197 private static String toCanonicalName(String className) {
12001198 className = StringUtils.deleteWhitespace(className);
1201 Validate.notNull(className, "className must not be null.");
1199 Validate.notNull(className, "className");
12021200 if (className.endsWith("[]")) {
12031201 final StringBuilder classNameBuffer = new StringBuilder();
12041202 while (className.endsWith("[]")) {
14591457 className.endsWith(";")
14601458 ? className.length() - 1
14611459 : className.length());
1462 } else {
1463 if (!className.isEmpty()) {
1464 className = reverseAbbreviationMap.get(className.substring(0, 1));
1465 }
1460 } else if (!className.isEmpty()) {
1461 className = reverseAbbreviationMap.get(className.substring(0, 1));
14661462 }
14671463 final StringBuilder canonicalClassNameBuffer = new StringBuilder(className);
14681464 for (int i = 0; i < dim; i++) {
4141 *
4242 * <pre>
4343 * {@code
44 * Consumer<java.lang.reflect.Method> consumer = (m) -> {
44 * Consumer<java.lang.reflect.Method> consumer = m -> {
4545 * try {
4646 * m.invoke(o, args);
4747 * } catch (Throwable t) {
8080 JAVA_1_9(9.0f, "9"),
8181
8282 /**
83 * Java 9
83 * Java 9.
8484 *
8585 * @since 3.5
8686 */
8787 JAVA_9(9.0f, "9"),
8888
8989 /**
90 * Java 10
90 * Java 10.
9191 *
9292 * @since 3.7
9393 */
9494 JAVA_10(10.0f, "10"),
9595
9696 /**
97 * Java 11
97 * Java 11.
9898 *
9999 * @since 3.8
100100 */
101101 JAVA_11(11.0f, "11"),
102102
103103 /**
104 * Java 12
104 * Java 12.
105105 *
106106 * @since 3.9
107107 */
108108 JAVA_12(12.0f, "12"),
109109
110110 /**
111 * Java 13
111 * Java 13.
112112 *
113113 * @since 3.9
114114 */
115115 JAVA_13(13.0f, "13"),
116116
117117 /**
118 * Java 14
118 * Java 14.
119119 *
120120 * @since 3.11
121121 */
122122 JAVA_14(14.0f, "14"),
123123
124124 /**
125 * Java 15
125 * Java 15.
126126 *
127127 * @since 3.11
128128 */
129129 JAVA_15(15.0f, "15"),
130130
131131 /**
132 * Java 16
132 * Java 16.
133133 *
134134 * @since 3.11
135135 */
136136 JAVA_16(16.0f, "16"),
137
138 /**
139 * Java 17.
140 *
141 * @since 3.12.0
142 */
143 JAVA_17(17.0f, "17"),
137144
138145 /**
139146 * The most recent java version. Mainly introduced to avoid to break when a new version of Java is used.
209216 * corresponding constant of this enumeration class. This method is used
210217 * internally.
211218 *
212 * @param nom the Java version as string
219 * @param versionStr the Java version as string
213220 * @return the corresponding enumeration constant or <b>null</b> if the
214221 * version is unknown
215222 */
216 static JavaVersion get(final String nom) {
217 if (nom == null) {
223 static JavaVersion get(final String versionStr) {
224 if (versionStr == null) {
218225 return null;
219 } else if ("0.9".equals(nom)) {
226 }
227 switch (versionStr) {
228 case "0.9":
220229 return JAVA_0_9;
221 } else if ("1.1".equals(nom)) {
230 case "1.1":
222231 return JAVA_1_1;
223 } else if ("1.2".equals(nom)) {
232 case "1.2":
224233 return JAVA_1_2;
225 } else if ("1.3".equals(nom)) {
234 case "1.3":
226235 return JAVA_1_3;
227 } else if ("1.4".equals(nom)) {
236 case "1.4":
228237 return JAVA_1_4;
229 } else if ("1.5".equals(nom)) {
238 case "1.5":
230239 return JAVA_1_5;
231 } else if ("1.6".equals(nom)) {
240 case "1.6":
232241 return JAVA_1_6;
233 } else if ("1.7".equals(nom)) {
242 case "1.7":
234243 return JAVA_1_7;
235 } else if ("1.8".equals(nom)) {
244 case "1.8":
236245 return JAVA_1_8;
237 } else if ("9".equals(nom)) {
246 case "9":
238247 return JAVA_9;
239 } else if ("10".equals(nom)) {
248 case "10":
240249 return JAVA_10;
241 } else if ("11".equals(nom)) {
250 case "11":
242251 return JAVA_11;
243 } else if ("12".equals(nom)) {
252 case "12":
244253 return JAVA_12;
245 } else if ("13".equals(nom)) {
254 case "13":
246255 return JAVA_13;
247 } else if ("14".equals(nom)) {
256 case "14":
248257 return JAVA_14;
249 } else if ("15".equals(nom)) {
258 case "15":
250259 return JAVA_15;
251 } else if ("16".equals(nom)) {
260 case "16":
252261 return JAVA_16;
253 }
254 final float v = toFloatVersion(nom);
255 if ((v - 1.) < 1.) { // then we need to check decimals > .9
256 final int firstComma = Math.max(nom.indexOf('.'), nom.indexOf(','));
257 final int end = Math.max(nom.length(), nom.indexOf(',', firstComma));
258 if (Float.parseFloat(nom.substring(firstComma + 1, end)) > .9f) {
262 case "17":
263 return JAVA_17;
264 default:
265 final float v = toFloatVersion(versionStr);
266 if ((v - 1.) < 1.) { // then we need to check decimals > .9
267 final int firstComma = Math.max(versionStr.indexOf('.'), versionStr.indexOf(','));
268 final int end = Math.max(versionStr.length(), versionStr.indexOf(',', firstComma));
269 if (Float.parseFloat(versionStr.substring(firstComma + 1, end)) > .9f) {
270 return JAVA_RECENT;
271 }
272 } else if (v > 10) {
259273 return JAVA_RECENT;
260274 }
261 } else if (v > 10) {
262 return JAVA_RECENT;
275 return null;
263276 }
264 return null;
265277 }
266278
267279 //-----------------------------------------------------------------------
3636 */
3737 public class LocaleUtils {
3838
39 // class to avoid synchronization (Init on demand)
40 static class SyncAvoid {
41 /** Unmodifiable list of available locales. */
42 private static final List<Locale> AVAILABLE_LOCALE_LIST;
43 /** Unmodifiable set of available locales. */
44 private static final Set<Locale> AVAILABLE_LOCALE_SET;
45
46 static {
47 final List<Locale> list = new ArrayList<>(Arrays.asList(Locale.getAvailableLocales())); // extra safe
48 AVAILABLE_LOCALE_LIST = Collections.unmodifiableList(list);
49 AVAILABLE_LOCALE_SET = Collections.unmodifiableSet(new HashSet<>(list));
50 }
51 }
52
3953 /** Concurrent map of language locales by country. */
4054 private static final ConcurrentMap<String, List<Locale>> cLanguagesByCountry =
4155 new ConcurrentHashMap<>();
4559 new ConcurrentHashMap<>();
4660
4761 /**
48 * <p>{@code LocaleUtils} instances should NOT be constructed in standard programming.
49 * Instead, the class should be used as {@code LocaleUtils.toLocale("en_GB");}.</p>
50 *
51 * <p>This constructor is public to permit tools that require a JavaBean instance
52 * to operate.</p>
53 */
54 public LocaleUtils() {
55 super();
56 }
57
58 //-----------------------------------------------------------------------
59 /**
60 * <p>Converts a String to a Locale.</p>
61 *
62 * <p>This method takes the string format of a locale and creates the
63 * locale object from it.</p>
64 *
65 * <pre>
66 * LocaleUtils.toLocale("") = new Locale("", "")
67 * LocaleUtils.toLocale("en") = new Locale("en", "")
68 * LocaleUtils.toLocale("en_GB") = new Locale("en", "GB")
69 * LocaleUtils.toLocale("en_001") = new Locale("en", "001")
70 * LocaleUtils.toLocale("en_GB_xxx") = new Locale("en", "GB", "xxx") (#)
71 * </pre>
72 *
73 * <p>(#) The behavior of the JDK variant constructor changed between JDK1.3 and JDK1.4.
74 * In JDK1.3, the constructor upper cases the variant, in JDK1.4, it doesn't.
75 * Thus, the result from getVariant() may vary depending on your JDK.</p>
76 *
77 * <p>This method validates the input strictly.
78 * The language code must be lowercase.
79 * The country code must be uppercase.
80 * The separator must be an underscore.
81 * The length must be correct.
82 * </p>
83 *
84 * @param str the locale String to convert, null returns null
85 * @return a Locale, null if null input
86 * @throws IllegalArgumentException if the string is an invalid format
87 * @see Locale#forLanguageTag(String)
88 */
89 public static Locale toLocale(final String str) {
90 if (str == null) {
91 return null;
92 }
93 if (str.isEmpty()) { // LANG-941 - JDK 8 introduced an empty locale where all fields are blank
94 return new Locale(StringUtils.EMPTY, StringUtils.EMPTY);
95 }
96 if (str.contains("#")) { // LANG-879 - Cannot handle Java 7 script & extensions
97 throw new IllegalArgumentException("Invalid locale format: " + str);
98 }
99 final int len = str.length();
100 if (len < 2) {
101 throw new IllegalArgumentException("Invalid locale format: " + str);
102 }
103 final char ch0 = str.charAt(0);
104 if (ch0 == '_') {
105 if (len < 3) {
106 throw new IllegalArgumentException("Invalid locale format: " + str);
107 }
108 final char ch1 = str.charAt(1);
109 final char ch2 = str.charAt(2);
110 if (!Character.isUpperCase(ch1) || !Character.isUpperCase(ch2)) {
111 throw new IllegalArgumentException("Invalid locale format: " + str);
112 }
113 if (len == 3) {
114 return new Locale(StringUtils.EMPTY, str.substring(1, 3));
115 }
116 if (len < 5) {
117 throw new IllegalArgumentException("Invalid locale format: " + str);
118 }
119 if (str.charAt(3) != '_') {
120 throw new IllegalArgumentException("Invalid locale format: " + str);
121 }
122 return new Locale(StringUtils.EMPTY, str.substring(1, 3), str.substring(4));
123 }
124
125 return parseLocale(str);
126 }
127
128 /**
129 * Tries to parse a locale from the given String.
130 *
131 * @param str the String to parse a locale from.
132 * @return a Locale instance parsed from the given String.
133 * @throws IllegalArgumentException if the given String can not be parsed.
134 */
135 private static Locale parseLocale(final String str) {
136 if (isISO639LanguageCode(str)) {
137 return new Locale(str);
138 }
139
140 final String[] segments = str.split("_", -1);
141 final String language = segments[0];
142 if (segments.length == 2) {
143 final String country = segments[1];
144 if (isISO639LanguageCode(language) && isISO3166CountryCode(country) ||
145 isNumericAreaCode(country)) {
146 return new Locale(language, country);
147 }
148 } else if (segments.length == 3) {
149 final String country = segments[1];
150 final String variant = segments[2];
151 if (isISO639LanguageCode(language) &&
152 (country.isEmpty() || isISO3166CountryCode(country) || isNumericAreaCode(country)) &&
153 !variant.isEmpty()) {
154 return new Locale(language, country, variant);
155 }
156 }
157 throw new IllegalArgumentException("Invalid locale format: " + str);
158 }
159
160 /**
161 * Checks whether the given String is a ISO 639 compliant language code.
162 *
163 * @param str the String to check.
164 * @return true, if the given String is a ISO 639 compliant language code.
165 */
166 private static boolean isISO639LanguageCode(final String str) {
167 return StringUtils.isAllLowerCase(str) && (str.length() == 2 || str.length() == 3);
168 }
169
170 /**
171 * Checks whether the given String is a ISO 3166 alpha-2 country code.
172 *
173 * @param str the String to check
174 * @return true, is the given String is a ISO 3166 compliant country code.
175 */
176 private static boolean isISO3166CountryCode(final String str) {
177 return StringUtils.isAllUpperCase(str) && str.length() == 2;
178 }
179
180 /**
181 * Checks whether the given String is a UN M.49 numeric area code.
182 *
183 * @param str the String to check
184 * @return true, is the given String is a UN M.49 numeric area code.
185 */
186 private static boolean isNumericAreaCode(final String str) {
187 return StringUtils.isNumeric(str) && str.length() == 3;
188 }
189
190 //-----------------------------------------------------------------------
191 /**
192 * <p>Obtains the list of locales to search through when performing
193 * a locale search.</p>
194 *
195 * <pre>
196 * localeLookupList(Locale("fr", "CA", "xxx"))
197 * = [Locale("fr", "CA", "xxx"), Locale("fr", "CA"), Locale("fr")]
198 * </pre>
199 *
200 * @param locale the locale to start from
201 * @return the unmodifiable list of Locale objects, 0 being locale, not null
202 */
203 public static List<Locale> localeLookupList(final Locale locale) {
204 return localeLookupList(locale, locale);
205 }
206
207 //-----------------------------------------------------------------------
208 /**
209 * <p>Obtains the list of locales to search through when performing
210 * a locale search.</p>
211 *
212 * <pre>
213 * localeLookupList(Locale("fr", "CA", "xxx"), Locale("en"))
214 * = [Locale("fr", "CA", "xxx"), Locale("fr", "CA"), Locale("fr"), Locale("en"]
215 * </pre>
216 *
217 * <p>The result list begins with the most specific locale, then the
218 * next more general and so on, finishing with the default locale.
219 * The list will never contain the same locale twice.</p>
220 *
221 * @param locale the locale to start from, null returns empty list
222 * @param defaultLocale the default locale to use if no other is found
223 * @return the unmodifiable list of Locale objects, 0 being locale, not null
224 */
225 public static List<Locale> localeLookupList(final Locale locale, final Locale defaultLocale) {
226 final List<Locale> list = new ArrayList<>(4);
227 if (locale != null) {
228 list.add(locale);
229 if (!locale.getVariant().isEmpty()) {
230 list.add(new Locale(locale.getLanguage(), locale.getCountry()));
231 }
232 if (!locale.getCountry().isEmpty()) {
233 list.add(new Locale(locale.getLanguage(), StringUtils.EMPTY));
234 }
235 if (!list.contains(defaultLocale)) {
236 list.add(defaultLocale);
237 }
238 }
239 return Collections.unmodifiableList(list);
240 }
241
242 //-----------------------------------------------------------------------
243 /**
24462 * <p>Obtains an unmodifiable list of installed locales.</p>
24563 *
24664 * <p>This method is a wrapper around {@link Locale#getAvailableLocales()}.
25371 return SyncAvoid.AVAILABLE_LOCALE_LIST;
25472 }
25573
256 //-----------------------------------------------------------------------
25774 /**
25875 * <p>Obtains an unmodifiable set of installed locales.</p>
25976 *
26784 return SyncAvoid.AVAILABLE_LOCALE_SET;
26885 }
26986
270 //-----------------------------------------------------------------------
271 /**
272 * <p>Checks if the locale specified is in the list of available locales.</p>
273 *
274 * @param locale the Locale object to check if it is available
275 * @return true if the locale is a known locale
276 */
277 public static boolean isAvailableLocale(final Locale locale) {
278 return availableLocaleList().contains(locale);
279 }
280
281 //-----------------------------------------------------------------------
282 /**
283 * <p>Obtains the list of languages supported for a given country.</p>
284 *
285 * <p>This method takes a country code and searches to find the
286 * languages available for that country. Variant locales are removed.</p>
287 *
288 * @param countryCode the 2 letter country code, null returns empty
289 * @return an unmodifiable List of Locale objects, not null
290 */
291 public static List<Locale> languagesByCountry(final String countryCode) {
292 if (countryCode == null) {
293 return Collections.emptyList();
294 }
295 List<Locale> langs = cLanguagesByCountry.get(countryCode);
296 if (langs == null) {
297 langs = new ArrayList<>();
298 final List<Locale> locales = availableLocaleList();
299 for (final Locale locale : locales) {
300 if (countryCode.equals(locale.getCountry()) &&
301 locale.getVariant().isEmpty()) {
302 langs.add(locale);
303 }
304 }
305 langs = Collections.unmodifiableList(langs);
306 cLanguagesByCountry.putIfAbsent(countryCode, langs);
307 langs = cLanguagesByCountry.get(countryCode);
308 }
309 return langs;
310 }
311
312 //-----------------------------------------------------------------------
31387 /**
31488 * <p>Obtains the list of countries supported for a given language.</p>
31589 *
341115 return countries;
342116 }
343117
344 //-----------------------------------------------------------------------
345 // class to avoid synchronization (Init on demand)
346 static class SyncAvoid {
347 /** Unmodifiable list of available locales. */
348 private static final List<Locale> AVAILABLE_LOCALE_LIST;
349 /** Unmodifiable set of available locales. */
350 private static final Set<Locale> AVAILABLE_LOCALE_SET;
351
352 static {
353 final List<Locale> list = new ArrayList<>(Arrays.asList(Locale.getAvailableLocales())); // extra safe
354 AVAILABLE_LOCALE_LIST = Collections.unmodifiableList(list);
355 AVAILABLE_LOCALE_SET = Collections.unmodifiableSet(new HashSet<>(list));
356 }
118 /**
119 * <p>Checks if the locale specified is in the list of available locales.</p>
120 *
121 * @param locale the Locale object to check if it is available
122 * @return true if the locale is a known locale
123 */
124 public static boolean isAvailableLocale(final Locale locale) {
125 return availableLocaleList().contains(locale);
126 }
127
128 /**
129 * Checks whether the given String is a ISO 3166 alpha-2 country code.
130 *
131 * @param str the String to check
132 * @return true, is the given String is a ISO 3166 compliant country code.
133 */
134 private static boolean isISO3166CountryCode(final String str) {
135 return StringUtils.isAllUpperCase(str) && str.length() == 2;
136 }
137
138 /**
139 * Checks whether the given String is a ISO 639 compliant language code.
140 *
141 * @param str the String to check.
142 * @return true, if the given String is a ISO 639 compliant language code.
143 */
144 private static boolean isISO639LanguageCode(final String str) {
145 return StringUtils.isAllLowerCase(str) && (str.length() == 2 || str.length() == 3);
146 }
147
148 /**
149 * Checks whether the given String is a UN M.49 numeric area code.
150 *
151 * @param str the String to check
152 * @return true, is the given String is a UN M.49 numeric area code.
153 */
154 private static boolean isNumericAreaCode(final String str) {
155 return StringUtils.isNumeric(str) && str.length() == 3;
156 }
157
158 /**
159 * <p>Obtains the list of languages supported for a given country.</p>
160 *
161 * <p>This method takes a country code and searches to find the
162 * languages available for that country. Variant locales are removed.</p>
163 *
164 * @param countryCode the 2 letter country code, null returns empty
165 * @return an unmodifiable List of Locale objects, not null
166 */
167 public static List<Locale> languagesByCountry(final String countryCode) {
168 if (countryCode == null) {
169 return Collections.emptyList();
170 }
171 List<Locale> langs = cLanguagesByCountry.get(countryCode);
172 if (langs == null) {
173 langs = new ArrayList<>();
174 final List<Locale> locales = availableLocaleList();
175 for (final Locale locale : locales) {
176 if (countryCode.equals(locale.getCountry()) &&
177 locale.getVariant().isEmpty()) {
178 langs.add(locale);
179 }
180 }
181 langs = Collections.unmodifiableList(langs);
182 cLanguagesByCountry.putIfAbsent(countryCode, langs);
183 langs = cLanguagesByCountry.get(countryCode);
184 }
185 return langs;
186 }
187
188 /**
189 * <p>Obtains the list of locales to search through when performing
190 * a locale search.</p>
191 *
192 * <pre>
193 * localeLookupList(Locale("fr", "CA", "xxx"))
194 * = [Locale("fr", "CA", "xxx"), Locale("fr", "CA"), Locale("fr")]
195 * </pre>
196 *
197 * @param locale the locale to start from
198 * @return the unmodifiable list of Locale objects, 0 being locale, not null
199 */
200 public static List<Locale> localeLookupList(final Locale locale) {
201 return localeLookupList(locale, locale);
202 }
203
204 /**
205 * <p>Obtains the list of locales to search through when performing
206 * a locale search.</p>
207 *
208 * <pre>
209 * localeLookupList(Locale("fr", "CA", "xxx"), Locale("en"))
210 * = [Locale("fr", "CA", "xxx"), Locale("fr", "CA"), Locale("fr"), Locale("en"]
211 * </pre>
212 *
213 * <p>The result list begins with the most specific locale, then the
214 * next more general and so on, finishing with the default locale.
215 * The list will never contain the same locale twice.</p>
216 *
217 * @param locale the locale to start from, null returns empty list
218 * @param defaultLocale the default locale to use if no other is found
219 * @return the unmodifiable list of Locale objects, 0 being locale, not null
220 */
221 public static List<Locale> localeLookupList(final Locale locale, final Locale defaultLocale) {
222 final List<Locale> list = new ArrayList<>(4);
223 if (locale != null) {
224 list.add(locale);
225 if (!locale.getVariant().isEmpty()) {
226 list.add(new Locale(locale.getLanguage(), locale.getCountry()));
227 }
228 if (!locale.getCountry().isEmpty()) {
229 list.add(new Locale(locale.getLanguage(), StringUtils.EMPTY));
230 }
231 if (!list.contains(defaultLocale)) {
232 list.add(defaultLocale);
233 }
234 }
235 return Collections.unmodifiableList(list);
236 }
237
238 /**
239 * Tries to parse a locale from the given String.
240 *
241 * @param str the String to parse a locale from.
242 * @return a Locale instance parsed from the given String.
243 * @throws IllegalArgumentException if the given String can not be parsed.
244 */
245 private static Locale parseLocale(final String str) {
246 if (isISO639LanguageCode(str)) {
247 return new Locale(str);
248 }
249
250 final String[] segments = str.split("_", -1);
251 final String language = segments[0];
252 if (segments.length == 2) {
253 final String country = segments[1];
254 if (isISO639LanguageCode(language) && isISO3166CountryCode(country) ||
255 isNumericAreaCode(country)) {
256 return new Locale(language, country);
257 }
258 } else if (segments.length == 3) {
259 final String country = segments[1];
260 final String variant = segments[2];
261 if (isISO639LanguageCode(language) &&
262 (country.isEmpty() || isISO3166CountryCode(country) || isNumericAreaCode(country)) &&
263 !variant.isEmpty()) {
264 return new Locale(language, country, variant);
265 }
266 }
267 throw new IllegalArgumentException("Invalid locale format: " + str);
268 }
269
270 /**
271 * Returns the given locale if non-{@code null}, otherwise {@link Locale#getDefault()}.
272 *
273 * @param locale a locale or {@code null}.
274 * @return the given locale if non-{@code null}, otherwise {@link Locale#getDefault()}.
275 * @since 3.12.0
276 */
277 public static Locale toLocale(final Locale locale) {
278 return locale != null ? locale : Locale.getDefault();
279 }
280
281 /**
282 * <p>Converts a String to a Locale.</p>
283 *
284 * <p>This method takes the string format of a locale and creates the
285 * locale object from it.</p>
286 *
287 * <pre>
288 * LocaleUtils.toLocale("") = new Locale("", "")
289 * LocaleUtils.toLocale("en") = new Locale("en", "")
290 * LocaleUtils.toLocale("en_GB") = new Locale("en", "GB")
291 * LocaleUtils.toLocale("en_001") = new Locale("en", "001")
292 * LocaleUtils.toLocale("en_GB_xxx") = new Locale("en", "GB", "xxx") (#)
293 * </pre>
294 *
295 * <p>(#) The behavior of the JDK variant constructor changed between JDK1.3 and JDK1.4.
296 * In JDK1.3, the constructor upper cases the variant, in JDK1.4, it doesn't.
297 * Thus, the result from getVariant() may vary depending on your JDK.</p>
298 *
299 * <p>This method validates the input strictly.
300 * The language code must be lowercase.
301 * The country code must be uppercase.
302 * The separator must be an underscore.
303 * The length must be correct.
304 * </p>
305 *
306 * @param str the locale String to convert, null returns null
307 * @return a Locale, null if null input
308 * @throws IllegalArgumentException if the string is an invalid format
309 * @see Locale#forLanguageTag(String)
310 */
311 public static Locale toLocale(final String str) {
312 if (str == null) {
313 return null;
314 }
315 if (str.isEmpty()) { // LANG-941 - JDK 8 introduced an empty locale where all fields are blank
316 return new Locale(StringUtils.EMPTY, StringUtils.EMPTY);
317 }
318 if (str.contains("#")) { // LANG-879 - Cannot handle Java 7 script & extensions
319 throw new IllegalArgumentException("Invalid locale format: " + str);
320 }
321 final int len = str.length();
322 if (len < 2) {
323 throw new IllegalArgumentException("Invalid locale format: " + str);
324 }
325 final char ch0 = str.charAt(0);
326 if (ch0 == '_') {
327 if (len < 3) {
328 throw new IllegalArgumentException("Invalid locale format: " + str);
329 }
330 final char ch1 = str.charAt(1);
331 final char ch2 = str.charAt(2);
332 if (!Character.isUpperCase(ch1) || !Character.isUpperCase(ch2)) {
333 throw new IllegalArgumentException("Invalid locale format: " + str);
334 }
335 if (len == 3) {
336 return new Locale(StringUtils.EMPTY, str.substring(1, 3));
337 }
338 if (len < 5) {
339 throw new IllegalArgumentException("Invalid locale format: " + str);
340 }
341 if (str.charAt(3) != '_') {
342 throw new IllegalArgumentException("Invalid locale format: " + str);
343 }
344 return new Locale(StringUtils.EMPTY, str.substring(1, 3), str.substring(4));
345 }
346
347 return parseLocale(str);
348 }
349
350 /**
351 * <p>{@code LocaleUtils} instances should NOT be constructed in standard programming.
352 * Instead, the class should be used as {@code LocaleUtils.toLocale("en_GB");}.</p>
353 *
354 * <p>This constructor is public to permit tools that require a JavaBean instance
355 * to operate.</p>
356 */
357 public LocaleUtils() {
357358 }
358359
359360 }
2020 import java.lang.reflect.Array;
2121 import java.lang.reflect.InvocationTargetException;
2222 import java.lang.reflect.Method;
23 import java.time.Duration;
2324 import java.util.Collection;
2425 import java.util.Collections;
2526 import java.util.Comparator;
2627 import java.util.HashMap;
2728 import java.util.Map;
29 import java.util.Objects;
2830 import java.util.TreeSet;
2931 import java.util.function.Supplier;
3032
3133 import org.apache.commons.lang3.exception.CloneFailedException;
3234 import org.apache.commons.lang3.mutable.MutableInt;
3335 import org.apache.commons.lang3.text.StrBuilder;
36 import org.apache.commons.lang3.time.DurationUtils;
3437
3538 /**
3639 * <p>Operations on {@code Object}.</p>
7477 * Restricted constructor - singleton.
7578 */
7679 Null() {
77 super();
7880 }
7981
8082 /**
107109 public static final Null NULL = new Null();
108110
109111 /**
110 * Checks if all values in the given array are {@code null}.
111 *
112 * <p>
113 * If all the values are {@code null} or the array is {@code null}
114 * or empty, then {@code true} is returned, otherwise {@code false} is returned.
115 * </p>
116 *
117 * <pre>
118 * ObjectUtils.allNull(*) = false
119 * ObjectUtils.allNull(*, null) = false
120 * ObjectUtils.allNull(null, *) = false
121 * ObjectUtils.allNull(null, null, *, *) = false
122 * ObjectUtils.allNull(null) = true
123 * ObjectUtils.allNull(null, null) = true
124 * </pre>
125 *
126 * @param values the values to test, may be {@code null} or empty
127 * @return {@code true} if all values in the array are {@code null}s,
128 * {@code false} if there is at least one non-null value in the array.
129 * @since 3.11
130 */
131 public static boolean allNull(final Object... values) {
132 return !anyNotNull(values);
133 }
134
135 /**
136112 * Checks if all values in the array are not {@code nulls}.
137113 *
138114 * <p>
172148 }
173149
174150 /**
151 * Checks if all values in the given array are {@code null}.
152 *
153 * <p>
154 * If all the values are {@code null} or the array is {@code null}
155 * or empty, then {@code true} is returned, otherwise {@code false} is returned.
156 * </p>
157 *
158 * <pre>
159 * ObjectUtils.allNull(*) = false
160 * ObjectUtils.allNull(*, null) = false
161 * ObjectUtils.allNull(null, *) = false
162 * ObjectUtils.allNull(null, null, *, *) = false
163 * ObjectUtils.allNull(null) = true
164 * ObjectUtils.allNull(null, null) = true
165 * </pre>
166 *
167 * @param values the values to test, may be {@code null} or empty
168 * @return {@code true} if all values in the array are {@code null}s,
169 * {@code false} if there is at least one non-null value in the array.
170 * @since 3.11
171 */
172 public static boolean allNull(final Object... values) {
173 return !anyNotNull(values);
174 }
175
176 /**
177 * Checks if any value in the given array is not {@code null}.
178 *
179 * <p>
180 * If all the values are {@code null} or the array is {@code null}
181 * or empty then {@code false} is returned. Otherwise {@code true} is returned.
182 * </p>
183 *
184 * <pre>
185 * ObjectUtils.anyNotNull(*) = true
186 * ObjectUtils.anyNotNull(*, null) = true
187 * ObjectUtils.anyNotNull(null, *) = true
188 * ObjectUtils.anyNotNull(null, null, *, *) = true
189 * ObjectUtils.anyNotNull(null) = false
190 * ObjectUtils.anyNotNull(null, null) = false
191 * </pre>
192 *
193 * @param values the values to test, may be {@code null} or empty
194 * @return {@code true} if there is at least one non-null value in the array,
195 * {@code false} if all values in the array are {@code null}s.
196 * If the array is {@code null} or empty {@code false} is also returned.
197 * @since 3.5
198 */
199 public static boolean anyNotNull(final Object... values) {
200 return firstNonNull(values) != null;
201 }
202
203 /**
175204 * Checks if any value in the given array is {@code null}.
176205 *
177206 * <p>
197226 */
198227 public static boolean anyNull(final Object... values) {
199228 return !allNotNull(values);
200 }
201
202 /**
203 * Checks if any value in the given array is not {@code null}.
204 *
205 * <p>
206 * If all the values are {@code null} or the array is {@code null}
207 * or empty then {@code false} is returned. Otherwise {@code true} is returned.
208 * </p>
209 *
210 * <pre>
211 * ObjectUtils.anyNotNull(*) = true
212 * ObjectUtils.anyNotNull(*, null) = true
213 * ObjectUtils.anyNotNull(null, *) = true
214 * ObjectUtils.anyNotNull(null, null, *, *) = true
215 * ObjectUtils.anyNotNull(null) = false
216 * ObjectUtils.anyNotNull(null, null) = false
217 * </pre>
218 *
219 * @param values the values to test, may be {@code null} or empty
220 * @return {@code true} if there is at least one non-null value in the array,
221 * {@code false} if all values in the array are {@code null}s.
222 * If the array is {@code null} or empty {@code false} is also returned.
223 * @since 3.5
224 */
225 public static boolean anyNotNull(final Object... values) {
226 return firstNonNull(values) != null;
227229 }
228230
229231 // cloning
803805 *
804806 * @param appendable the appendable to append to
805807 * @param object the object to create a toString for
806 * @throws IOException if an I/O error occurs
808 * @throws IOException if an I/O error occurs.
807809 * @since 3.2
808810 */
809811 public static void identityToString(final Appendable appendable, final Object object) throws IOException {
810 Validate.notNull(object, "Cannot get the toString of a null object");
812 Validate.notNull(object, "object");
811813 appendable.append(object.getClass().getName())
812814 .append(AT_SIGN)
813815 .append(Integer.toHexString(System.identityHashCode(object)));
865867 */
866868 @Deprecated
867869 public static void identityToString(final StrBuilder builder, final Object object) {
868 Validate.notNull(object, "Cannot get the toString of a null object");
870 Validate.notNull(object, "object");
869871 final String name = object.getClass().getName();
870872 final String hexString = Integer.toHexString(System.identityHashCode(object));
871873 builder.ensureCapacity(builder.length() + name.length() + 1 + hexString.length());
890892 * @since 2.4
891893 */
892894 public static void identityToString(final StringBuffer buffer, final Object object) {
893 Validate.notNull(object, "Cannot get the toString of a null object");
895 Validate.notNull(object, "object");
894896 final String name = object.getClass().getName();
895897 final String hexString = Integer.toHexString(System.identityHashCode(object));
896898 buffer.ensureCapacity(buffer.length() + name.length() + 1 + hexString.length());
915917 * @since 3.2
916918 */
917919 public static void identityToString(final StringBuilder builder, final Object object) {
918 Validate.notNull(object, "Cannot get the toString of a null object");
920 Validate.notNull(object, "object");
919921 final String name = object.getClass().getName();
920922 final String hexString = Integer.toHexString(System.identityHashCode(object));
921923 builder.ensureCapacity(builder.length() + name.length() + 1 + hexString.length());
10621064 public static <T> T median(final Comparator<T> comparator, final T... items) {
10631065 Validate.notEmpty(items, "null/empty items");
10641066 Validate.noNullElements(items);
1065 Validate.notNull(comparator, "null comparator");
1067 Validate.notNull(comparator, "comparator");
10661068 final TreeSet<T> sort = new TreeSet<>(comparator);
10671069 Collections.addAll(sort, items);
10681070 @SuppressWarnings("unchecked") //we know all items added were T instances
11821184 return !equals(object1, object2);
11831185 }
11841186
1187 /**
1188 * Checks that the specified object reference is not {@code null} or empty per {@link #isEmpty(Object)}. Use this
1189 * method for validation, for example:
1190 *
1191 * <blockquote>
1192 *
1193 * <pre>
1194 * public Foo(Bar bar) {
1195 * this.bar = Objects.requireNonEmpty(bar);
1196 * }
1197 * </pre>
1198 *
1199 * </blockquote>
1200 *
1201 * @param <T> the type of the reference.
1202 * @param obj the object reference to check for nullity.
1203 * @return {@code obj} if not {@code null}.
1204 * @throws NullPointerException if {@code obj} is {@code null}.
1205 * @throws IllegalArgumentException if {@code obj} is empty per {@link #isEmpty(Object)}.
1206 * @see #isEmpty(Object)
1207 * @since 3.12.0
1208 */
1209 public static <T> T requireNonEmpty(final T obj) {
1210 return requireNonEmpty(obj, "object");
1211 }
1212
1213 /**
1214 * Checks that the specified object reference is not {@code null} or empty per {@link #isEmpty(Object)}. Use this
1215 * method for validation, for example:
1216 *
1217 * <blockquote>
1218 *
1219 * <pre>
1220 * public Foo(Bar bar) {
1221 * this.bar = Objects.requireNonEmpty(bar, "bar");
1222 * }
1223 * </pre>
1224 *
1225 * </blockquote>
1226 *
1227 * @param <T> the type of the reference.
1228 * @param obj the object reference to check for nullity.
1229 * @param message the exception message.
1230 * @return {@code obj} if not {@code null}.
1231 * @throws NullPointerException if {@code obj} is {@code null}.
1232 * @throws IllegalArgumentException if {@code obj} is empty per {@link #isEmpty(Object)}.
1233 * @see #isEmpty(Object)
1234 * @since 3.12.0
1235 */
1236 public static <T> T requireNonEmpty(final T obj, final String message) {
1237 // check for null first to give the most precise exception.
1238 Objects.requireNonNull(obj, message);
1239 if (isEmpty(obj)) {
1240 throw new IllegalArgumentException(message);
1241 }
1242 return obj;
1243 }
1244
11851245 // ToString
11861246 //-----------------------------------------------------------------------
11871247 /**
12081268 public static String toString(final Object obj) {
12091269 return obj == null ? StringUtils.EMPTY : obj.toString();
12101270 }
1211
12121271 /**
12131272 * <p>Gets the {@code toString} of an {@code Object} returning
12141273 * a specified text if {@code null} input.</p>
12601319 }
12611320
12621321 /**
1322 * Calls {@link Object#wait(long, int)} for the given Duration.
1323 *
1324 * @param obj The receiver of the wait call.
1325 * @param duration How long to wait.
1326 * @throws IllegalArgumentException if the timeout duration is negative.
1327 * @throws IllegalMonitorStateException if the current thread is not the owner of the {@code obj}'s monitor.
1328 * @throws InterruptedException if any thread interrupted the current thread before or while the current thread was
1329 * waiting for a notification. The <em>interrupted status</em> of the current thread is cleared when this
1330 * exception is thrown.
1331 * @see Object#wait(long, int)
1332 * @since 3.12.0
1333 */
1334 public static void wait(final Object obj, final Duration duration) throws InterruptedException {
1335 DurationUtils.accept(obj::wait, DurationUtils.zeroIfNull(duration));
1336 }
1337
1338 /**
12631339 * <p>{@code ObjectUtils} instances should NOT be constructed in
12641340 * standard programming. Instead, the static methods on the class should
12651341 * be used, such as {@code ObjectUtils.defaultIfNull("a","b");}.</p>
12681344 * instance to operate.</p>
12691345 */
12701346 public ObjectUtils() {
1271 super();
12721347 }
12731348
12741349 }
6363 * to operate.</p>
6464 */
6565 public RandomStringUtils() {
66 super();
6766 }
6867
6968 // Random
309308 * @param count the length of random string to create
310309 * @param start the position in set of chars to start at
311310 * @param end the position in set of chars to end before
312 * @param letters only allow letters?
313 * @param numbers only allow numbers?
311 * @param letters if {@code true}, generated string may include
312 * alphabetic characters
313 * @param numbers if {@code true}, generated string may include
314 * numeric characters
314315 * @param chars the set of chars to choose randoms from.
315316 * If {@code null}, then it will use the set of all chars.
316317 * @return the random string
343344 * @param count the length of random string to create
344345 * @param start the position in set of chars to start at (inclusive)
345346 * @param end the position in set of chars to end before (exclusive)
346 * @param letters only allow letters?
347 * @param numbers only allow numbers?
347 * @param letters if {@code true}, generated string may include
348 * alphabetic characters
349 * @param numbers if {@code true}, generated string may include
350 * numeric characters
348351 * @param chars the set of chars to choose randoms from, must not be empty.
349352 * If {@code null}, then it will use the set of all chars.
350353 * @param random a source of randomness.
368371 if (start == 0 && end == 0) {
369372 if (chars != null) {
370373 end = chars.length;
374 } else if (!letters && !numbers) {
375 end = Character.MAX_CODE_POINT;
371376 } else {
372 if (!letters && !numbers) {
373 end = Character.MAX_CODE_POINT;
374 } else {
375 end = 'z' + 1;
376 start = ' ';
377 }
377 end = 'z' + 1;
378 start = ' ';
378379 }
379 } else {
380 if (end <= start) {
381 throw new IllegalArgumentException("Parameter end (" + end + ") must be greater than start (" + start + ")");
382 }
380 } else if (end <= start) {
381 throw new IllegalArgumentException("Parameter end (" + end + ") must be greater than start (" + start + ")");
383382 }
384383
385384 final int zero_digit_ascii = 48;
395394 final int gap = end - start;
396395
397396 while (count-- != 0) {
398 int codePoint;
397 final int codePoint;
399398 if (chars == null) {
400399 codePoint = random.nextInt(gap) + start;
401400
5151 * </p>
5252 */
5353 public RandomUtils() {
54 super();
5554 }
5655
5756 /**
144143 return startInclusive;
145144 }
146145
147 return (long) nextDouble(startInclusive, endExclusive);
146 return startInclusive + nextLong(endExclusive - startInclusive);
148147 }
149148
150149 /**
155154 * @since 3.5
156155 */
157156 public static long nextLong() {
158 return nextLong(0, Long.MAX_VALUE);
157 return nextLong(Long.MAX_VALUE);
158 }
159
160 /**
161 * Generates a {@code long} value between 0 (inclusive) and the specified
162 * value (exclusive).
163 *
164 * @param n Bound on the random number to be returned. Must be positive.
165 * @return a random {@code long} value between 0 (inclusive) and {@code n}
166 * (exclusive).
167 */
168 private static long nextLong(final long n) {
169 // Extracted from o.a.c.rng.core.BaseProvider.nextLong(long)
170 long bits;
171 long val;
172 do {
173 bits = RANDOM.nextLong() >>> 1;
174 val = bits % n;
175 } while (bits - val + (n - 1) < 0);
176
177 return val;
159178 }
160179
161180 /**
3131 */
3232 public final class Range<T> implements Serializable {
3333
34 //-----------------------------------------------------------------------
3534 @SuppressWarnings({"rawtypes", "unchecked"})
3635 private enum ComparableComparator implements Comparator {
3736 INSTANCE;
154153 */
155154 private transient String toString;
156155
157 // Accessors
158 //--------------------------------------------------------------------
159
160156 /**
161157 * Creates an instance.
162158 *
226222 */
227223 public int elementCompareTo(final T element) {
228224 // Comparable API says throw NPE on null
229 Validate.notNull(element, "Element is null");
225 Validate.notNull(element, "element");
230226 if (isAfter(element)) {
231227 return -1;
232228 } else if (isBefore(element)) {
331327 return between(min, max, getComparator());
332328 }
333329
334 // Range tests
335 //--------------------------------------------------------------------
336
337330 /**
338331 * <p>Checks whether this range is after the specified element.</p>
339332 *
404397 }
405398 return comparator.compare(element, maximum) == 0;
406399 }
407
408 // Basics
409 //--------------------------------------------------------------------
410400
411401 /**
412402 * <p>Whether or not the Range is using the natural ordering of the elements.</p>
255255 * @see java.util.regex.Pattern
256256 */
257257 public static String replaceAll(final String text, final Pattern regex, final String replacement) {
258 if (text == null || regex == null || replacement == null) {
258 if (ObjectUtils.anyNull(text, regex, replacement)) {
259259 return text;
260260 }
261261 return regex.matcher(text).replaceAll(replacement);
309309 * @see java.util.regex.Pattern#DOTALL
310310 */
311311 public static String replaceAll(final String text, final String regex, final String replacement) {
312 if (text == null || regex == null || replacement == null) {
312 if (ObjectUtils.anyNull(text, regex, replacement)) {
313313 return text;
314314 }
315315 return text.replaceAll(regex, replacement);
448448 * @see Pattern#DOTALL
449449 */
450450 public static String replacePattern(final String text, final String regex, final String replacement) {
451 if (text == null || regex == null || replacement == null) {
451 if (ObjectUtils.anyNull(text, regex, replacement)) {
452452 return text;
453453 }
454454 return Pattern.compile(regex, Pattern.DOTALL).matcher(text).replaceAll(replacement);
3737 * detail message.</p>
3838 */
3939 public SerializationException() {
40 super();
4140 }
4241
4342 /**
4444 * @since 1.0
4545 */
4646 public class SerializationUtils {
47
48 /**
49 * <p>SerializationUtils instances should NOT be constructed in standard programming.
50 * Instead, the class should be used as {@code SerializationUtils.clone(object)}.</p>
51 *
52 * <p>This constructor is public to permit tools that require a JavaBean instance
53 * to operate.</p>
54 * @since 2.0
55 */
56 public SerializationUtils() {
57 super();
58 }
59
60 // Clone
61 //-----------------------------------------------------------------------
62 /**
63 * <p>Deep clone an {@code Object} using serialization.</p>
64 *
65 * <p>This is many times slower than writing clone methods by hand
66 * on all objects in your object graph. However, for complex object
67 * graphs, or for those that don't support deep cloning this can
68 * be a simple alternative implementation. Of course all the objects
69 * must be {@code Serializable}.</p>
70 *
71 * @param <T> the type of the object involved
72 * @param object the {@code Serializable} object to clone
73 * @return the cloned object
74 * @throws SerializationException (runtime) if the serialization fails
75 */
76 public static <T extends Serializable> T clone(final T object) {
77 if (object == null) {
78 return null;
79 }
80 final byte[] objectData = serialize(object);
81 final ByteArrayInputStream bais = new ByteArrayInputStream(objectData);
82
83 try (ClassLoaderAwareObjectInputStream in = new ClassLoaderAwareObjectInputStream(bais,
84 object.getClass().getClassLoader())) {
85 /*
86 * when we serialize and deserialize an object,
87 * it is reasonable to assume the deserialized object
88 * is of the same type as the original serialized object
89 */
90 @SuppressWarnings("unchecked") // see above
91 final T readObject = (T) in.readObject();
92 return readObject;
93
94 } catch (final ClassNotFoundException ex) {
95 throw new SerializationException("ClassNotFoundException while reading cloned object data", ex);
96 } catch (final IOException ex) {
97 throw new SerializationException("IOException while reading or closing cloned object data", ex);
98 }
99 }
100
101 /**
102 * Performs a serialization roundtrip. Serializes and deserializes the given object, great for testing objects that
103 * implement {@link Serializable}.
104 *
105 * @param <T>
106 * the type of the object involved
107 * @param msg
108 * the object to roundtrip
109 * @return the serialized and deserialized object
110 * @since 3.3
111 */
112 @SuppressWarnings("unchecked") // OK, because we serialized a type `T`
113 public static <T extends Serializable> T roundtrip(final T msg) {
114 return (T) deserialize(serialize(msg));
115 }
116
117 // Serialize
118 //-----------------------------------------------------------------------
119 /**
120 * <p>Serializes an {@code Object} to the specified stream.</p>
121 *
122 * <p>The stream will be closed once the object is written.
123 * This avoids the need for a finally clause, and maybe also exception
124 * handling, in the application code.</p>
125 *
126 * <p>The stream passed in is not buffered internally within this method.
127 * This is the responsibility of your application if desired.</p>
128 *
129 * @param obj the object to serialize to bytes, may be null
130 * @param outputStream the stream to write to, must not be null
131 * @throws NullPointerException if {@code outputStream} is {@code null}
132 * @throws SerializationException (runtime) if the serialization fails
133 */
134 public static void serialize(final Serializable obj, final OutputStream outputStream) {
135 Validate.notNull(outputStream, "The OutputStream must not be null");
136 try (ObjectOutputStream out = new ObjectOutputStream(outputStream)) {
137 out.writeObject(obj);
138 } catch (final IOException ex) {
139 throw new SerializationException(ex);
140 }
141 }
142
143 /**
144 * <p>Serializes an {@code Object} to a byte array for
145 * storage/serialization.</p>
146 *
147 * @param obj the object to serialize to bytes
148 * @return a byte[] with the converted Serializable
149 * @throws SerializationException (runtime) if the serialization fails
150 */
151 public static byte[] serialize(final Serializable obj) {
152 final ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
153 serialize(obj, baos);
154 return baos.toByteArray();
155 }
156
157 // Deserialize
158 //-----------------------------------------------------------------------
159 /**
160 * <p>
161 * Deserializes an {@code Object} from the specified stream.
162 * </p>
163 *
164 * <p>
165 * The stream will be closed once the object is written. This avoids the need for a finally clause, and maybe also
166 * exception handling, in the application code.
167 * </p>
168 *
169 * <p>
170 * The stream passed in is not buffered internally within this method. This is the responsibility of your
171 * application if desired.
172 * </p>
173 *
174 * <p>
175 * If the call site incorrectly types the return value, a {@link ClassCastException} is thrown from the call site.
176 * Without Generics in this declaration, the call site must type cast and can cause the same ClassCastException.
177 * Note that in both cases, the ClassCastException is in the call site, not in this method.
178 * </p>
179 *
180 * @param <T> the object type to be deserialized
181 * @param inputStream
182 * the serialized object input stream, must not be null
183 * @return the deserialized object
184 * @throws NullPointerException if {@code inputStream} is {@code null}
185 * @throws SerializationException (runtime) if the serialization fails
186 */
187 public static <T> T deserialize(final InputStream inputStream) {
188 Validate.notNull(inputStream, "The InputStream must not be null");
189 try (ObjectInputStream in = new ObjectInputStream(inputStream)) {
190 @SuppressWarnings("unchecked")
191 final T obj = (T) in.readObject();
192 return obj;
193 } catch (final ClassNotFoundException | IOException ex) {
194 throw new SerializationException(ex);
195 }
196 }
197
198 /**
199 * <p>
200 * Deserializes a single {@code Object} from an array of bytes.
201 * </p>
202 *
203 * <p>
204 * If the call site incorrectly types the return value, a {@link ClassCastException} is thrown from the call site.
205 * Without Generics in this declaration, the call site must type cast and can cause the same ClassCastException.
206 * Note that in both cases, the ClassCastException is in the call site, not in this method.
207 * </p>
208 *
209 * @param <T> the object type to be deserialized
210 * @param objectData
211 * the serialized object, must not be null
212 * @return the deserialized object
213 * @throws NullPointerException if {@code objectData} is {@code null}
214 * @throws SerializationException (runtime) if the serialization fails
215 */
216 public static <T> T deserialize(final byte[] objectData) {
217 Validate.notNull(objectData, "The byte[] must not be null");
218 return deserialize(new ByteArrayInputStream(objectData));
219 }
22047
22148 /**
22249 * <p>Custom specialization of the standard JDK {@link java.io.ObjectInputStream}
289116
290117 }
291118
119 /**
120 * <p>Deep clone an {@code Object} using serialization.</p>
121 *
122 * <p>This is many times slower than writing clone methods by hand
123 * on all objects in your object graph. However, for complex object
124 * graphs, or for those that don't support deep cloning this can
125 * be a simple alternative implementation. Of course all the objects
126 * must be {@code Serializable}.</p>
127 *
128 * @param <T> the type of the object involved
129 * @param object the {@code Serializable} object to clone
130 * @return the cloned object
131 * @throws SerializationException (runtime) if the serialization fails
132 */
133 public static <T extends Serializable> T clone(final T object) {
134 if (object == null) {
135 return null;
136 }
137 final byte[] objectData = serialize(object);
138 final ByteArrayInputStream bais = new ByteArrayInputStream(objectData);
139
140 try (ClassLoaderAwareObjectInputStream in = new ClassLoaderAwareObjectInputStream(bais,
141 object.getClass().getClassLoader())) {
142 /*
143 * when we serialize and deserialize an object,
144 * it is reasonable to assume the deserialized object
145 * is of the same type as the original serialized object
146 */
147 @SuppressWarnings("unchecked") // see above
148 final T readObject = (T) in.readObject();
149 return readObject;
150
151 } catch (final ClassNotFoundException ex) {
152 throw new SerializationException("ClassNotFoundException while reading cloned object data", ex);
153 } catch (final IOException ex) {
154 throw new SerializationException("IOException while reading or closing cloned object data", ex);
155 }
156 }
157
158 /**
159 * <p>
160 * Deserializes a single {@code Object} from an array of bytes.
161 * </p>
162 *
163 * <p>
164 * If the call site incorrectly types the return value, a {@link ClassCastException} is thrown from the call site.
165 * Without Generics in this declaration, the call site must type cast and can cause the same ClassCastException.
166 * Note that in both cases, the ClassCastException is in the call site, not in this method.
167 * </p>
168 *
169 * @param <T> the object type to be deserialized
170 * @param objectData
171 * the serialized object, must not be null
172 * @return the deserialized object
173 * @throws NullPointerException if {@code objectData} is {@code null}
174 * @throws SerializationException (runtime) if the serialization fails
175 */
176 public static <T> T deserialize(final byte[] objectData) {
177 Validate.notNull(objectData, "objectData");
178 return deserialize(new ByteArrayInputStream(objectData));
179 }
180
181 /**
182 * <p>
183 * Deserializes an {@code Object} from the specified stream.
184 * </p>
185 *
186 * <p>
187 * The stream will be closed once the object is written. This avoids the need for a finally clause, and maybe also
188 * exception handling, in the application code.
189 * </p>
190 *
191 * <p>
192 * The stream passed in is not buffered internally within this method. This is the responsibility of your
193 * application if desired.
194 * </p>
195 *
196 * <p>
197 * If the call site incorrectly types the return value, a {@link ClassCastException} is thrown from the call site.
198 * Without Generics in this declaration, the call site must type cast and can cause the same ClassCastException.
199 * Note that in both cases, the ClassCastException is in the call site, not in this method.
200 * </p>
201 *
202 * @param <T> the object type to be deserialized
203 * @param inputStream
204 * the serialized object input stream, must not be null
205 * @return the deserialized object
206 * @throws NullPointerException if {@code inputStream} is {@code null}
207 * @throws SerializationException (runtime) if the serialization fails
208 */
209 @SuppressWarnings("resource") // inputStream is managed by the caller
210 public static <T> T deserialize(final InputStream inputStream) {
211 Validate.notNull(inputStream, "inputStream");
212 try (ObjectInputStream in = new ObjectInputStream(inputStream)) {
213 @SuppressWarnings("unchecked")
214 final T obj = (T) in.readObject();
215 return obj;
216 } catch (final ClassNotFoundException | IOException ex) {
217 throw new SerializationException(ex);
218 }
219 }
220
221 /**
222 * Performs a serialization roundtrip. Serializes and deserializes the given object, great for testing objects that
223 * implement {@link Serializable}.
224 *
225 * @param <T>
226 * the type of the object involved
227 * @param obj
228 * the object to roundtrip
229 * @return the serialized and deserialized object
230 * @since 3.3
231 */
232 @SuppressWarnings("unchecked") // OK, because we serialized a type `T`
233 public static <T extends Serializable> T roundtrip(final T obj) {
234 return (T) deserialize(serialize(obj));
235 }
236
237 /**
238 * <p>Serializes an {@code Object} to a byte array for
239 * storage/serialization.</p>
240 *
241 * @param obj the object to serialize to bytes
242 * @return a byte[] with the converted Serializable
243 * @throws SerializationException (runtime) if the serialization fails
244 */
245 public static byte[] serialize(final Serializable obj) {
246 final ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
247 serialize(obj, baos);
248 return baos.toByteArray();
249 }
250
251 /**
252 * <p>Serializes an {@code Object} to the specified stream.</p>
253 *
254 * <p>The stream will be closed once the object is written.
255 * This avoids the need for a finally clause, and maybe also exception
256 * handling, in the application code.</p>
257 *
258 * <p>The stream passed in is not buffered internally within this method.
259 * This is the responsibility of your application if desired.</p>
260 *
261 * @param obj the object to serialize to bytes, may be null
262 * @param outputStream the stream to write to, must not be null
263 * @throws NullPointerException if {@code outputStream} is {@code null}
264 * @throws SerializationException (runtime) if the serialization fails
265 */
266 @SuppressWarnings("resource") // outputStream is managed by the caller
267 public static void serialize(final Serializable obj, final OutputStream outputStream) {
268 Validate.notNull(outputStream, "outputStream");
269 try (ObjectOutputStream out = new ObjectOutputStream(outputStream)) {
270 out.writeObject(obj);
271 } catch (final IOException ex) {
272 throw new SerializationException(ex);
273 }
274 }
275
276 /**
277 * <p>SerializationUtils instances should NOT be constructed in standard programming.
278 * Instead, the class should be used as {@code SerializationUtils.clone(object)}.</p>
279 *
280 * <p>This constructor is public to permit tools that require a JavaBean instance
281 * to operate.</p>
282 * @since 2.0
283 */
284 public SerializationUtils() {
285 }
286
292287 }
4242 * not to throw Exceptions, at least not checked Exceptions, AKA instances
4343 * of {@link Exception}. This enforces the use of constructs like
4444 * <pre>
45 * Consumer&lt;java.lang.reflect.Method&gt; consumer = (m) -&gt; {
45 * Consumer&lt;java.lang.reflect.Method&gt; consumer = m -&gt; {
4646 * try {
4747 * m.invoke(o, args);
4848 * } catch (Throwable t) {
439439 }
440440
441441 /**
442 * A Collector type for arrays.
443 *
444 * @param <O> The array type.
442445 * @deprecated Use {@link org.apache.commons.lang3.stream.Streams.ArrayCollector}.
443446 */
444447 @Deprecated
446449 private static final Set<Characteristics> characteristics = Collections.emptySet();
447450 private final Class<O> elementType;
448451
452 /**
453 * Constructs a new instance for the given element type.
454 *
455 * @param elementType The element type.
456 */
449457 public ArrayCollector(final Class<O> elementType) {
450458 this.elementType = elementType;
451459 }
427427 * instance to operate.</p>
428428 */
429429 public StringEscapeUtils() {
430 super();
431430 }
432431
433432 // Java and JavaScript
2626 import java.util.Locale;
2727 import java.util.Objects;
2828 import java.util.Set;
29 import java.util.StringJoiner;
2930 import java.util.function.Supplier;
3031 import java.util.regex.Pattern;
32
33 import org.apache.commons.lang3.function.ToBooleanBiFunction;
3134
3235 /**
3336 * <p>Operations on {@link java.lang.String} that are
183186 */
184187 private static final Pattern STRIP_ACCENTS_PATTERN = Pattern.compile("\\p{InCombiningDiacriticalMarks}+"); //$NON-NLS-1$
185188
186 // Abbreviating
187 //-----------------------------------------------------------------------
188189 /**
189190 * <p>Abbreviates a String using ellipses. This will turn
190191 * "Now is the time for all good men" into "Now is the time for..."</p>
348349 if (maxWidth < minAbbrevWidth) {
349350 throw new IllegalArgumentException(String.format("Minimum abbreviation width is %d", minAbbrevWidth));
350351 }
351 if (str.length() <= maxWidth) {
352 final int strLen = str.length();
353 if (strLen <= maxWidth) {
352354 return str;
353355 }
354 if (offset > str.length()) {
355 offset = str.length();
356 }
357 if (str.length() - offset < maxWidth - abbrevMarkerLength) {
358 offset = str.length() - (maxWidth - abbrevMarkerLength);
356 if (offset > strLen) {
357 offset = strLen;
358 }
359 if (strLen - offset < maxWidth - abbrevMarkerLength) {
360 offset = strLen - (maxWidth - abbrevMarkerLength);
359361 }
360362 if (offset <= abbrevMarkerLength+1) {
361363 return str.substring(0, maxWidth - abbrevMarkerLength) + abbrevMarker;
363365 if (maxWidth < minAbbrevWidthOffset) {
364366 throw new IllegalArgumentException(String.format("Minimum abbreviation width with offset is %d", minAbbrevWidthOffset));
365367 }
366 if (offset + maxWidth - abbrevMarkerLength < str.length()) {
368 if (offset + maxWidth - abbrevMarkerLength < strLen) {
367369 return abbrevMarker + abbreviate(str.substring(offset), abbrevMarker, maxWidth - abbrevMarkerLength);
368370 }
369 return abbrevMarker + str.substring(str.length() - (maxWidth - abbrevMarkerLength));
371 return abbrevMarker + str.substring(strLen - (maxWidth - abbrevMarkerLength));
370372 }
371373
372374 /**
558560 return new String(newCodePoints, 0, outOffset);
559561 }
560562
561 // Centering
562 //-----------------------------------------------------------------------
563563 /**
564564 * <p>Centers a String in a larger String of size {@code size}
565565 * using the space character (' ').</p>
668668 return str;
669669 }
670670
671 // Chomping
672 //-----------------------------------------------------------------------
673671 /**
674672 * <p>Removes one newline from end of a String if it's there,
675673 * otherwise leave it alone. A newline is &quot;{@code \n}&quot;,
753751 return removeEnd(str, separator);
754752 }
755753
756 // Chopping
757 //-----------------------------------------------------------------------
758754 /**
759755 * <p>Remove the last character from a String.</p>
760756 *
795791 return ret;
796792 }
797793
798 // Compare
799 //-----------------------------------------------------------------------
800794 /**
801795 * <p>Compare two Strings lexicographically, as per {@link String#compareTo(String)}, returning :</p>
802796 * <ul>
868862 * @since 3.5
869863 */
870864 public static int compare(final String str1, final String str2, final boolean nullIsLess) {
871 if (str1 == str2) {
865 if (str1 == str2) { // NOSONARLINT this intentionally uses == to allow for both null
872866 return 0;
873867 }
874868 if (str1 == null) {
961955 * @since 3.5
962956 */
963957 public static int compareIgnoreCase(final String str1, final String str2, final boolean nullIsLess) {
964 if (str1 == str2) {
958 if (str1 == str2) { // NOSONARLINT this intentionally uses == to allow for both null
965959 return 0;
966960 }
967961 if (str1 == null) {
1002996 return CharSequenceUtils.indexOf(seq, searchSeq, 0) >= 0;
1003997 }
1004998
1005 // Contains
1006 //-----------------------------------------------------------------------
1007999 /**
10081000 * <p>Checks if CharSequence contains a search character, handling {@code null}.
10091001 * This method uses {@link String#indexOf(int)} if possible.</p>
10311023 return CharSequenceUtils.indexOf(seq, searchChar, 0) >= 0;
10321024 }
10331025
1034 // ContainsAny
1035 //-----------------------------------------------------------------------
10361026 /**
10371027 * <p>Checks if the CharSequence contains any character in the given
10381028 * set of characters.</p>
11271117 }
11281118
11291119 /**
1130 * <p>Checks if the CharSequence contains any of the CharSequences in the given array.</p>
1131 *
11321120 * <p>
1133 * A {@code null} {@code cs} CharSequence will return {@code false}. A {@code null} or zero
1134 * length search array will return {@code false}.
1121 * Checks if the CharSequence contains any of the CharSequences in the given array.
1122 * </p>
1123 *
1124 * <p>
1125 * A {@code null} {@code cs} CharSequence will return {@code false}. A {@code null} or zero length search array will
1126 * return {@code false}.
11351127 * </p>
11361128 *
11371129 * <pre>
11461138 *
11471139 *
11481140 * @param cs The CharSequence to check, may be null
1149 * @param searchCharSequences The array of CharSequences to search for, may be null.
1150 * Individual CharSequences may be null as well.
1141 * @param searchCharSequences The array of CharSequences to search for, may be null. Individual CharSequences may be
1142 * null as well.
11511143 * @return {@code true} if any of the search CharSequences are found, {@code false} otherwise
11521144 * @since 3.4
11531145 */
11541146 public static boolean containsAny(final CharSequence cs, final CharSequence... searchCharSequences) {
1147 return containsAny(StringUtils::contains, cs, searchCharSequences);
1148 }
1149
1150 /**
1151 * <p>
1152 * Checks if the CharSequence contains any of the CharSequences in the given array.
1153 * </p>
1154 *
1155 * <p>
1156 * A {@code null} {@code cs} CharSequence will return {@code false}. A {@code null} or zero length search array will
1157 * return {@code false}.
1158 * </p>
1159 *
1160 * @param cs The CharSequence to check, may be null
1161 * @param searchCharSequences The array of CharSequences to search for, may be null. Individual CharSequences may be
1162 * null as well.
1163 * @return {@code true} if any of the search CharSequences are found, {@code false} otherwise
1164 * @since 3.12.0
1165 */
1166 private static boolean containsAny(final ToBooleanBiFunction<CharSequence, CharSequence> test,
1167 final CharSequence cs, final CharSequence... searchCharSequences) {
11551168 if (isEmpty(cs) || ArrayUtils.isEmpty(searchCharSequences)) {
11561169 return false;
11571170 }
11581171 for (final CharSequence searchCharSequence : searchCharSequences) {
1159 if (contains(cs, searchCharSequence)) {
1172 if (test.applyAsBoolean(cs, searchCharSequence)) {
11601173 return true;
11611174 }
11621175 }
11631176 return false;
1177 }
1178
1179 /**
1180 * <p>
1181 * Checks if the CharSequence contains any of the CharSequences in the given array, ignoring case.
1182 * </p>
1183 *
1184 * <p>
1185 * A {@code null} {@code cs} CharSequence will return {@code false}. A {@code null} or zero length search array will
1186 * return {@code false}.
1187 * </p>
1188 *
1189 * <pre>
1190 * StringUtils.containsAny(null, *) = false
1191 * StringUtils.containsAny("", *) = false
1192 * StringUtils.containsAny(*, null) = false
1193 * StringUtils.containsAny(*, []) = false
1194 * StringUtils.containsAny("abcd", "ab", null) = true
1195 * StringUtils.containsAny("abcd", "ab", "cd") = true
1196 * StringUtils.containsAny("abc", "d", "abc") = true
1197 * StringUtils.containsAny("abc", "D", "ABC") = true
1198 * StringUtils.containsAny("ABC", "d", "abc") = true
1199 * </pre>
1200 *
1201 *
1202 * @param cs The CharSequence to check, may be null
1203 * @param searchCharSequences The array of CharSequences to search for, may be null. Individual CharSequences may be
1204 * null as well.
1205 * @return {@code true} if any of the search CharSequences are found, {@code false} otherwise
1206 * @since 3.12.0
1207 */
1208 public static boolean containsAnyIgnoreCase(final CharSequence cs, final CharSequence... searchCharSequences) {
1209 return containsAny(StringUtils::containsIgnoreCase, cs, searchCharSequences);
11641210 }
11651211
11661212 /**
12011247 return false;
12021248 }
12031249
1204 // ContainsNone
1205 //-----------------------------------------------------------------------
12061250 /**
12071251 * <p>Checks that the CharSequence does not contain certain characters.</p>
12081252 *
12801324 * @since 3.0 Changed signature from containsNone(String, String) to containsNone(CharSequence, String)
12811325 */
12821326 public static boolean containsNone(final CharSequence cs, final String invalidChars) {
1283 if (cs == null || invalidChars == null) {
1327 if (invalidChars == null) {
12841328 return true;
12851329 }
12861330 return containsNone(cs, invalidChars.toCharArray());
12871331 }
12881332
1289 // ContainsOnly
1290 //-----------------------------------------------------------------------
12911333 /**
12921334 * <p>Checks if the CharSequence contains only certain characters.</p>
12931335 *
13811423 private static void convertRemainingAccentCharacters(final StringBuilder decomposed) {
13821424 for (int i = 0; i < decomposed.length(); i++) {
13831425 if (decomposed.charAt(i) == '\u0141') {
1384 decomposed.deleteCharAt(i);
1385 decomposed.insert(i, 'L');
1426 decomposed.setCharAt(i, 'L');
13861427 } else if (decomposed.charAt(i) == '\u0142') {
1387 decomposed.deleteCharAt(i);
1388 decomposed.insert(i, 'l');
1428 decomposed.setCharAt(i, 'l');
13891429 }
13901430 }
13911431 }
14231463 return count;
14241464 }
14251465
1426 // Count matches
1427 //-----------------------------------------------------------------------
1428 /**
1429 * <p>Counts how many times the substring appears in the larger string.</p>
1466 /**
1467 * <p>Counts how many times the substring appears in the larger string.
1468 * Note that the code only counts non-overlapping matches.</p>
14301469 *
14311470 * <p>A {@code null} or empty ("") String input returns {@code 0}.</p>
14321471 *
14381477 * StringUtils.countMatches("abba", "a") = 2
14391478 * StringUtils.countMatches("abba", "ab") = 1
14401479 * StringUtils.countMatches("abba", "xxx") = 0
1480 * StringUtils.countMatches("ababa", "aba") = 1
14411481 * </pre>
14421482 *
14431483 * @param str the CharSequence to check, may be null
15451585 return str == null ? defaultStr : str;
15461586 }
15471587
1548 // Delete
1549 //-----------------------------------------------------------------------
15501588 /**
15511589 * <p>Deletes all whitespaces from a String as defined by
15521590 * {@link Character#isWhitespace(char)}.</p>
15761614 if (count == sz) {
15771615 return str;
15781616 }
1617 if (count == 0) {
1618 return EMPTY;
1619 }
15791620 return new String(chs, 0, count);
15801621 }
15811622
1582 // Difference
1583 //-----------------------------------------------------------------------
15841623 /**
15851624 * <p>Compares two Strings, and returns the portion where they differ.
15861625 * More precisely, return the remainder of the second String,
17331772 return endsWith(str, suffix, true);
17341773 }
17351774
1736 // Equals
1737 //-----------------------------------------------------------------------
17381775 /**
17391776 * <p>Compares two CharSequences, returning {@code true} if they represent
17401777 * equal sequences of characters.</p>
22512288 if (m == 0) {
22522289 return 0D;
22532290 }
2254 final double j = ((m / first.length() + m / second.length() + (m - mtp[1]) / m)) / 3;
2291 final double j = (m / first.length() + m / second.length() + (m - mtp[1]) / m) / 3;
22552292 final double jw = j < 0.7D ? j : j + Math.min(DEFAULT_SCALING_FACTOR, 1D / mtp[3]) * mtp[2] * (1D - j);
22562293 return Math.round(jw * 100.0D) / 100.0D;
22572294 }
22582295
2259 // Misc
2260 //-----------------------------------------------------------------------
22612296 /**
22622297 * <p>Find the Levenshtein distance between two Strings.</p>
22632298 *
25872622 return CharSequenceUtils.indexOf(seq, searchSeq, startPos);
25882623 }
25892624
2590 // IndexOf
2591 //-----------------------------------------------------------------------
25922625 /**
25932626 * Returns the index within {@code seq} of the first occurrence of
25942627 * the specified character. If a character with value
26932726 return CharSequenceUtils.indexOf(seq, searchChar, startPos);
26942727 }
26952728
2696 // IndexOfAny chars
2697 //-----------------------------------------------------------------------
26982729 /**
26992730 * <p>Search a CharSequence to find the first index of any
27002731 * character in the given set of characters.</p>
27442775 return INDEX_NOT_FOUND;
27452776 }
27462777
2747 // IndexOfAny strings
2748 //-----------------------------------------------------------------------
27492778 /**
27502779 * <p>Find the first index of any of a set of potential substrings.</p>
27512780 *
28292858 return indexOfAny(cs, searchChars.toCharArray());
28302859 }
28312860
2832 // IndexOfAnyBut chars
2833 //-----------------------------------------------------------------------
28342861 /**
28352862 * <p>Searches a CharSequence to find the first index of any
28362863 * character not in the given set of characters.</p>
29182945 if (chFound && CharSequenceUtils.indexOf(searchChars, ch2, 0) < 0) {
29192946 return i;
29202947 }
2921 } else {
2922 if (!chFound) {
2923 return i;
2924 }
2948 } else if (!chFound) {
2949 return i;
29252950 }
29262951 }
29272952 return INDEX_NOT_FOUND;
32783303 return true;
32793304 }
32803305
3281 // Character Tests
3282 //-----------------------------------------------------------------------
32833306 /**
32843307 * <p>Checks if the CharSequence contains only Unicode letters.</p>
32853308 *
33763399 }
33773400 final int sz = cs.length();
33783401 for (int i = 0; i < sz; i++) {
3379 if (!Character.isLetterOrDigit(cs.charAt(i)) && cs.charAt(i) != ' ') {
3402 final char nowChar = cs.charAt(i);
3403 if (nowChar != ' ' && !Character.isLetterOrDigit(nowChar) ) {
33803404 return false;
33813405 }
33823406 }
34113435 }
34123436 final int sz = cs.length();
34133437 for (int i = 0; i < sz; i++) {
3414 if (!Character.isLetter(cs.charAt(i)) && cs.charAt(i) != ' ') {
3438 final char nowChar = cs.charAt(i);
3439 if (nowChar != ' ' && !Character.isLetter(nowChar)) {
34153440 return false;
34163441 }
34173442 }
34423467 * @since 3.2
34433468 */
34443469 public static boolean isAnyBlank(final CharSequence... css) {
3445 if (ArrayUtils.isEmpty(css)) {
3470 if (ArrayUtils.isEmpty(css)) {
3471 return false;
3472 }
3473 for (final CharSequence cs : css) {
3474 if (isBlank(cs)) {
3475 return true;
3476 }
3477 }
34463478 return false;
3447 }
3448 for (final CharSequence cs : css) {
3449 if (isBlank(cs)) {
3450 return true;
3451 }
3452 }
3453 return false;
34543479 }
34553480
34563481 /**
34743499 * @since 3.2
34753500 */
34763501 public static boolean isAnyEmpty(final CharSequence... css) {
3477 if (ArrayUtils.isEmpty(css)) {
3502 if (ArrayUtils.isEmpty(css)) {
3503 return false;
3504 }
3505 for (final CharSequence cs : css) {
3506 if (isEmpty(cs)) {
3507 return true;
3508 }
3509 }
34783510 return false;
3479 }
3480 for (final CharSequence cs : css) {
3481 if (isEmpty(cs)) {
3482 return true;
3483 }
3484 }
3485 return false;
34863511 }
34873512
34883513 /**
35243549 return true;
35253550 }
35263551
3527 // Nested extraction
3528 //-----------------------------------------------------------------------
3529
35303552 /**
35313553 * <p>Checks if a CharSequence is empty (""), null or whitespace only.</p>
35323554 *
35583580 return true;
35593581 }
35603582
3561 // Empty checks
3562 //-----------------------------------------------------------------------
35633583 /**
35643584 * <p>Checks if a CharSequence is empty ("") or null.</p>
35653585 *
37753795 * StringUtils.isNumericSpace(" ") = true
37763796 * StringUtils.isNumericSpace("123") = true
37773797 * StringUtils.isNumericSpace("12 3") = true
3778 * StringUtils.isNumeric("\u0967\u0968\u0969") = true
3779 * StringUtils.isNumeric("\u0967\u0968 \u0969") = true
3798 * StringUtils.isNumericSpace("\u0967\u0968\u0969") = true
3799 * StringUtils.isNumericSpace("\u0967\u0968 \u0969") = true
37803800 * StringUtils.isNumericSpace("ab2c") = false
37813801 * StringUtils.isNumericSpace("12-3") = false
37823802 * StringUtils.isNumericSpace("12.3") = false
37933813 }
37943814 final int sz = cs.length();
37953815 for (int i = 0; i < sz; i++) {
3796 if (!Character.isDigit(cs.charAt(i)) && cs.charAt(i) != ' ') {
3816 final char nowChar = cs.charAt(i);
3817 if (nowChar != ' ' && !Character.isDigit(nowChar)) {
37973818 return false;
37983819 }
37993820 }
38463867 * </p>
38473868 *
38483869 * <pre>
3870 * StringUtils.join(null, *) = null
3871 * StringUtils.join([], *) = ""
3872 * StringUtils.join([null], *) = ""
3873 * StringUtils.join([false, false], ';') = "false;false"
3874 * </pre>
3875 *
3876 * @param array
3877 * the array of values to join together, may be null
3878 * @param delimiter
3879 * the separator character to use
3880 * @return the joined String, {@code null} if null array input
3881 * @since 3.12.0
3882 */
3883 public static String join(final boolean[] array, final char delimiter) {
3884 if (array == null) {
3885 return null;
3886 }
3887 return join(array, delimiter, 0, array.length);
3888 }
3889
3890 /**
3891 * <p>
3892 * Joins the elements of the provided array into a single String containing the provided list of elements.
3893 * </p>
3894 *
3895 * <p>
3896 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented
3897 * by empty strings.
3898 * </p>
3899 *
3900 * <pre>
3901 * StringUtils.join(null, *) = null
3902 * StringUtils.join([], *) = ""
3903 * StringUtils.join([null], *) = ""
3904 * StringUtils.join([true, false, true], ';') = "true;false;true"
3905 * </pre>
3906 *
3907 * @param array
3908 * the array of values to join together, may be null
3909 * @param delimiter
3910 * the separator character to use
3911 * @param startIndex
3912 * the first index to start joining from. It is an error to pass in a start index past the end of the
3913 * array
3914 * @param endIndex
3915 * the index to stop joining from (exclusive). It is an error to pass in an end index past the end of
3916 * the array
3917 * @return the joined String, {@code null} if null array input
3918 * @since 3.12.0
3919 */
3920 public static String join(final boolean[] array, final char delimiter, final int startIndex, final int endIndex) {
3921 if (array == null) {
3922 return null;
3923 }
3924 if (endIndex - startIndex <= 0) {
3925 return EMPTY;
3926 }
3927 final StringJoiner joiner = newStringJoiner(delimiter);
3928 for (int i = startIndex; i < endIndex; i++) {
3929 joiner.add(String.valueOf(array[i]));
3930 }
3931 return joiner.toString();
3932 }
3933
3934 /**
3935 * <p>
3936 * Joins the elements of the provided array into a single String containing the provided list of elements.
3937 * </p>
3938 *
3939 * <p>
3940 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented
3941 * by empty strings.
3942 * </p>
3943 *
3944 * <pre>
38493945 * StringUtils.join(null, *) = null
38503946 * StringUtils.join([], *) = ""
38513947 * StringUtils.join([null], *) = ""
38553951 *
38563952 * @param array
38573953 * the array of values to join together, may be null
3858 * @param separator
3954 * @param delimiter
38593955 * the separator character to use
38603956 * @return the joined String, {@code null} if null array input
38613957 * @since 3.2
38623958 */
3863 public static String join(final byte[] array, final char separator) {
3959 public static String join(final byte[] array, final char delimiter) {
38643960 if (array == null) {
38653961 return null;
38663962 }
3867 return join(array, separator, 0, array.length);
3963 return join(array, delimiter, 0, array.length);
38683964 }
38693965
38703966 /**
38873983 *
38883984 * @param array
38893985 * the array of values to join together, may be null
3890 * @param separator
3986 * @param delimiter
38913987 * the separator character to use
38923988 * @param startIndex
38933989 * the first index to start joining from. It is an error to pass in a start index past the end of the
38983994 * @return the joined String, {@code null} if null array input
38993995 * @since 3.2
39003996 */
3901 public static String join(final byte[] array, final char separator, final int startIndex, final int endIndex) {
3997 public static String join(final byte[] array, final char delimiter, final int startIndex, final int endIndex) {
39023998 if (array == null) {
39033999 return null;
39044000 }
3905 final int noOfItems = endIndex - startIndex;
3906 if (noOfItems <= 0) {
4001 if (endIndex - startIndex <= 0) {
39074002 return EMPTY;
39084003 }
3909 final StringBuilder buf = newStringBuilder(noOfItems);
3910 buf.append(array[startIndex]);
3911 for (int i = startIndex + 1; i < endIndex; i++) {
3912 buf.append(separator);
3913 buf.append(array[i]);
3914 }
3915 return buf.toString();
4004 final StringJoiner joiner = newStringJoiner(delimiter);
4005 for (int i = startIndex; i < endIndex; i++) {
4006 joiner.add(String.valueOf(array[i]));
4007 }
4008 return joiner.toString();
39164009 }
39174010
39184011 /**
39354028 *
39364029 * @param array
39374030 * the array of values to join together, may be null
3938 * @param separator
4031 * @param delimiter
39394032 * the separator character to use
39404033 * @return the joined String, {@code null} if null array input
39414034 * @since 3.2
39424035 */
3943 public static String join(final char[] array, final char separator) {
4036 public static String join(final char[] array, final char delimiter) {
39444037 if (array == null) {
39454038 return null;
39464039 }
3947 return join(array, separator, 0, array.length);
4040 return join(array, delimiter, 0, array.length);
39484041 }
39494042
39504043 /**
39674060 *
39684061 * @param array
39694062 * the array of values to join together, may be null
3970 * @param separator
4063 * @param delimiter
39714064 * the separator character to use
39724065 * @param startIndex
39734066 * the first index to start joining from. It is an error to pass in a start index past the end of the
39784071 * @return the joined String, {@code null} if null array input
39794072 * @since 3.2
39804073 */
3981 public static String join(final char[] array, final char separator, final int startIndex, final int endIndex) {
4074 public static String join(final char[] array, final char delimiter, final int startIndex, final int endIndex) {
39824075 if (array == null) {
39834076 return null;
39844077 }
3985 final int noOfItems = endIndex - startIndex;
3986 if (noOfItems <= 0) {
4078 if (endIndex - startIndex <= 0) {
39874079 return EMPTY;
39884080 }
3989 final StringBuilder buf = newStringBuilder(noOfItems);
3990 buf.append(array[startIndex]);
3991 for (int i = startIndex + 1; i < endIndex; i++) {
3992 buf.append(separator);
3993 buf.append(array[i]);
3994 }
3995 return buf.toString();
4081 final StringJoiner joiner = newStringJoiner(delimiter);
4082 for (int i = startIndex; i < endIndex; i++) {
4083 joiner.add(String.valueOf(array[i]));
4084 }
4085 return joiner.toString();
39964086 }
39974087
39984088 /**
40154105 *
40164106 * @param array
40174107 * the array of values to join together, may be null
4018 * @param separator
4108 * @param delimiter
40194109 * the separator character to use
40204110 * @return the joined String, {@code null} if null array input
40214111 * @since 3.2
40224112 */
4023 public static String join(final double[] array, final char separator) {
4113 public static String join(final double[] array, final char delimiter) {
40244114 if (array == null) {
40254115 return null;
40264116 }
4027 return join(array, separator, 0, array.length);
4117 return join(array, delimiter, 0, array.length);
40284118 }
40294119
40304120 /**
40474137 *
40484138 * @param array
40494139 * the array of values to join together, may be null
4050 * @param separator
4140 * @param delimiter
40514141 * the separator character to use
40524142 * @param startIndex
40534143 * the first index to start joining from. It is an error to pass in a start index past the end of the
40584148 * @return the joined String, {@code null} if null array input
40594149 * @since 3.2
40604150 */
4061 public static String join(final double[] array, final char separator, final int startIndex, final int endIndex) {
4151 public static String join(final double[] array, final char delimiter, final int startIndex, final int endIndex) {
40624152 if (array == null) {
40634153 return null;
40644154 }
4065 final int noOfItems = endIndex - startIndex;
4066 if (noOfItems <= 0) {
4155 if (endIndex - startIndex <= 0) {
40674156 return EMPTY;
40684157 }
4069 final StringBuilder buf = newStringBuilder(noOfItems);
4070 buf.append(array[startIndex]);
4071 for (int i = startIndex + 1; i < endIndex; i++) {
4072 buf.append(separator);
4073 buf.append(array[i]);
4074 }
4075 return buf.toString();
4158 final StringJoiner joiner = newStringJoiner(delimiter);
4159 for (int i = startIndex; i < endIndex; i++) {
4160 joiner.add(String.valueOf(array[i]));
4161 }
4162 return joiner.toString();
40764163 }
40774164
40784165 /**
40954182 *
40964183 * @param array
40974184 * the array of values to join together, may be null
4098 * @param separator
4185 * @param delimiter
40994186 * the separator character to use
41004187 * @return the joined String, {@code null} if null array input
41014188 * @since 3.2
41024189 */
4103 public static String join(final float[] array, final char separator) {
4190 public static String join(final float[] array, final char delimiter) {
41044191 if (array == null) {
41054192 return null;
41064193 }
4107 return join(array, separator, 0, array.length);
4194 return join(array, delimiter, 0, array.length);
41084195 }
41094196
41104197 /**
41274214 *
41284215 * @param array
41294216 * the array of values to join together, may be null
4130 * @param separator
4217 * @param delimiter
41314218 * the separator character to use
41324219 * @param startIndex
41334220 * the first index to start joining from. It is an error to pass in a start index past the end of the
41384225 * @return the joined String, {@code null} if null array input
41394226 * @since 3.2
41404227 */
4141 public static String join(final float[] array, final char separator, final int startIndex, final int endIndex) {
4228 public static String join(final float[] array, final char delimiter, final int startIndex, final int endIndex) {
41424229 if (array == null) {
41434230 return null;
41444231 }
4145 final int noOfItems = endIndex - startIndex;
4146 if (noOfItems <= 0) {
4232 if (endIndex - startIndex <= 0) {
41474233 return EMPTY;
41484234 }
4149 final StringBuilder buf = newStringBuilder(noOfItems);
4150 buf.append(array[startIndex]);
4151 for (int i = startIndex + 1; i < endIndex; i++) {
4152 buf.append(separator);
4153 buf.append(array[i]);
4154 }
4155 return buf.toString();
4235 final StringJoiner joiner = newStringJoiner(delimiter);
4236 for (int i = startIndex; i < endIndex; i++) {
4237 joiner.add(String.valueOf(array[i]));
4238 }
4239 return joiner.toString();
41564240 }
41574241
41584242 /**
42074291 *
42084292 * @param array
42094293 * the array of values to join together, may be null
4210 * @param separator
4294 * @param delimiter
42114295 * the separator character to use
42124296 * @param startIndex
42134297 * the first index to start joining from. It is an error to pass in a start index past the end of the
42184302 * @return the joined String, {@code null} if null array input
42194303 * @since 3.2
42204304 */
4221 public static String join(final int[] array, final char separator, final int startIndex, final int endIndex) {
4305 public static String join(final int[] array, final char delimiter, final int startIndex, final int endIndex) {
42224306 if (array == null) {
42234307 return null;
42244308 }
4225 final int noOfItems = endIndex - startIndex;
4226 if (noOfItems <= 0) {
4309 if (endIndex - startIndex <= 0) {
42274310 return EMPTY;
42284311 }
4229 final StringBuilder buf = newStringBuilder(noOfItems);
4230 buf.append(array[startIndex]);
4231 for (int i = startIndex + 1; i < endIndex; i++) {
4232 buf.append(separator);
4233 buf.append(array[i]);
4234 }
4235 return buf.toString();
4312 final StringJoiner joiner = newStringJoiner(delimiter);
4313 for (int i = startIndex; i < endIndex; i++) {
4314 joiner.add(String.valueOf(array[i]));
4315 }
4316 return joiner.toString();
42364317 }
42374318
42384319 /**
43024383 }
43034384 final Object first = iterator.next();
43044385 if (!iterator.hasNext()) {
4305 return Objects.toString(first, EMPTY);
4386 return toStringOrEmpty(first);
43064387 }
43074388
43084389 // two or more elements
44964577 *
44974578 * @param array
44984579 * the array of values to join together, may be null
4499 * @param separator
4580 * @param delimiter
45004581 * the separator character to use
45014582 * @param startIndex
45024583 * the first index to start joining from. It is an error to pass in a start index past the end of the
45074588 * @return the joined String, {@code null} if null array input
45084589 * @since 3.2
45094590 */
4510 public static String join(final long[] array, final char separator, final int startIndex, final int endIndex) {
4591 public static String join(final long[] array, final char delimiter, final int startIndex, final int endIndex) {
45114592 if (array == null) {
45124593 return null;
45134594 }
4514 final int noOfItems = endIndex - startIndex;
4515 if (noOfItems <= 0) {
4595 if (endIndex - startIndex <= 0) {
45164596 return EMPTY;
45174597 }
4518 final StringBuilder buf = newStringBuilder(noOfItems);
4519 buf.append(array[startIndex]);
4520 for (int i = startIndex + 1; i < endIndex; i++) {
4521 buf.append(separator);
4522 buf.append(array[i]);
4523 }
4524 return buf.toString();
4598 final StringJoiner joiner = newStringJoiner(delimiter);
4599 for (int i = startIndex; i < endIndex; i++) {
4600 joiner.add(String.valueOf(array[i]));
4601 }
4602 return joiner.toString();
45254603 }
45264604
45274605 /**
45424620 * </pre>
45434621 *
45444622 * @param array the array of values to join together, may be null
4545 * @param separator the separator character to use
4623 * @param delimiter the separator character to use
45464624 * @return the joined String, {@code null} if null array input
45474625 * @since 2.0
45484626 */
4549 public static String join(final Object[] array, final char separator) {
4627 public static String join(final Object[] array, final char delimiter) {
45504628 if (array == null) {
45514629 return null;
45524630 }
4553 return join(array, separator, 0, array.length);
4631 return join(array, delimiter, 0, array.length);
45544632 }
45554633
45564634 /**
45714649 * </pre>
45724650 *
45734651 * @param array the array of values to join together, may be null
4574 * @param separator the separator character to use
4652 * @param delimiter the separator character to use
45754653 * @param startIndex the first index to start joining from. It is
45764654 * an error to pass in a start index past the end of the array
45774655 * @param endIndex the index to stop joining from (exclusive). It is
45794657 * @return the joined String, {@code null} if null array input
45804658 * @since 2.0
45814659 */
4582 public static String join(final Object[] array, final char separator, final int startIndex, final int endIndex) {
4660 public static String join(final Object[] array, final char delimiter, final int startIndex, final int endIndex) {
45834661 if (array == null) {
45844662 return null;
45854663 }
4586 final int noOfItems = endIndex - startIndex;
4587 if (noOfItems <= 0) {
4664 if (endIndex - startIndex <= 0) {
45884665 return EMPTY;
45894666 }
4590 final StringBuilder buf = newStringBuilder(noOfItems);
4591 if (array[startIndex] != null) {
4592 buf.append(array[startIndex]);
4593 }
4594 for (int i = startIndex + 1; i < endIndex; i++) {
4595 buf.append(separator);
4596 if (array[i] != null) {
4597 buf.append(array[i]);
4598 }
4599 }
4600 return buf.toString();
4667 final StringJoiner joiner = newStringJoiner(delimiter);
4668 for (int i = startIndex; i < endIndex; i++) {
4669 joiner.add(toStringOrEmpty(array[i]));
4670 }
4671 return joiner.toString();
46014672 }
46024673
46034674 /**
46204691 * </pre>
46214692 *
46224693 * @param array the array of values to join together, may be null
4623 * @param separator the separator character to use, null treated as ""
4694 * @param delimiter the separator character to use, null treated as ""
46244695 * @return the joined String, {@code null} if null array input
46254696 */
4626 public static String join(final Object[] array, final String separator) {
4697 public static String join(final Object[] array, final String delimiter) {
46274698 if (array == null) {
46284699 return null;
46294700 }
4630 return join(array, separator, 0, array.length);
4701 return join(array, delimiter, 0, array.length);
46314702 }
46324703
46334704 /**
46534724 * </pre>
46544725 *
46554726 * @param array the array of values to join together, may be null
4656 * @param separator the separator character to use, null treated as ""
4727 * @param delimiter the separator character to use, null treated as ""
46574728 * @param startIndex the first index to start joining from.
46584729 * @param endIndex the index to stop joining from (exclusive).
46594730 * @return the joined String, {@code null} if null array input; or the empty string
46654736 * {@code endIndex < 0} or <br>
46664737 * {@code endIndex > array.length()}
46674738 */
4668 public static String join(final Object[] array, String separator, final int startIndex, final int endIndex) {
4739 public static String join(final Object[] array, final String delimiter, final int startIndex, final int endIndex) {
46694740 if (array == null) {
46704741 return null;
46714742 }
4672 if (separator == null) {
4673 separator = EMPTY;
4674 }
4675
4676 // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator))
4677 // (Assuming that all Strings are roughly equally long)
4678 final int noOfItems = endIndex - startIndex;
4679 if (noOfItems <= 0) {
4743 if (endIndex - startIndex <= 0) {
46804744 return EMPTY;
46814745 }
4682
4683 final StringBuilder buf = newStringBuilder(noOfItems);
4684
4685 if (array[startIndex] != null) {
4686 buf.append(array[startIndex]);
4687 }
4688
4689 for (int i = startIndex + 1; i < endIndex; i++) {
4690 buf.append(separator);
4691
4692 if (array[i] != null) {
4693 buf.append(array[i]);
4694 }
4695 }
4696 return buf.toString();
4746 final StringJoiner joiner = new StringJoiner(toStringOrEmpty(delimiter));
4747 for (int i = startIndex; i < endIndex; i++) {
4748 joiner.add(toStringOrEmpty(array[i]));
4749 }
4750 return joiner.toString();
46974751 }
46984752
46994753 /**
47164770 *
47174771 * @param array
47184772 * the array of values to join together, may be null
4719 * @param separator
4773 * @param delimiter
47204774 * the separator character to use
47214775 * @return the joined String, {@code null} if null array input
47224776 * @since 3.2
47234777 */
4724 public static String join(final short[] array, final char separator) {
4778 public static String join(final short[] array, final char delimiter) {
47254779 if (array == null) {
47264780 return null;
47274781 }
4728 return join(array, separator, 0, array.length);
4782 return join(array, delimiter, 0, array.length);
47294783 }
47304784
47314785 /**
47484802 *
47494803 * @param array
47504804 * the array of values to join together, may be null
4751 * @param separator
4805 * @param delimiter
47524806 * the separator character to use
47534807 * @param startIndex
47544808 * the first index to start joining from. It is an error to pass in a start index past the end of the
47594813 * @return the joined String, {@code null} if null array input
47604814 * @since 3.2
47614815 */
4762 public static String join(final short[] array, final char separator, final int startIndex, final int endIndex) {
4816 public static String join(final short[] array, final char delimiter, final int startIndex, final int endIndex) {
47634817 if (array == null) {
47644818 return null;
47654819 }
4766 final int noOfItems = endIndex - startIndex;
4767 if (noOfItems <= 0) {
4820 if (endIndex - startIndex <= 0) {
47684821 return EMPTY;
47694822 }
4770 final StringBuilder buf = newStringBuilder(noOfItems);
4771 buf.append(array[startIndex]);
4772 for (int i = startIndex + 1; i < endIndex; i++) {
4773 buf.append(separator);
4774 buf.append(array[i]);
4775 }
4776 return buf.toString();
4777 }
4778
4779
4780 // Joining
4781 //-----------------------------------------------------------------------
4823 final StringJoiner joiner = newStringJoiner(delimiter);
4824 for (int i = startIndex; i < endIndex; i++) {
4825 joiner.add(String.valueOf(array[i]));
4826 }
4827 return joiner.toString();
4828 }
4829
47824830 /**
47834831 * <p>Joins the elements of the provided array into a single String
47844832 * containing the provided list of elements.</p>
48204868 * StringUtils.joinWith(null, {"a", "b"}) = "ab"
48214869 * </pre>
48224870 *
4823 * @param separator the separator character to use, null treated as ""
4824 * @param objects the varargs providing the values to join together. {@code null} elements are treated as ""
4871 * @param delimiter the separator character to use, null treated as ""
4872 * @param array the varargs providing the values to join together. {@code null} elements are treated as ""
48254873 * @return the joined String.
48264874 * @throws java.lang.IllegalArgumentException if a null varargs is provided
48274875 * @since 3.5
48284876 */
4829 public static String joinWith(final String separator, final Object... objects) {
4830 if (objects == null) {
4877 public static String joinWith(final String delimiter, final Object... array) {
4878 if (array == null) {
48314879 throw new IllegalArgumentException("Object varargs must not be null");
48324880 }
4833
4834 final String sanitizedSeparator = defaultString(separator);
4835
4836 final StringBuilder result = new StringBuilder();
4837
4838 final Iterator<Object> iterator = Arrays.asList(objects).iterator();
4839 while (iterator.hasNext()) {
4840 final String value = Objects.toString(iterator.next(), "");
4841 result.append(value);
4842
4843 if (iterator.hasNext()) {
4844 result.append(sanitizedSeparator);
4845 }
4846 }
4847
4848 return result.toString();
4881 return join(array, delimiter);
48494882 }
48504883
48514884 /**
48724905 * @since 3.0 Changed signature from lastIndexOf(String, String) to lastIndexOf(CharSequence, CharSequence)
48734906 */
48744907 public static int lastIndexOf(final CharSequence seq, final CharSequence searchSeq) {
4875 if (seq == null || searchSeq == null) {
4908 if (seq == null) {
48764909 return INDEX_NOT_FOUND;
48774910 }
48784911 return CharSequenceUtils.lastIndexOf(seq, searchSeq, seq.length());
49144947 * @since 3.0 Changed signature from lastIndexOf(String, String, int) to lastIndexOf(CharSequence, CharSequence, int)
49154948 */
49164949 public static int lastIndexOf(final CharSequence seq, final CharSequence searchSeq, final int startPos) {
4917 if (seq == null || searchSeq == null) {
4918 return INDEX_NOT_FOUND;
4919 }
49204950 return CharSequenceUtils.lastIndexOf(seq, searchSeq, startPos);
49214951 }
49224952
4923 // LastIndexOf
4924 //-----------------------------------------------------------------------
49254953 /**
49264954 * Returns the index within {@code seq} of the last occurrence of
49274955 * the specified character. For values of {@code searchChar} in the
51245152 if (str == null || searchStr == null) {
51255153 return INDEX_NOT_FOUND;
51265154 }
5127 if (startPos > str.length() - searchStr.length()) {
5128 startPos = str.length() - searchStr.length();
5155 final int searchStrLength = searchStr.length();
5156 final int strLength = str.length();
5157 if (startPos > strLength - searchStrLength) {
5158 startPos = strLength - searchStrLength;
51295159 }
51305160 if (startPos < 0) {
51315161 return INDEX_NOT_FOUND;
51325162 }
5133 if (searchStr.length() == 0) {
5163 if (searchStrLength == 0) {
51345164 return startPos;
51355165 }
51365166
51375167 for (int i = startPos; i >= 0; i--) {
5138 if (CharSequenceUtils.regionMatches(str, true, i, searchStr, 0, searchStr.length())) {
5168 if (CharSequenceUtils.regionMatches(str, true, i, searchStr, 0, searchStrLength)) {
51395169 return i;
51405170 }
51415171 }
51805210 return ordinalIndexOf(str, searchStr, ordinal, true);
51815211 }
51825212
5183 // Left/Right/Mid
5184 //-----------------------------------------------------------------------
51855213 /**
51865214 * <p>Gets the leftmost {@code len} characters of a String.</p>
51875215 *
53885416 if (str == null) {
53895417 return null;
53905418 }
5391 return str.toLowerCase(locale);
5419 return str.toLowerCase(LocaleUtils.toLocale(locale));
53925420 }
53935421
53945422 private static int[] matches(final CharSequence first, final CharSequence second) {
5395 CharSequence max, min;
5423 final CharSequence max;
5424 final CharSequence min;
53965425 if (first.length() > second.length()) {
53975426 max = first;
53985427 min = second;
54885517 return str.substring(pos, pos + len);
54895518 }
54905519
5491 private static StringBuilder newStringBuilder(final int noOfItems) {
5492 return new StringBuilder(noOfItems * 16);
5520 private static StringJoiner newStringJoiner(final char delimiter) {
5521 return new StringJoiner(String.valueOf(delimiter));
54935522 }
54945523
54955524 /**
56585687 return index;
56595688 }
56605689
5661 // Overlay
5662 //-----------------------------------------------------------------------
56635690 /**
56645691 * <p>Overlays part of a String with another String.</p>
56655692 *
60866113 * @since 3.5
60876114 */
60886115 public static String removeIgnoreCase(final String str, final String remove) {
6089 if (isEmpty(str) || isEmpty(remove)) {
6090 return str;
6091 }
60926116 return replaceIgnoreCase(str, remove, EMPTY, -1);
60936117 }
60946118
61296153 return RegExUtils.removePattern(source, regex);
61306154 }
61316155
6132 // Remove
6133 //-----------------------------------------------------------------------
61346156 /**
61356157 * <p>Removes a substring only if it is at the beginning of a source string,
61366158 * otherwise returns the source string.</p>
61916213 * @since 2.4
61926214 */
61936215 public static String removeStartIgnoreCase(final String str, final String remove) {
6194 if (isEmpty(str) || isEmpty(remove)) {
6195 return str;
6196 }
6197 if (startsWithIgnoreCase(str, remove)) {
6198 return str.substring(remove.length());
6216 if (str != null && startsWithIgnoreCase(str, remove)) {
6217 return str.substring(length(remove));
61996218 }
62006219 return str;
62016220 }
62276246 return EMPTY;
62286247 }
62296248 final char[] buf = new char[repeat];
6230 for (int i = repeat - 1; i >= 0; i--) {
6231 buf[i] = ch;
6232 }
6249 Arrays.fill(buf, ch);
62336250 return new String(buf);
62346251 }
62356252
6236 // Padding
6237 //-----------------------------------------------------------------------
62386253 /**
62396254 * <p>Repeat a String {@code repeat} times to form a
62406255 * new String.</p>
62556270 */
62566271 public static String repeat(final String str, final int repeat) {
62576272 // Performance tuned for 2.0 (JDK1.4)
6258
62596273 if (str == null) {
62606274 return null;
62616275 }
62916305 return buf.toString();
62926306 }
62936307 }
6294
6295 // Conversion
6296 //-----------------------------------------------------------------------
62976308
62986309 /**
62996310 * <p>Repeat a String {@code repeat} times to form a
64976508 return RegExUtils.replaceAll(text, regex, replacement);
64986509 }
64996510
6500 // Replace, character based
6501 //-----------------------------------------------------------------------
65026511 /**
65036512 * <p>Replaces all occurrences of a character in a String with another.
65046513 * This is a null-safe version of {@link String#replace(char, char)}.</p>
66956704 final Set<String> searchSet = new HashSet<>(Arrays.asList(searchList));
66966705 final Set<String> replacementSet = new HashSet<>(Arrays.asList(replacementList));
66976706 searchSet.retainAll(replacementSet);
6698 if (searchSet.size() > 0) {
6707 if (!searchSet.isEmpty()) {
66996708 throw new IllegalStateException("Aborting to protect against StackOverflowError - " +
67006709 "output of one loop is the input of another");
67016710 }
67356744 // see if we need to keep searching for this
67366745 if (tempIndex == -1) {
67376746 noMoreMatchesForReplIndex[i] = true;
6738 } else {
6739 if (textIndex == -1 || tempIndex < textIndex) {
6740 textIndex = tempIndex;
6741 replaceIndex = i;
6742 }
6747 } else if (textIndex == -1 || tempIndex < textIndex) {
6748 textIndex = tempIndex;
6749 replaceIndex = i;
67436750 }
67446751 }
67456752 // NOTE: logic mostly below END
67806787
67816788 textIndex = -1;
67826789 replaceIndex = -1;
6783 tempIndex = -1;
67846790 // find the next earliest match
67856791 // NOTE: logic mostly duplicated above START
67866792 for (int i = 0; i < searchLength; i++) {
67936799 // see if we need to keep searching for this
67946800 if (tempIndex == -1) {
67956801 noMoreMatchesForReplIndex[i] = true;
6796 } else {
6797 if (textIndex == -1 || tempIndex < textIndex) {
6798 textIndex = tempIndex;
6799 replaceIndex = i;
6800 }
6802 } else if (textIndex == -1 || tempIndex < textIndex) {
6803 textIndex = tempIndex;
6804 replaceIndex = i;
68016805 }
68026806 }
68036807 // NOTE: logic duplicated above END
69786982 return replace(text, searchString, replacement, max, true);
69796983 }
69806984
6981 // Replacing
6982 //-----------------------------------------------------------------------
69836985 /**
69846986 * <p>Replaces a String with another String inside a larger String, once.</p>
69856987 *
70827084 return RegExUtils.replacePattern(source, regex, replacement);
70837085 }
70847086
7085 // Reversing
7086 //-----------------------------------------------------------------------
70877087 /**
70887088 * <p>Reverses a String as per {@link StringBuilder#reverse()}.</p>
70897089 *
72807280 }
72817281 }
72827282
7283 // Rotating (circular shift)
7284 //-----------------------------------------------------------------------
72857283 /**
72867284 * <p>Rotate (circular shift) a String of {@code shift} characters.</p>
72877285 * <ul>
73257323 return builder.toString();
73267324 }
73277325
7328 // Splitting
7329 //-----------------------------------------------------------------------
73307326 /**
73317327 * <p>Splits the provided text into an array, using whitespace as the
73327328 * separator.
77417737 return substrings.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
77427738 }
77437739
7744 // -----------------------------------------------------------------------
77457740 /**
77467741 * <p>Splits the provided text into an array, using whitespace as the
77477742 * separator, preserving all tokens, including empty tokens created by
79067901 return ArrayUtils.EMPTY_STRING_ARRAY;
79077902 }
79087903 final List<String> list = new ArrayList<>();
7909 int i = 0, start = 0;
7904 int i = 0;
7905 int start = 0;
79107906 boolean match = false;
79117907 boolean lastMatch = false;
79127908 while (i < len) {
79577953 }
79587954 final List<String> list = new ArrayList<>();
79597955 int sizePlus1 = 1;
7960 int i = 0, start = 0;
7956 int i = 0;
7957 int start = 0;
79617958 boolean match = false;
79627959 boolean lastMatch = false;
79637960 if (separatorChars == null) {
80698066 if (str == null || prefix == null) {
80708067 return str == prefix;
80718068 }
8072 if (prefix.length() > str.length()) {
8069 // Get length once instead of twice in the unlikely case that it changes.
8070 final int preLen = prefix.length();
8071 if (preLen > str.length()) {
80738072 return false;
80748073 }
8075 return CharSequenceUtils.regionMatches(str, ignoreCase, 0, prefix, 0, prefix.length());
8074 return CharSequenceUtils.regionMatches(str, ignoreCase, 0, prefix, 0, preLen);
80768075 }
80778076
80788077 /**
81358134 return startsWith(str, prefix, true);
81368135 }
81378136
8138 // Stripping
8139 //-----------------------------------------------------------------------
81408137 /**
81418138 * <p>Strips whitespace from the start and end of a String.</p>
81428139 *
81908187 * @return the stripped String, {@code null} if null String input
81918188 */
81928189 public static String strip(String str, final String stripChars) {
8193 if (isEmpty(str)) {
8194 return str;
8195 }
81968190 str = stripStart(str, stripChars);
81978191 return stripEnd(str, stripChars);
81988192 }
82258219 return STRIP_ACCENTS_PATTERN.matcher(decomposed).replaceAll(EMPTY);
82268220 }
82278221
8228 // StripAll
8229 //-----------------------------------------------------------------------
82308222 /**
82318223 * <p>Strips whitespace from the start and end of every String in an array.
82328224 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
84308422 return null;
84318423 }
84328424 str = strip(str, null);
8433 return str.isEmpty() ? null : str;
8434 }
8435
8436 // Substring
8437 //-----------------------------------------------------------------------
8425 return str.isEmpty() ? null : str; // NOSONARLINT str cannot be null here
8426 }
8427
84388428 /**
84398429 * <p>Gets a substring from the specified String avoiding exceptions.</p>
84408430 *
86258615 return str.substring(pos + separator.length());
86268616 }
86278617
8628 // startsWith
8629 //-----------------------------------------------------------------------
8630
86318618 /**
86328619 * <p>Gets the substring after the last occurrence of a separator.
86338620 * The separator is not returned.</p>
87088695 return str.substring(pos + separator.length());
87098696 }
87108697
8711 // SubStringAfter/SubStringBefore
8712 //-----------------------------------------------------------------------
8698 /**
8699 * <p>
8700 * Gets the substring before the first occurrence of a separator. The separator is not returned.
8701 * </p>
8702 *
8703 * <p>
8704 * A {@code null} string input will return {@code null}. An empty ("") string input will return the empty string.
8705 * </p>
8706 *
8707 * <p>
8708 * If nothing is found, the string input is returned.
8709 * </p>
8710 *
8711 * <pre>
8712 * StringUtils.substringBefore(null, *) = null
8713 * StringUtils.substringBefore("", *) = ""
8714 * StringUtils.substringBefore("abc", 'a') = ""
8715 * StringUtils.substringBefore("abcba", 'b') = "a"
8716 * StringUtils.substringBefore("abc", 'c') = "ab"
8717 * StringUtils.substringBefore("abc", 'd') = "abc"
8718 * </pre>
8719 *
8720 * @param str the String to get a substring from, may be null
8721 * @param separator the String to search for, may be null
8722 * @return the substring before the first occurrence of the separator, {@code null} if null String input
8723 * @since 3.12.0
8724 */
8725 public static String substringBefore(final String str, final int separator) {
8726 if (isEmpty(str)) {
8727 return str;
8728 }
8729 final int pos = str.indexOf(separator);
8730 if (pos == INDEX_NOT_FOUND) {
8731 return str;
8732 }
8733 return str.substring(0, pos);
8734 }
8735
87138736 /**
87148737 * <p>Gets the substring before the first occurrence of a separator.
87158738 * The separator is not returned.</p>
87898812 return str.substring(0, pos);
87908813 }
87918814
8792 // Substring between
8793 //-----------------------------------------------------------------------
87948815 /**
87958816 * <p>Gets the String that is nested in between two instances of the
87968817 * same String.</p>
88158836 public static String substringBetween(final String str, final String tag) {
88168837 return substringBetween(str, tag, tag);
88178838 }
8818
8819 // endsWith
8820 //-----------------------------------------------------------------------
88218839
88228840 /**
88238841 * <p>Gets the String that is nested in between two Strings.
89768994 * StringUtils.toCodePoints("") = [] // empty array
89778995 * </pre>
89788996 *
8979 * @param str the character sequence to convert
8997 * @param cs the character sequence to convert
89808998 * @return an array of code points
89818999 * @since 3.6
89829000 */
8983 public static int[] toCodePoints(final CharSequence str) {
8984 if (str == null) {
9001 public static int[] toCodePoints(final CharSequence cs) {
9002 if (cs == null) {
89859003 return null;
89869004 }
8987 if (str.length() == 0) {
9005 if (cs.length() == 0) {
89889006 return ArrayUtils.EMPTY_INT_ARRAY;
89899007 }
89909008
8991 final String s = str.toString();
9009 final String s = cs.toString();
89929010 final int[] result = new int[s.codePointCount(0, s.length())];
89939011 int index = 0;
89949012 for (int i = 0; i < result.length; i++) {
90549072 */
90559073 @Deprecated
90569074 public static String toString(final byte[] bytes, final String charsetName) throws UnsupportedEncodingException {
9057 return charsetName != null ? new String(bytes, charsetName) : new String(bytes, Charset.defaultCharset());
9058 }
9059
9060 // Trim
9061 //-----------------------------------------------------------------------
9075 return new String(bytes, Charsets.toCharset(charsetName));
9076 }
9077
9078 private static String toStringOrEmpty(final Object obj) {
9079 return Objects.toString(obj, EMPTY);
9080 }
9081
90629082 /**
90639083 * <p>Removes control characters (char &lt;= 32) from both
90649084 * ends of this String, handling {@code null} by returning
93689388 * @since 3.6
93699389 */
93709390 public static String unwrap(final String str, final String wrapToken) {
9371 if (isEmpty(str) || isEmpty(wrapToken) || str.length() == 1) {
9391 if (isEmpty(str) || isEmpty(wrapToken) || str.length() < 2 * wrapToken.length()) {
93729392 return str;
93739393 }
93749394
93859405 return str;
93869406 }
93879407
9388 // Case conversion
9389 //-----------------------------------------------------------------------
93909408 /**
93919409 * <p>Converts a String to upper case as per {@link String#toUpperCase()}.</p>
93929410 *
94339451 if (str == null) {
94349452 return null;
94359453 }
9436 return str.toUpperCase(locale);
9454 return str.toUpperCase(LocaleUtils.toLocale(locale));
94379455 }
94389456
94399457 /**
96269644 * instance to operate.</p>
96279645 */
96289646 public StringUtils() {
9629 super();
96309647 }
96319648
96329649 }
12871287
12881288 /**
12891289 * <p>
1290 * Is {@code true} if this is Mac OS X Sierra.
1291 * </p>
1292 * <p>
1293 * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1294 * </p>
1295 *
1296 * @since 3.12.0
1297 */
1298 public static final boolean IS_OS_MAC_OSX_SIERRA = getOsMatches("Mac OS X", "10.12");
1299
1300 /**
1301 * <p>
1302 * Is {@code true} if this is Mac OS X High Sierra.
1303 * </p>
1304 * <p>
1305 * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1306 * </p>
1307 *
1308 * @since 3.12.0
1309 */
1310 public static final boolean IS_OS_MAC_OSX_HIGH_SIERRA = getOsMatches("Mac OS X", "10.13");
1311
1312 /**
1313 * <p>
1314 * Is {@code true} if this is Mac OS X Mojave.
1315 * </p>
1316 * <p>
1317 * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1318 * </p>
1319 *
1320 * @since 3.12.0
1321 */
1322 public static final boolean IS_OS_MAC_OSX_MOJAVE = getOsMatches("Mac OS X", "10.14");
1323
1324 /**
1325 * <p>
1326 * Is {@code true} if this is Mac OS X Catalina.
1327 * </p>
1328 * <p>
1329 * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1330 * </p>
1331 *
1332 * @since 3.12.0
1333 */
1334 public static final boolean IS_OS_MAC_OSX_CATALINA = getOsMatches("Mac OS X", "10.15");
1335
1336 /**
1337 * <p>
1338 * Is {@code true} if this is Mac OS X Big Sur.
1339 * </p>
1340 * <p>
1341 * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1342 * </p>
1343 *
1344 * @since 3.12.0
1345 */
1346 public static final boolean IS_OS_MAC_OSX_BIG_SUR = getOsMatches("Mac OS X", "10.16");
1347
1348 /**
1349 * <p>
12901350 * Is {@code true} if this is FreeBSD.
12911351 * </p>
12921352 * <p>
15581618
15591619 /**
15601620 * <p>
1621 * Gets an environment variable, defaulting to {@code defaultValue} if the variable cannot be read.
1622 * </p>
1623 * <p>
1624 * If a {@code SecurityException} is caught, the return value is {@code defaultValue} and a message is written to
1625 * {@code System.err}.
1626 * </p>
1627 *
1628 * @param name
1629 * the environment variable name
1630 * @param defaultValue
1631 * the default value
1632 * @return the environment variable value or {@code defaultValue} if a security problem occurs
1633 * @since 3.8
1634 */
1635 public static String getEnvironmentVariable(final String name, final String defaultValue) {
1636 try {
1637 final String value = System.getenv(name);
1638 return value == null ? defaultValue : value;
1639 } catch (final SecurityException ex) {
1640 // we are not allowed to look at this property
1641 // System.err.println("Caught a SecurityException reading the environment variable '" + name + "'.");
1642 return defaultValue;
1643 }
1644 }
1645
1646 /**
1647 * Gets the host name from an environment variable
1648 * (COMPUTERNAME on Windows, HOSTNAME elsewhere).
1649 *
1650 * <p>
1651 * If you want to know what the network stack says is the host name, you should use {@code InetAddress.getLocalHost().getHostName()}.
1652 * </p>
1653 *
1654 * @return the host name. Will be {@code null} if the environment variable is not defined.
1655 * @since 3.6
1656 */
1657 public static String getHostName() {
1658 return IS_OS_WINDOWS ? System.getenv("COMPUTERNAME") : System.getenv("HOSTNAME");
1659 }
1660
1661 /**
1662 * <p>
15611663 * Gets the Java home directory as a {@code File}.
15621664 * </p>
15631665 *
15691671 */
15701672 public static File getJavaHome() {
15711673 return new File(System.getProperty(JAVA_HOME_KEY));
1572 }
1573
1574 /**
1575 * Gets the host name from an environment variable
1576 * (COMPUTERNAME on Windows, HOSTNAME elsewhere).
1577 *
1578 * <p>
1579 * If you want to know what the network stack says is the host name, you should use {@code InetAddress.getLocalHost().getHostName()}.
1580 * </p>
1581 *
1582 * @return the host name. Will be {@code null} if the environment variable is not defined.
1583 * @since 3.6
1584 */
1585 public static String getHostName() {
1586 return IS_OS_WINDOWS ? System.getenv("COMPUTERNAME") : System.getenv("HOSTNAME");
15871674 }
15881675
15891676 /**
16601747
16611748 /**
16621749 * <p>
1663 * Gets an environment variable, defaulting to {@code defaultValue} if the variable cannot be read.
1664 * </p>
1665 * <p>
1666 * If a {@code SecurityException} is caught, the return value is {@code defaultValue} and a message is written to
1667 * {@code System.err}.
1668 * </p>
1669 *
1670 * @param name
1671 * the environment variable name
1672 * @param defaultValue
1673 * the default value
1674 * @return the environment variable value or {@code defaultValue} if a security problem occurs
1675 * @since 3.8
1676 */
1677 public static String getEnvironmentVariable(final String name, final String defaultValue) {
1678 try {
1679 final String value = System.getenv(name);
1680 return value == null ? defaultValue : value;
1681 } catch (final SecurityException ex) {
1682 // we are not allowed to look at this property
1683 // System.err.println("Caught a SecurityException reading the environment variable '" + name + "'.");
1684 return defaultValue;
1685 }
1686 }
1687
1688 /**
1689 * <p>
16901750 * Gets the user directory as a {@code File}.
16911751 * </p>
16921752 *
17801840 * </p>
17811841 *
17821842 * @param requiredVersion the required version, for example 1.31f
1783 * @return {@code true} if the actual version is equal or greater than the required version
1843 * @return {@code true} if the actual version is equal or less than the required version
17841844 * @since 3.9
17851845 */
17861846 public static boolean isJavaVersionAtMost(final JavaVersion requiredVersion) {
18791939 * </p>
18801940 */
18811941 public SystemUtils() {
1882 super();
18831942 }
18841943
18851944 }
1515 */
1616 package org.apache.commons.lang3;
1717
18 import java.time.Duration;
1819 import java.util.ArrayList;
1920 import java.util.Collection;
2021 import java.util.Collections;
2122 import java.util.List;
23
24 import org.apache.commons.lang3.time.DurationUtils;
2225
2326 /**
2427 * <p>
3538 public class ThreadUtils {
3639
3740 /**
41 * A predicate implementation which always returns true.
42 */
43 private static final class AlwaysTruePredicate implements ThreadPredicate, ThreadGroupPredicate {
44
45 private AlwaysTruePredicate() {
46 }
47
48 @Override
49 public boolean test(final Thread thread) {
50 return true;
51 }
52
53 @Override
54 public boolean test(final ThreadGroup threadGroup) {
55 return true;
56 }
57 }
58
59 /**
60 * A predicate implementation which matches a thread or threadgroup name.
61 */
62 public static class NamePredicate implements ThreadPredicate, ThreadGroupPredicate {
63
64 private final String name;
65
66 /**
67 * Predicate constructor
68 *
69 * @param name thread or threadgroup name
70 * @throws IllegalArgumentException if the name is {@code null}
71 */
72 public NamePredicate(final String name) {
73 Validate.notNull(name, "name");
74 this.name = name;
75 }
76
77 @Override
78 public boolean test(final Thread thread) {
79 return thread != null && thread.getName().equals(name);
80 }
81
82 @Override
83 public boolean test(final ThreadGroup threadGroup) {
84 return threadGroup != null && threadGroup.getName().equals(name);
85 }
86 }
87
88 /**
89 * A predicate for selecting threadgroups.
90 */
91 // When breaking BC, replace this with Predicate<ThreadGroup>
92 @FunctionalInterface
93 public interface ThreadGroupPredicate {
94
95 /**
96 * Evaluates this predicate on the given threadgroup.
97 * @param threadGroup the threadgroup
98 * @return {@code true} if the threadGroup matches the predicate, otherwise {@code false}
99 */
100 boolean test(ThreadGroup threadGroup);
101 }
102
103 /**
104 * A predicate implementation which matches a thread id.
105 */
106 public static class ThreadIdPredicate implements ThreadPredicate {
107
108 private final long threadId;
109
110 /**
111 * Predicate constructor
112 *
113 * @param threadId the threadId to match
114 * @throws IllegalArgumentException if the threadId is zero or negative
115 */
116 public ThreadIdPredicate(final long threadId) {
117 if (threadId <= 0) {
118 throw new IllegalArgumentException("The thread id must be greater than zero");
119 }
120 this.threadId = threadId;
121 }
122
123 @Override
124 public boolean test(final Thread thread) {
125 return thread != null && thread.getId() == threadId;
126 }
127 }
128
129 /**
130 * A predicate for selecting threads.
131 */
132 // When breaking BC, replace this with Predicate<Thread>
133 @FunctionalInterface
134 public interface ThreadPredicate {
135
136 /**
137 * Evaluates this predicate on the given thread.
138 * @param thread the thread
139 * @return {@code true} if the thread matches the predicate, otherwise {@code false}
140 */
141 boolean test(Thread thread);
142 }
143
144 /**
145 * Predicate which always returns true.
146 */
147 public static final AlwaysTruePredicate ALWAYS_TRUE_PREDICATE = new AlwaysTruePredicate();
148
149 /**
150 * Finds the active thread with the specified id.
151 *
152 * @param threadId The thread id
153 * @return The thread with the specified id or {@code null} if no such thread exists
154 * @throws IllegalArgumentException if the specified id is zero or negative
155 * @throws SecurityException
156 * if the current thread cannot access the system thread group
157 *
158 * @throws SecurityException if the current thread cannot modify
159 * thread groups from this thread's thread group up to the system thread group
160 */
161 public static Thread findThreadById(final long threadId) {
162 final Collection<Thread> result = findThreads(new ThreadIdPredicate(threadId));
163 return result.isEmpty() ? null : result.iterator().next();
164 }
165
166 /**
167 * Finds the active thread with the specified id if it belongs to a thread group with the specified group name.
168 *
169 * @param threadId The thread id
170 * @param threadGroupName The thread group name
171 * @return The threads which belongs to a thread group with the specified group name and the thread's id match the specified id.
172 * {@code null} is returned if no such thread exists
173 * @throws IllegalArgumentException if the specified id is zero or negative or the group name is null
174 * @throws SecurityException
175 * if the current thread cannot access the system thread group
176 *
177 * @throws SecurityException if the current thread cannot modify
178 * thread groups from this thread's thread group up to the system thread group
179 */
180 public static Thread findThreadById(final long threadId, final String threadGroupName) {
181 Validate.notNull(threadGroupName, "threadGroupName");
182 final Thread thread = findThreadById(threadId);
183 if (thread != null && thread.getThreadGroup() != null && thread.getThreadGroup().getName().equals(threadGroupName)) {
184 return thread;
185 }
186 return null;
187 }
188
189 /**
38190 * Finds the active thread with the specified id if it belongs to the specified thread group.
39191 *
40192 * @param threadId The thread id
49201 * thread groups from this thread's thread group up to the system thread group
50202 */
51203 public static Thread findThreadById(final long threadId, final ThreadGroup threadGroup) {
52 Validate.notNull(threadGroup, "The thread group must not be null");
204 Validate.notNull(threadGroup, "threadGroup");
53205 final Thread thread = findThreadById(threadId);
54206 if (thread != null && threadGroup.equals(thread.getThreadGroup())) {
55207 return thread;
58210 }
59211
60212 /**
61 * Finds the active thread with the specified id if it belongs to a thread group with the specified group name.
62 *
63 * @param threadId The thread id
213 * Select all active threadgroups which match the given predicate and which is a subgroup of the given thread group (or one of its subgroups).
214 *
215 * @param group the thread group
216 * @param recurse if {@code true} then evaluate the predicate recursively on all threadgroups in all subgroups of the given group
217 * @param predicate the predicate
218 * @return An unmodifiable {@code Collection} of active threadgroups which match the given predicate and which is a subgroup of the given thread group
219 * @throws IllegalArgumentException if the given group or predicate is null
220 * @throws SecurityException if the current thread cannot modify
221 * thread groups from this thread's thread group up to the system thread group
222 */
223 public static Collection<ThreadGroup> findThreadGroups(final ThreadGroup group, final boolean recurse, final ThreadGroupPredicate predicate) {
224 Validate.notNull(group, "group");
225 Validate.notNull(predicate, "predicate");
226
227 int count = group.activeGroupCount();
228 ThreadGroup[] threadGroups;
229 do {
230 threadGroups = new ThreadGroup[count + (count / 2) + 1]; //slightly grow the array size
231 count = group.enumerate(threadGroups, recurse);
232 //return value of enumerate() must be strictly less than the array size according to javadoc
233 } while (count >= threadGroups.length);
234
235 final List<ThreadGroup> result = new ArrayList<>(count);
236 for (int i = 0; i < count; ++i) {
237 if (predicate.test(threadGroups[i])) {
238 result.add(threadGroups[i]);
239 }
240 }
241 return Collections.unmodifiableCollection(result);
242 }
243
244 /**
245 * Select all active threadgroups which match the given predicate.
246 *
247 * @param predicate the predicate
248 * @return An unmodifiable {@code Collection} of active threadgroups matching the given predicate
249 * @throws IllegalArgumentException if the predicate is null
250 * @throws SecurityException
251 * if the current thread cannot access the system thread group
252 * @throws SecurityException if the current thread cannot modify
253 * thread groups from this thread's thread group up to the system thread group
254 */
255 public static Collection<ThreadGroup> findThreadGroups(final ThreadGroupPredicate predicate) {
256 return findThreadGroups(getSystemThreadGroup(), true, predicate);
257 }
258
259 /**
260 * Finds active thread groups with the specified group name.
261 *
64262 * @param threadGroupName The thread group name
65 * @return The threads which belongs to a thread group with the specified group name and the thread's id match the specified id.
66 * {@code null} is returned if no such thread exists
67 * @throws IllegalArgumentException if the specified id is zero or negative or the group name is null
68 * @throws SecurityException
69 * if the current thread cannot access the system thread group
70 *
71 * @throws SecurityException if the current thread cannot modify
72 * thread groups from this thread's thread group up to the system thread group
73 */
74 public static Thread findThreadById(final long threadId, final String threadGroupName) {
75 Validate.notNull(threadGroupName, "The thread group name must not be null");
76 final Thread thread = findThreadById(threadId);
77 if (thread != null && thread.getThreadGroup() != null && thread.getThreadGroup().getName().equals(threadGroupName)) {
78 return thread;
79 }
80 return null;
263 * @return the thread groups with the specified group name or an empty collection if no such thread group exists. The collection returned is always unmodifiable.
264 * @throws IllegalArgumentException if group name is null
265 * @throws SecurityException
266 * if the current thread cannot access the system thread group
267 *
268 * @throws SecurityException if the current thread cannot modify
269 * thread groups from this thread's thread group up to the system thread group
270 */
271 public static Collection<ThreadGroup> findThreadGroupsByName(final String threadGroupName) {
272 return findThreadGroups(new NamePredicate(threadGroupName));
273 }
274
275 /**
276 * Select all active threads which match the given predicate and which belongs to the given thread group (or one of its subgroups).
277 *
278 * @param group the thread group
279 * @param recurse if {@code true} then evaluate the predicate recursively on all threads in all subgroups of the given group
280 * @param predicate the predicate
281 * @return An unmodifiable {@code Collection} of active threads which match the given predicate and which belongs to the given thread group
282 * @throws IllegalArgumentException if the given group or predicate is null
283 * @throws SecurityException if the current thread cannot modify
284 * thread groups from this thread's thread group up to the system thread group
285 */
286 public static Collection<Thread> findThreads(final ThreadGroup group, final boolean recurse, final ThreadPredicate predicate) {
287 Validate.notNull(group, "The group must not be null");
288 Validate.notNull(predicate, "The predicate must not be null");
289
290 int count = group.activeCount();
291 Thread[] threads;
292 do {
293 threads = new Thread[count + (count / 2) + 1]; //slightly grow the array size
294 count = group.enumerate(threads, recurse);
295 //return value of enumerate() must be strictly less than the array size according to javadoc
296 } while (count >= threads.length);
297
298 final List<Thread> result = new ArrayList<>(count);
299 for (int i = 0; i < count; ++i) {
300 if (predicate.test(threads[i])) {
301 result.add(threads[i]);
302 }
303 }
304 return Collections.unmodifiableCollection(result);
305 }
306
307 /**
308 * Select all active threads which match the given predicate.
309 *
310 * @param predicate the predicate
311 * @return An unmodifiable {@code Collection} of active threads matching the given predicate
312 *
313 * @throws IllegalArgumentException if the predicate is null
314 * @throws SecurityException
315 * if the current thread cannot access the system thread group
316 * @throws SecurityException if the current thread cannot modify
317 * thread groups from this thread's thread group up to the system thread group
318 */
319 public static Collection<Thread> findThreads(final ThreadPredicate predicate) {
320 return findThreads(getSystemThreadGroup(), true, predicate);
321 }
322
323 /**
324 * Finds active threads with the specified name.
325 *
326 * @param threadName The thread name
327 * @return The threads with the specified name or an empty collection if no such thread exists. The collection returned is always unmodifiable.
328 * @throws IllegalArgumentException if the specified name is null
329 * @throws SecurityException
330 * if the current thread cannot access the system thread group
331 *
332 * @throws SecurityException if the current thread cannot modify
333 * thread groups from this thread's thread group up to the system thread group
334 */
335 public static Collection<Thread> findThreadsByName(final String threadName) {
336 return findThreads(new NamePredicate(threadName));
337 }
338
339 /**
340 * Finds active threads with the specified name if they belong to a thread group with the specified group name.
341 *
342 * @param threadName The thread name
343 * @param threadGroupName The thread group name
344 * @return The threads which belongs to a thread group with the specified group name and the thread's name match the specified name,
345 * An empty collection is returned if no such thread exists. The collection returned is always unmodifiable.
346 * @throws IllegalArgumentException if the specified thread name or group name is null
347 * @throws SecurityException
348 * if the current thread cannot access the system thread group
349 *
350 * @throws SecurityException if the current thread cannot modify
351 * thread groups from this thread's thread group up to the system thread group
352 */
353 public static Collection<Thread> findThreadsByName(final String threadName, final String threadGroupName) {
354 Validate.notNull(threadName, "threadName");
355 Validate.notNull(threadGroupName, "threadGroupName");
356
357 final Collection<ThreadGroup> threadGroups = findThreadGroups(new NamePredicate(threadGroupName));
358
359 if (threadGroups.isEmpty()) {
360 return Collections.emptyList();
361 }
362
363 final Collection<Thread> result = new ArrayList<>();
364 final NamePredicate threadNamePredicate = new NamePredicate(threadName);
365 for (final ThreadGroup group : threadGroups) {
366 result.addAll(findThreads(group, false, threadNamePredicate));
367 }
368 return Collections.unmodifiableCollection(result);
81369 }
82370
83371 /**
99387 }
100388
101389 /**
102 * Finds active threads with the specified name if they belong to a thread group with the specified group name.
103 *
104 * @param threadName The thread name
105 * @param threadGroupName The thread group name
106 * @return The threads which belongs to a thread group with the specified group name and the thread's name match the specified name,
107 * An empty collection is returned if no such thread exists. The collection returned is always unmodifiable.
108 * @throws IllegalArgumentException if the specified thread name or group name is null
109 * @throws SecurityException
110 * if the current thread cannot access the system thread group
111 *
112 * @throws SecurityException if the current thread cannot modify
113 * thread groups from this thread's thread group up to the system thread group
114 */
115 public static Collection<Thread> findThreadsByName(final String threadName, final String threadGroupName) {
116 Validate.notNull(threadName, "The thread name must not be null");
117 Validate.notNull(threadGroupName, "The thread group name must not be null");
118
119 final Collection<ThreadGroup> threadGroups = findThreadGroups(new NamePredicate(threadGroupName));
120
121 if (threadGroups.isEmpty()) {
122 return Collections.emptyList();
123 }
124
125 final Collection<Thread> result = new ArrayList<>();
126 final NamePredicate threadNamePredicate = new NamePredicate(threadName);
127 for (final ThreadGroup group : threadGroups) {
128 result.addAll(findThreads(group, false, threadNamePredicate));
129 }
130 return Collections.unmodifiableCollection(result);
131 }
132
133 /**
134 * Finds active thread groups with the specified group name.
135 *
136 * @param threadGroupName The thread group name
137 * @return the thread groups with the specified group name or an empty collection if no such thread group exists. The collection returned is always unmodifiable.
138 * @throws IllegalArgumentException if group name is null
139 * @throws SecurityException
140 * if the current thread cannot access the system thread group
141 *
142 * @throws SecurityException if the current thread cannot modify
143 * thread groups from this thread's thread group up to the system thread group
144 */
145 public static Collection<ThreadGroup> findThreadGroupsByName(final String threadGroupName) {
146 return findThreadGroups(new NamePredicate(threadGroupName));
147 }
148
149 /**
150390 * Gets all active thread groups excluding the system thread group (A thread group is active if it has been not destroyed).
151391 *
152392 * @return all thread groups excluding the system thread group. The collection returned is always unmodifiable.
158398 */
159399 public static Collection<ThreadGroup> getAllThreadGroups() {
160400 return findThreadGroups(ALWAYS_TRUE_PREDICATE);
401 }
402
403 /**
404 * Gets all active threads (A thread is active if it has been started and has not yet died).
405 *
406 * @return all active threads. The collection returned is always unmodifiable.
407 * @throws SecurityException
408 * if the current thread cannot access the system thread group
409 *
410 * @throws SecurityException if the current thread cannot modify
411 * thread groups from this thread's thread group up to the system thread group
412 */
413 public static Collection<Thread> getAllThreads() {
414 return findThreads(ALWAYS_TRUE_PREDICATE);
161415 }
162416
163417 /**
176430 }
177431
178432 /**
179 * Gets all active threads (A thread is active if it has been started and has not yet died).
180 *
181 * @return all active threads. The collection returned is always unmodifiable.
182 * @throws SecurityException
183 * if the current thread cannot access the system thread group
184 *
185 * @throws SecurityException if the current thread cannot modify
186 * thread groups from this thread's thread group up to the system thread group
187 */
188 public static Collection<Thread> getAllThreads() {
189 return findThreads(ALWAYS_TRUE_PREDICATE);
190 }
191
192 /**
193 * Finds active threads with the specified name.
194 *
195 * @param threadName The thread name
196 * @return The threads with the specified name or an empty collection if no such thread exists. The collection returned is always unmodifiable.
197 * @throws IllegalArgumentException if the specified name is null
198 * @throws SecurityException
199 * if the current thread cannot access the system thread group
200 *
201 * @throws SecurityException if the current thread cannot modify
202 * thread groups from this thread's thread group up to the system thread group
203 */
204 public static Collection<Thread> findThreadsByName(final String threadName) {
205 return findThreads(new NamePredicate(threadName));
206 }
207
208 /**
209 * Finds the active thread with the specified id.
210 *
211 * @param threadId The thread id
212 * @return The thread with the specified id or {@code null} if no such thread exists
213 * @throws IllegalArgumentException if the specified id is zero or negative
214 * @throws SecurityException
215 * if the current thread cannot access the system thread group
216 *
217 * @throws SecurityException if the current thread cannot modify
218 * thread groups from this thread's thread group up to the system thread group
219 */
220 public static Thread findThreadById(final long threadId) {
221 final Collection<Thread> result = findThreads(new ThreadIdPredicate(threadId));
222 return result.isEmpty() ? null : result.iterator().next();
433 * Waits for the given thread to die for the given duration. Implemented using {@link Thread#join(long, int)}.
434 *
435 * @param thread The thread to join.
436 * @param duration How long to wait.
437 * @throws InterruptedException if any thread has interrupted the current thread.
438 * @see Thread#join(long, int)
439 * @since 3.12.0
440 */
441 public static void join(final Thread thread, final Duration duration) throws InterruptedException {
442 DurationUtils.accept(thread::join, duration);
443 }
444
445 /**
446 * Sleeps the current thread for the given duration. Implemented using {@link Thread#sleep(long, int)}.
447 *
448 * @param duration How long to sleep.
449 * @throws InterruptedException if any thread has interrupted the current thread.
450 * @see Thread#sleep(long, int)
451 * @since 3.12.0
452 */
453 public static void sleep(final Duration duration) throws InterruptedException {
454 DurationUtils.accept(Thread::sleep, duration);
223455 }
224456
225457 /**
232464 * </p>
233465 */
234466 public ThreadUtils() {
235 super();
236 }
237
238 /**
239 * A predicate for selecting threads.
240 */
241 // When breaking BC, replace this with Predicate<Thread>
242 @FunctionalInterface
243 public interface ThreadPredicate {
244
245 /**
246 * Evaluates this predicate on the given thread.
247 * @param thread the thread
248 * @return {@code true} if the thread matches the predicate, otherwise {@code false}
249 */
250 boolean test(Thread thread);
251 }
252
253 /**
254 * A predicate for selecting threadgroups.
255 */
256 // When breaking BC, replace this with Predicate<ThreadGroup>
257 @FunctionalInterface
258 public interface ThreadGroupPredicate {
259
260 /**
261 * Evaluates this predicate on the given threadgroup.
262 * @param threadGroup the threadgroup
263 * @return {@code true} if the threadGroup matches the predicate, otherwise {@code false}
264 */
265 boolean test(ThreadGroup threadGroup);
266 }
267
268 /**
269 * Predicate which always returns true.
270 */
271 public static final AlwaysTruePredicate ALWAYS_TRUE_PREDICATE = new AlwaysTruePredicate();
272
273 /**
274 * A predicate implementation which always returns true.
275 */
276 private static final class AlwaysTruePredicate implements ThreadPredicate, ThreadGroupPredicate {
277
278 private AlwaysTruePredicate() {
279 }
280
281 @Override
282 public boolean test(final ThreadGroup threadGroup) {
283 return true;
284 }
285
286 @Override
287 public boolean test(final Thread thread) {
288 return true;
289 }
290 }
291
292 /**
293 * A predicate implementation which matches a thread or threadgroup name.
294 */
295 public static class NamePredicate implements ThreadPredicate, ThreadGroupPredicate {
296
297 private final String name;
298
299 /**
300 * Predicate constructor
301 *
302 * @param name thread or threadgroup name
303 * @throws IllegalArgumentException if the name is {@code null}
304 */
305 public NamePredicate(final String name) {
306 super();
307 Validate.notNull(name, "The name must not be null");
308 this.name = name;
309 }
310
311 @Override
312 public boolean test(final ThreadGroup threadGroup) {
313 return threadGroup != null && threadGroup.getName().equals(name);
314 }
315
316 @Override
317 public boolean test(final Thread thread) {
318 return thread != null && thread.getName().equals(name);
319 }
320 }
321
322 /**
323 * A predicate implementation which matches a thread id.
324 */
325 public static class ThreadIdPredicate implements ThreadPredicate {
326
327 private final long threadId;
328
329 /**
330 * Predicate constructor
331 *
332 * @param threadId the threadId to match
333 * @throws IllegalArgumentException if the threadId is zero or negative
334 */
335 public ThreadIdPredicate(final long threadId) {
336 super();
337 if (threadId <= 0) {
338 throw new IllegalArgumentException("The thread id must be greater than zero");
339 }
340 this.threadId = threadId;
341 }
342
343 @Override
344 public boolean test(final Thread thread) {
345 return thread != null && thread.getId() == threadId;
346 }
347 }
348
349 /**
350 * Select all active threads which match the given predicate.
351 *
352 * @param predicate the predicate
353 * @return An unmodifiable {@code Collection} of active threads matching the given predicate
354 *
355 * @throws IllegalArgumentException if the predicate is null
356 * @throws SecurityException
357 * if the current thread cannot access the system thread group
358 * @throws SecurityException if the current thread cannot modify
359 * thread groups from this thread's thread group up to the system thread group
360 */
361 public static Collection<Thread> findThreads(final ThreadPredicate predicate) {
362 return findThreads(getSystemThreadGroup(), true, predicate);
363 }
364
365 /**
366 * Select all active threadgroups which match the given predicate.
367 *
368 * @param predicate the predicate
369 * @return An unmodifiable {@code Collection} of active threadgroups matching the given predicate
370 * @throws IllegalArgumentException if the predicate is null
371 * @throws SecurityException
372 * if the current thread cannot access the system thread group
373 * @throws SecurityException if the current thread cannot modify
374 * thread groups from this thread's thread group up to the system thread group
375 */
376 public static Collection<ThreadGroup> findThreadGroups(final ThreadGroupPredicate predicate) {
377 return findThreadGroups(getSystemThreadGroup(), true, predicate);
378 }
379
380 /**
381 * Select all active threads which match the given predicate and which belongs to the given thread group (or one of its subgroups).
382 *
383 * @param group the thread group
384 * @param recurse if {@code true} then evaluate the predicate recursively on all threads in all subgroups of the given group
385 * @param predicate the predicate
386 * @return An unmodifiable {@code Collection} of active threads which match the given predicate and which belongs to the given thread group
387 * @throws IllegalArgumentException if the given group or predicate is null
388 * @throws SecurityException if the current thread cannot modify
389 * thread groups from this thread's thread group up to the system thread group
390 */
391 public static Collection<Thread> findThreads(final ThreadGroup group, final boolean recurse, final ThreadPredicate predicate) {
392 Validate.notNull(group, "The group must not be null");
393 Validate.notNull(predicate, "The predicate must not be null");
394
395 int count = group.activeCount();
396 Thread[] threads;
397 do {
398 threads = new Thread[count + (count / 2) + 1]; //slightly grow the array size
399 count = group.enumerate(threads, recurse);
400 //return value of enumerate() must be strictly less than the array size according to javadoc
401 } while (count >= threads.length);
402
403 final List<Thread> result = new ArrayList<>(count);
404 for (int i = 0; i < count; ++i) {
405 if (predicate.test(threads[i])) {
406 result.add(threads[i]);
407 }
408 }
409 return Collections.unmodifiableCollection(result);
410 }
411
412 /**
413 * Select all active threadgroups which match the given predicate and which is a subgroup of the given thread group (or one of its subgroups).
414 *
415 * @param group the thread group
416 * @param recurse if {@code true} then evaluate the predicate recursively on all threadgroups in all subgroups of the given group
417 * @param predicate the predicate
418 * @return An unmodifiable {@code Collection} of active threadgroups which match the given predicate and which is a subgroup of the given thread group
419 * @throws IllegalArgumentException if the given group or predicate is null
420 * @throws SecurityException if the current thread cannot modify
421 * thread groups from this thread's thread group up to the system thread group
422 */
423 public static Collection<ThreadGroup> findThreadGroups(final ThreadGroup group, final boolean recurse, final ThreadGroupPredicate predicate) {
424 Validate.notNull(group, "The group must not be null");
425 Validate.notNull(predicate, "The predicate must not be null");
426
427 int count = group.activeGroupCount();
428 ThreadGroup[] threadGroups;
429 do {
430 threadGroups = new ThreadGroup[count + (count / 2) + 1]; //slightly grow the array size
431 count = group.enumerate(threadGroups, recurse);
432 //return value of enumerate() must be strictly less than the array size according to javadoc
433 } while (count >= threadGroups.length);
434
435 final List<ThreadGroup> result = new ArrayList<>(count);
436 for (int i = 0; i < count; ++i) {
437 if (predicate.test(threadGroups[i])) {
438 result.add(threadGroups[i]);
439 }
440 }
441 return Collections.unmodifiableCollection(result);
442467 }
443468 }
7979 * Constructor. This class should not normally be instantiated.
8080 */
8181 public Validate() {
82 super();
8382 }
8483
8584 // isTrue
148148 * @return {@code true}, if {@link Processor} is {@link Arch#BIT_32}, else {@code false}.
149149 */
150150 public boolean is32Bit() {
151 return Arch.BIT_32.equals(arch);
151 return Arch.BIT_32 == arch;
152152 }
153153
154154 /**
157157 * @return {@code true}, if {@link Processor} is {@link Arch#BIT_64}, else {@code false}.
158158 */
159159 public boolean is64Bit() {
160 return Arch.BIT_64.equals(arch);
160 return Arch.BIT_64 == arch;
161161 }
162162
163163 /**
166166 * @return {@code true}, if {@link Processor} is {@link Type#X86}, else {@code false}.
167167 */
168168 public boolean isX86() {
169 return Type.X86.equals(type);
169 return Type.X86 == type;
170170 }
171171
172172 /**
175175 * @return {@code true}. if {@link Processor} is {@link Type#IA_64}, else {@code false}.
176176 */
177177 public boolean isIA64() {
178 return Type.IA_64.equals(type);
178 return Type.IA_64 == type;
179179 }
180180
181181 /**
184184 * @return {@code true}. if {@link Processor} is {@link Type#PPC}, else {@code false}.
185185 */
186186 public boolean isPPC() {
187 return Type.PPC.equals(type);
187 return Type.PPC == type;
188188 }
189189
190190 }
107107 * {@link #toComparison} to get the result.</p>
108108 */
109109 public CompareToBuilder() {
110 super();
111110 comparison = 0;
112111 }
113112
420419 if (lhs.getClass().isArray()) {
421420 // factor out array case in order to keep method small enough to be inlined
422421 appendArray(lhs, rhs, comparator);
422 } else // the simple case, not an array, just test the element
423 if (comparator == null) {
424 @SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc
425 final Comparable<Object> comparable = (Comparable<Object>) lhs;
426 comparison = comparable.compareTo(rhs);
423427 } else {
424 // the simple case, not an array, just test the element
425 if (comparator == null) {
426 @SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc
427 final Comparable<Object> comparable = (Comparable<Object>) lhs;
428 comparison = comparable.compareTo(rhs);
429 } else {
430 @SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc
431 final Comparator<Object> comparator2 = (Comparator<Object>) comparator;
432 comparison = comparator2.compare(lhs, rhs);
433 }
428 @SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc
429 final Comparator<Object> comparator2 = (Comparator<Object>) comparator;
430 comparison = comparator2.compare(lhs, rhs);
434431 }
435432 return this;
436433 }
103103 public DiffBuilder(final T lhs, final T rhs,
104104 final ToStringStyle style, final boolean testTriviallyEqual) {
105105
106 Validate.notNull(lhs, "lhs cannot be null");
107 Validate.notNull(rhs, "rhs cannot be null");
106 Validate.notNull(lhs, "lhs");
107 Validate.notNull(rhs, "rhs");
108108
109109 this.diffs = new ArrayList<>();
110110 this.left = lhs;
810810 return this;
811811 }
812812
813 Object objectToTest;
813 final Object objectToTest;
814814 if (lhs != null) {
815815 objectToTest = lhs;
816816 } else {
948948 public DiffBuilder<T> append(final String fieldName,
949949 final DiffResult<T> diffResult) {
950950 validateFieldNameNotNull(fieldName);
951 Validate.notNull(diffResult, "Diff result cannot be null");
951 Validate.notNull(diffResult, "diffResult");
952952 if (objectsTriviallyEqual) {
953953 return this;
954954 }
976976 }
977977
978978 private void validateFieldNameNotNull(final String fieldName) {
979 Validate.notNull(fieldName, "Field name cannot be null");
979 Validate.notNull(fieldName, "fieldName");
980980 }
981981
982982 }
4747
4848 private static final String DIFFERS_STRING = "differs from";
4949
50 private final List<Diff<?>> diffs;
50 private final List<Diff<?>> diffList;
5151 private final T lhs;
5252 private final T rhs;
5353 private final ToStringStyle style;
6262 * the left hand object
6363 * @param rhs
6464 * the right hand object
65 * @param diffs
65 * @param diffList
6666 * the list of differences, may be empty
6767 * @param style
6868 * the style to use for the {@link #toString()} method. May be
7070 * {@link ToStringStyle#DEFAULT_STYLE} is used
7171 * @throws NullPointerException if {@code lhs}, {@code rhs} or {@code diffs} is {@code null}
7272 */
73 DiffResult(final T lhs, final T rhs, final List<Diff<?>> diffs,
73 DiffResult(final T lhs, final T rhs, final List<Diff<?>> diffList,
7474 final ToStringStyle style) {
75 Validate.notNull(lhs, "Left hand object cannot be null");
76 Validate.notNull(rhs, "Right hand object cannot be null");
77 Validate.notNull(diffs, "List of differences cannot be null");
78
79 this.diffs = diffs;
75 Validate.notNull(lhs, "lhs");
76 Validate.notNull(rhs, "rhs");
77 Validate.notNull(diffList, "diffList");
78
79 this.diffList = diffList;
8080 this.lhs = lhs;
8181 this.rhs = rhs;
8282
116116 * @return an unmodifiable list of {@code Diff}s
117117 */
118118 public List<Diff<?>> getDiffs() {
119 return Collections.unmodifiableList(diffs);
119 return Collections.unmodifiableList(diffList);
120120 }
121121
122122 /**
127127 * @return the number of differences
128128 */
129129 public int getNumberOfDiffs() {
130 return diffs.size();
130 return diffList.size();
131131 }
132132
133133 /**
189189 * @return a {@code String} description of the differences.
190190 */
191191 public String toString(final ToStringStyle style) {
192 if (diffs.isEmpty()) {
192 if (diffList.isEmpty()) {
193193 return OBJECTS_SAME_STRING;
194194 }
195195
196196 final ToStringBuilder lhsBuilder = new ToStringBuilder(lhs, style);
197197 final ToStringBuilder rhsBuilder = new ToStringBuilder(rhs, style);
198198
199 for (final Diff<?> diff : diffs) {
199 for (final Diff<?> diff : diffList) {
200200 lhsBuilder.append(diff.getFieldName(), diff.getLeft());
201201 rhsBuilder.append(diff.getFieldName(), diff.getRight());
202202 }
214214 */
215215 @Override
216216 public Iterator<Diff<?>> iterator() {
217 return diffs.iterator();
217 return diffList.iterator();
218218 }
219219 }
212212 */
213213 private boolean isEquals = true;
214214
215 private boolean testTransients = false;
216 private boolean testRecursive = false;
215 private boolean testTransients;
216 private boolean testRecursive;
217217 private List<Class<?>> bypassReflectionClasses;
218 private Class<?> reflectUpToClass = null;
219 private String[] excludeFields = null;
218 private Class<?> reflectUpToClass;
219 private String[] excludeFields;
220220
221221 /**
222222 * <p>Constructor for EqualsBuilder.</p>
531531 try {
532532 if (testClass.isArray()) {
533533 append(lhs, rhs);
534 } else //If either class is being excluded, call normal object equals method on lhsClass.
535 if (bypassReflectionClasses != null
536 && (bypassReflectionClasses.contains(lhsClass) || bypassReflectionClasses.contains(rhsClass))) {
537 isEquals = lhs.equals(rhs);
534538 } else {
535 //If either class is being excluded, call normal object equals method on lhsClass.
536 if (bypassReflectionClasses != null
537 && (bypassReflectionClasses.contains(lhsClass) || bypassReflectionClasses.contains(rhsClass))) {
538 isEquals = lhs.equals(rhs);
539 } else {
539 reflectionAppend(lhs, rhs, testClass);
540 while (testClass.getSuperclass() != null && testClass != reflectUpToClass) {
541 testClass = testClass.getSuperclass();
540542 reflectionAppend(lhs, rhs, testClass);
541 while (testClass.getSuperclass() != null && testClass != reflectUpToClass) {
542 testClass = testClass.getSuperclass();
543 reflectionAppend(lhs, rhs, testClass);
544 }
545543 }
546544 }
547545 } catch (final IllegalArgumentException e) {
551549 // If a subclass has ivars that we are trying to test them, we get an
552550 // exception and we know that the objects are not equal.
553551 isEquals = false;
554 return this;
555552 }
556553 return this;
557554 }
644641 // factor out array case in order to keep method small enough
645642 // to be inlined
646643 appendArray(lhs, rhs);
644 } else // The simple case, not an array, just test the element
645 if (testRecursive && !ClassUtils.isPrimitiveOrWrapper(lhsClass)) {
646 reflectionAppend(lhs, rhs);
647647 } else {
648 // The simple case, not an array, just test the element
649 if (testRecursive && !ClassUtils.isPrimitiveOrWrapper(lhsClass)) {
650 reflectionAppend(lhs, rhs);
651 } else {
652 isEquals = lhs.equals(rhs);
653 }
648 isEquals = lhs.equals(rhs);
654649 }
655650 return this;
656651 }
1919 import java.lang.reflect.AccessibleObject;
2020 import java.lang.reflect.Field;
2121 import java.lang.reflect.Modifier;
22 import java.util.Arrays;
2322 import java.util.Collection;
2423 import java.util.Comparator;
2524 import java.util.HashSet;
2625 import java.util.Set;
2726
27 import org.apache.commons.lang3.ArraySorter;
2828 import org.apache.commons.lang3.ArrayUtils;
2929 import org.apache.commons.lang3.Validate;
3030
190190 try {
191191 register(object);
192192 // The elements in the returned array are not sorted and are not in any particular order.
193 final Field[] fields = clazz.getDeclaredFields();
194 Arrays.sort(fields, Comparator.comparing(Field::getName));
193 final Field[] fields = ArraySorter.sort(clazz.getDeclaredFields(), Comparator.comparing(Field::getName));
195194 AccessibleObject.setAccessible(fields, true);
196195 for (final Field field : fields) {
197196 if (!ArrayUtils.contains(excludeFields, field.getName())
357356 */
358357 public static <T> int reflectionHashCode(final int initialNonZeroOddNumber, final int multiplierNonZeroOddNumber, final T object,
359358 final boolean testTransients, final Class<? super T> reflectUpToClass, final String... excludeFields) {
360 Validate.notNull(object, "The object to build a hash code for must not be null");
359 Validate.notNull(object, "object");
361360 final HashCodeBuilder builder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber);
362361 Class<?> clazz = object.getClass();
363362 reflectionAppend(object, clazz, builder, testTransients, excludeFields);
536535 /**
537536 * Running total of the hashCode.
538537 */
539 private int iTotal = 0;
538 private int iTotal;
540539
541540 /**
542541 * <p>
842841 if (object == null) {
843842 iTotal = iTotal * iConstant;
844843
845 } else {
846 if (object.getClass().isArray()) {
847 // factor out array case in order to keep method small enough
848 // to be inlined
849 appendArray(object);
850 } else {
851 iTotal = iTotal * iConstant + object.hashCode();
852 }
844 } else if (object.getClass().isArray()) {
845 // factor out array case in order to keep method small enough
846 // to be inlined
847 appendArray(object);
848 } else {
849 iTotal = iTotal * iConstant + object.hashCode();
853850 }
854851 return this;
855852 }
7878 * Constructor.
7979 */
8080 public MultilineRecursiveToStringStyle() {
81 super();
8281 resetIndent();
8382 }
8483
6262 * <p>Constructor.</p>
6363 */
6464 public RecursiveToStringStyle() {
65 super();
6665 }
6766
6867 @Override
2525 import java.util.Comparator;
2626 import java.util.List;
2727
28 import org.apache.commons.lang3.ArraySorter;
2829 import org.apache.commons.lang3.ArrayUtils;
2930 import org.apache.commons.lang3.ClassUtils;
3031 import org.apache.commons.lang3.Validate;
433434 }
434435
435436 private static Object checkNotNull(final Object obj) {
436 return Validate.notNull(obj, "The Object passed in should not be null.");
437 return Validate.notNull(obj, "obj");
437438 }
438439
439440 /**
440441 * Whether or not to append static fields.
441442 */
442 private boolean appendStatics = false;
443 private boolean appendStatics;
443444
444445 /**
445446 * Whether or not to append transient fields.
446447 */
447 private boolean appendTransients = false;
448 private boolean appendTransients;
448449
449450 /**
450451 * Whether or not to append fields that are null.
461462 /**
462463 * The last super class to stop appending fields for.
463464 */
464 private Class<?> upToClass = null;
465 private Class<?> upToClass;
465466
466467 /**
467468 * <p>
639640 return;
640641 }
641642 // The elements in the returned array are not sorted and are not in any particular order.
642 final Field[] fields = clazz.getDeclaredFields();
643 Arrays.sort(fields, Comparator.comparing(Field::getName));
643 final Field[] fields = ArraySorter.sort(clazz.getDeclaredFields(), Comparator.comparing(Field::getName));
644644 AccessibleObject.setAccessible(fields, true);
645645 for (final Field field : fields) {
646646 final String fieldName = field.getName();
800800 this.excludeFieldNames = null;
801801 } else {
802802 //clone and remove nulls
803 this.excludeFieldNames = toNoNullStringArray(excludeFieldNamesParam);
804 Arrays.sort(this.excludeFieldNames);
803 this.excludeFieldNames = ArraySorter.sort(toNoNullStringArray(excludeFieldNamesParam));
805804 }
806805 return this;
807806 }
3939 * <p>Constructor.</p>
4040 */
4141 public StandardToStringStyle() {
42 super();
4342 }
4443
4544 //---------------------------------------------------------------------
132132 * @throws IllegalArgumentException if the style is {@code null}
133133 */
134134 public static void setDefaultStyle(final ToStringStyle style) {
135 defaultStyle = Validate.notNull(style, "The style must not be null");
135 defaultStyle = Validate.notNull(style, "style");
136136 }
137137
138138 //----------------------------------------------------------------------------
262262 /**
263263 * Whether to use short class names, the default is {@code false}.
264264 */
265 private boolean useShortClassName = false;
265 private boolean useShortClassName;
266266
267267 /**
268268 * Whether to use the identity hash code, the default is {@code true}.
287287 /**
288288 * Whether the field separator should be added before any other fields.
289289 */
290 private boolean fieldSeparatorAtStart = false;
290 private boolean fieldSeparatorAtStart;
291291
292292 /**
293293 * Whether the field separator should be added after any other fields.
294294 */
295 private boolean fieldSeparatorAtEnd = false;
295 private boolean fieldSeparatorAtEnd;
296296
297297 /**
298298 * The field separator {@code ','}.
356356 * <p>Constructor.</p>
357357 */
358358 protected ToStringStyle() {
359 super();
360359 }
361360
362361 //----------------------------------------------------------------------------
575574 appendSummary(buffer, fieldName, (Object[]) value);
576575 }
577576
577 } else if (detail) {
578 appendDetail(buffer, fieldName, value);
578579 } else {
579 if (detail) {
580 appendDetail(buffer, fieldName, value);
581 } else {
582 appendSummary(buffer, fieldName, value);
583 }
580 appendSummary(buffer, fieldName, value);
584581 }
585582 } finally {
586583 unregister(value);
625622 * {@code toString}, not {@code null}
626623 */
627624 protected void appendDetail(final StringBuffer buffer, final String fieldName, final Collection<?> coll) {
628 if (coll != null && !coll.isEmpty()) {
629 buffer.append(arrayStart);
630 int i = 0;
631 for (final Object item : coll) {
632 appendDetail(buffer, fieldName, i++, item);
633 }
634 buffer.append(arrayEnd);
635 return;
636 }
637
638625 buffer.append(coll);
639626 }
640627
21602147 * <p>Use the static constant rather than instantiating.</p>
21612148 */
21622149 DefaultToStringStyle() {
2163 super();
21642150 }
21652151
21662152 /**
21932179 * <p>Use the static constant rather than instantiating.</p>
21942180 */
21952181 NoFieldNameToStringStyle() {
2196 super();
21972182 this.setUseFieldNames(false);
21982183 }
21992184
22272212 * <p>Use the static constant rather than instantiating.</p>
22282213 */
22292214 ShortPrefixToStringStyle() {
2230 super();
22312215 this.setUseShortClassName(true);
22322216 this.setUseIdentityHashCode(false);
22332217 }
22612245 * <p>Use the static constant rather than instantiating.</p>
22622246 */
22632247 SimpleToStringStyle() {
2264 super();
22652248 this.setUseClassName(false);
22662249 this.setUseIdentityHashCode(false);
22672250 this.setUseFieldNames(false);
22972280 * <p>Use the static constant rather than instantiating.</p>
22982281 */
22992282 MultiLineToStringStyle() {
2300 super();
23012283 this.setContentStart("[");
23022284 this.setFieldSeparator(System.lineSeparator() + " ");
23032285 this.setFieldSeparatorAtStart(true);
23342316 * <p>Use the static constant rather than instantiating.</p>
23352317 */
23362318 NoClassNameToStringStyle() {
2337 super();
23382319 this.setUseClassName(false);
23392320 this.setUseIdentityHashCode(false);
23402321 }
23812362 * </p>
23822363 */
23832364 JsonToStringStyle() {
2384 super();
2385
23862365 this.setUseClassName(false);
23872366 this.setUseIdentityHashCode(false);
23882367
25942573 }
25952574
25962575 appendDetail(buffer, fieldName, valueAsString);
2576 }
2577
2578 @Override
2579 protected void appendDetail(final StringBuffer buffer, final String fieldName, final Collection<?> coll) {
2580 if (coll != null && !coll.isEmpty()) {
2581 buffer.append(getArrayStart());
2582 int i = 0;
2583 for (final Object item : coll) {
2584 appendDetail(buffer, fieldName, i++, item);
2585 }
2586 buffer.append(getArrayEnd());
2587 return;
2588 }
2589
2590 buffer.append(coll);
25972591 }
25982592
25992593 @Override
2626 * @since 3.5
2727 */
2828 public abstract class AbstractCircuitBreaker<T> implements CircuitBreaker<T> {
29
2930 /**
3031 * The name of the <em>open</em> property as it is passed to registered
3132 * change listeners.
138139 * {@code CircuitBreaker}.
139140 */
140141 protected enum State {
142
143 /** The closed state. */
141144 CLOSED {
142145 /**
143146 * {@inheritDoc}
148151 }
149152 },
150153
154 /** The open state. */
151155 OPEN {
152156 /**
153157 * {@inheritDoc}
174174
175175 // Determine the executor to use and whether a temporary one has to
176176 // be created
177 ExecutorService tempExec;
177 final ExecutorService tempExec;
178178 executor = getExternalExecutor();
179179 if (executor == null) {
180180 executor = tempExec = createExecutor();
279279 * is <b>null</b>
280280 */
281281 public Builder wrappedFactory(final ThreadFactory factory) {
282 Validate.notNull(factory, "Wrapped ThreadFactory must not be null!");
282 Validate.notNull(factory, "factory");
283283
284284 wrappedFactory = factory;
285285 return this;
294294 * @throws NullPointerException if the naming pattern is <b>null</b>
295295 */
296296 public Builder namingPattern(final String pattern) {
297 Validate.notNull(pattern, "Naming pattern must not be null!");
297 Validate.notNull(pattern, "pattern");
298298
299299 namingPattern = pattern;
300300 return this;
336336 */
337337 public Builder uncaughtExceptionHandler(
338338 final Thread.UncaughtExceptionHandler handler) {
339 Validate.notNull(handler, "Uncaught exception handler must not be null!");
339 Validate.notNull(handler, "handler");
340340
341341 exceptionHandler = handler;
342342 return this;
115115 * Tests the passed in {@code Callable} and throws an exception if it is
116116 * undefined.
117117 *
118 * @param call the object to check
118 * @param callable the object to check
119119 * @throws IllegalArgumentException if the {@code Callable} is <b>null</b>
120120 */
121 private void checkCallable(final Callable<T> call) {
122 Validate.notNull(call, "Callable must not be null!");
121 private void checkCallable(final Callable<T> callable) {
122 Validate.notNull(callable, "callable");
123123 }
124124 }
3232 * Creates a new, uninitialized instance of {@code CircuitBreakingException}.
3333 */
3434 public CircuitBreakingException() {
35 super();
3635 }
3736
3837 /**
4040 * Creates a new, uninitialized instance of {@code ConcurrentException}.
4141 */
4242 protected ConcurrentException() {
43 super();
4443 }
4544
4645 /**
4242 * ConcurrentRuntimeException}.
4343 */
4444 protected ConcurrentRuntimeException() {
45 super();
4645 }
4746
4847 /**
173173 public EventCountCircuitBreaker(final int openingThreshold, final long openingInterval,
174174 final TimeUnit openingUnit, final int closingThreshold, final long closingInterval,
175175 final TimeUnit closingUnit) {
176 super();
177176 checkIntervalData = new AtomicReference<>(new CheckIntervalData(0, 0));
178177 this.openingThreshold = openingThreshold;
179178 this.openingInterval = openingUnit.toNanos(openingInterval);
293292 @Override
294293 public void open() {
295294 super.open();
296 checkIntervalData.set(new CheckIntervalData(0, now()));
295 checkIntervalData.set(new CheckIntervalData(0, nanoTime()));
297296 }
298297
299298 /**
305304 @Override
306305 public void close() {
307306 super.close();
308 checkIntervalData.set(new CheckIntervalData(0, now()));
307 checkIntervalData.set(new CheckIntervalData(0, nanoTime()));
309308 }
310309
311310 /**
321320 State currentState;
322321
323322 do {
324 final long time = now();
323 final long time = nanoTime();
325324 currentState = state.get();
326325 currentData = checkIntervalData.get();
327326 nextData = nextCheckIntervalData(increment, currentData, currentState, time);
360359 */
361360 private void changeStateAndStartNewCheckInterval(final State newState) {
362361 changeState(newState);
363 checkIntervalData.set(new CheckIntervalData(0, now()));
362 checkIntervalData.set(new CheckIntervalData(0, nanoTime()));
364363 }
365364
366365 /**
376375 */
377376 private CheckIntervalData nextCheckIntervalData(final int increment,
378377 final CheckIntervalData currentData, final State currentState, final long time) {
379 CheckIntervalData nextData;
378 final CheckIntervalData nextData;
380379 if (stateStrategy(currentState).isCheckIntervalFinished(this, currentData, time)) {
381380 nextData = new CheckIntervalData(increment, time);
382381 } else {
391390 *
392391 * @return the current time in nanoseconds
393392 */
394 long now() {
393 long nanoTime() {
395394 return System.nanoTime();
396395 }
397396
105105 * Creates a new instance of {@code MultiBackgroundInitializer}.
106106 */
107107 public MultiBackgroundInitializer() {
108 super();
109108 }
110109
111110 /**
126125 * been invoked.
127126 *
128127 * @param name the name of the initializer (must not be <b>null</b>)
129 * @param init the {@code BackgroundInitializer} to add (must not be
128 * @param backgroundInitializer the {@code BackgroundInitializer} to add (must not be
130129 * <b>null</b>)
131130 * @throws IllegalArgumentException if a required parameter is missing
132131 * @throws IllegalStateException if {@code start()} has already been called
133132 */
134 public void addInitializer(final String name, final BackgroundInitializer<?> init) {
135 Validate.notNull(name, "Name of child initializer must not be null!");
136 Validate.notNull(init, "Child initializer must not be null!");
133 public void addInitializer(final String name, final BackgroundInitializer<?> backgroundInitializer) {
134 Validate.notNull(name, "name");
135 Validate.notNull(backgroundInitializer, "backgroundInitializer");
137136
138137 synchronized (this) {
139138 if (isStarted()) {
140 throw new IllegalStateException(
141 "addInitializer() must not be called after start()!");
139 throw new IllegalStateException("addInitializer() must not be called after start()!");
142140 }
143 childInitializers.put(name, init);
141 childInitializers.put(name, backgroundInitializer);
144142 }
145143 }
146144
177175 */
178176 @Override
179177 protected MultiBackgroundInitializerResults initialize() throws Exception {
180 Map<String, BackgroundInitializer<?>> inits;
178 final Map<String, BackgroundInitializer<?>> inits;
181179 synchronized (this) {
182180 // create a snapshot to operate on
183181 inits = new HashMap<>(
7272 * @param threshold the threshold.
7373 */
7474 public ThresholdCircuitBreaker(final long threshold) {
75 super();
7675 this.used = new AtomicLong(INITIAL_COUNT);
7776 this.threshold = threshold;
7877 }
117117 * @param readLockSupplier Supplies the read lock, usually from the lock object.
118118 * @param writeLockSupplier Supplies the write lock, usually from the lock object.
119119 */
120 protected LockVisitor(final O object, L lock, Supplier<Lock> readLockSupplier, Supplier<Lock> writeLockSupplier) {
121 super();
120 protected LockVisitor(final O object, final L lock, final Supplier<Lock> readLockSupplier, final Supplier<Lock> writeLockSupplier) {
122121 this.object = Objects.requireNonNull(object, "object");
123122 this.lock = Objects.requireNonNull(lock, "lock");
124123 this.readLockSupplier = Objects.requireNonNull(readLockSupplier, "readLockSupplier");
143142 * @see #acceptWriteLocked(FailableConsumer)
144143 * @see #applyReadLocked(FailableFunction)
145144 */
146 public void acceptReadLocked(FailableConsumer<O, ?> consumer) {
145 public void acceptReadLocked(final FailableConsumer<O, ?> consumer) {
147146 lockAcceptUnlock(readLockSupplier, consumer);
148147 }
149148
205204 * @see #acceptReadLocked(FailableConsumer)
206205 * @see #applyWriteLocked(FailableFunction)
207206 */
208 public <T> T applyReadLocked(FailableFunction<O, T, ?> function) {
207 public <T> T applyReadLocked(final FailableFunction<O, T, ?> function) {
209208 return lockApplyUnlock(readLockSupplier, function);
210209 }
211210
271270 lock.lock();
272271 try {
273272 consumer.accept(object);
274 } catch (Throwable t) {
273 } catch (final Throwable t) {
275274 throw Failable.rethrow(t);
276275 } finally {
277276 lock.unlock();
298297 lock.lock();
299298 try {
300299 return function.apply(object);
301 } catch (Throwable t) {
300 } catch (final Throwable t) {
302301 throw Failable.rethrow(t);
303302 } finally {
304303 lock.unlock();
348347 * @param object The locked (hidden) object. The caller is supposed to drop all references to the locked object.
349348 * @param stampedLock the lock to use.
350349 */
351 protected StampedLockVisitor(final O object, StampedLock stampedLock) {
350 protected StampedLockVisitor(final O object, final StampedLock stampedLock) {
352351 super(object, stampedLock, stampedLock::asReadLock, stampedLock::asWriteLock);
353352 }
354353 }
139139 */
140140 public EventListenerSupport(final Class<L> listenerInterface, final ClassLoader classLoader) {
141141 this();
142 Validate.notNull(listenerInterface, "Listener interface cannot be null.");
143 Validate.notNull(classLoader, "ClassLoader cannot be null.");
142 Validate.notNull(listenerInterface, "listenerInterface");
143 Validate.notNull(classLoader, "classLoader");
144144 Validate.isTrue(listenerInterface.isInterface(), "Class %s is not an interface",
145145 listenerInterface.getName());
146146 initializeTransientFields(listenerInterface, classLoader);
193193 * @since 3.5
194194 */
195195 public void addListener(final L listener, final boolean allowDuplicate) {
196 Validate.notNull(listener, "Listener object cannot be null.");
196 Validate.notNull(listener, "listener");
197197 if (allowDuplicate || !listeners.contains(listener)) {
198198 listeners.add(listener);
199199 }
217217 * {@code null}.
218218 */
219219 public void removeListener(final L listener) {
220 Validate.notNull(listener, "Listener object cannot be null.");
220 Validate.notNull(listener, "listener");
221221 listeners.remove(listener);
222222 }
223223
4444 * throw new ContextedException("Error posting account transaction", e)
4545 * .addContextValue("Account Number", accountNumber)
4646 * .addContextValue("Amount Posted", amountPosted)
47 * .addContextValue("Previous Balance", previousBalance)
47 * .addContextValue("Previous Balance", previousBalance);
4848 * }
4949 * }
5050 * </pre>
9696 * The context information is stored using a default implementation.
9797 */
9898 public ContextedException() {
99 super();
10099 exceptionContext = new DefaultExceptionContext();
101100 }
102101
4444 * throw new ContextedRuntimeException("Error posting account transaction", e)
4545 * .addContextValue("Account Number", accountNumber)
4646 * .addContextValue("Amount Posted", amountPosted)
47 * .addContextValue("Previous Balance", previousBalance)
47 * .addContextValue("Previous Balance", previousBalance);
4848 * }
4949 * }
5050 * </pre>
9696 * The context information is stored using a default implementation.
9797 */
9898 public ContextedRuntimeException() {
99 super();
10099 exceptionContext = new DefaultExceptionContext();
101100 }
102101
4040 * constructs like:
4141 *
4242 * <pre>
43 * Consumer&lt;java.lang.reflect.Method-&gt; consumer = (m) -&gt; {
43 * Consumer&lt;java.lang.reflect.Method-&gt; consumer = m -&gt; {
4444 * try {
4545 * m.invoke(o, args);
4646 * } catch (Throwable t) {
323323 *
324324 * @param supplier The double supplier to invoke.
325325 * @param <E> The type of checked exception, which the supplier can throw.
326 * @return The boolean, which has been created by the supplier
326 * @return The double, which has been created by the supplier
327327 */
328328 public static <E extends Throwable> double getAsDouble(final FailableDoubleSupplier<E> supplier) {
329329 try {
338338 *
339339 * @param supplier The int supplier to invoke.
340340 * @param <E> The type of checked exception, which the supplier can throw.
341 * @return The boolean, which has been created by the supplier
341 * @return The int, which has been created by the supplier
342342 */
343343 public static <E extends Throwable> int getAsInt(final FailableIntSupplier<E> supplier) {
344344 try {
353353 *
354354 * @param supplier The long supplier to invoke.
355355 * @param <E> The type of checked exception, which the supplier can throw.
356 * @return The boolean, which has been created by the supplier
356 * @return The long, which has been created by the supplier
357357 */
358358 public static <E extends Throwable> long getAsLong(final FailableLongSupplier<E> supplier) {
359359 try {
360360 return supplier.getAsLong();
361 } catch (final Throwable t) {
362 throw rethrow(t);
363 }
364 }
365
366 /**
367 * Invokes a short supplier, and returns the result.
368 *
369 * @param supplier The short supplier to invoke.
370 * @param <E> The type of checked exception, which the supplier can throw.
371 * @return The short, which has been created by the supplier
372 */
373 public static <E extends Throwable> short getAsShort(final FailableShortSupplier<E> supplier) {
374 try {
375 return supplier.getAsShort();
361376 } catch (final Throwable t) {
362377 throw rethrow(t);
363378 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.commons.lang3.function;
18
19 import java.util.function.IntSupplier;
20
21 /**
22 * A functional interface like {@link IntSupplier} but for {@code short} that declares a {@code Throwable}.
23 *
24 * @param <E> Thrown exception.
25 * @since 3.12.0
26 */
27 @FunctionalInterface
28 public interface FailableShortSupplier<E extends Throwable> {
29
30 /**
31 * Supplies an int.
32 *
33 * @return a result
34 * @throws E if the supplier fails
35 */
36 short getAsShort() throws E;
37 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.commons.lang3.function;
18
19 import java.util.function.BiFunction;
20
21 /**
22 * A function that accepts two arguments and produces a boolean result. This is the {@code boolean}-producing primitive
23 * specialization for {@link BiFunction}.
24 *
25 * @param <T> the type of the first argument to the function.
26 * @param <U> the type of the second argument to the function.
27 *
28 * @see BiFunction
29 * @since 3.12.0
30 */
31 @FunctionalInterface
32 public interface ToBooleanBiFunction<T, U> {
33
34 /**
35 * Applies this function to the given arguments.
36 *
37 * @param t the first function argument.
38 * @param u the second function argument.
39 * @return the function result.
40 */
41 boolean applyAsBoolean(T t, U u);
42 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.commons.lang3.function;
17
18 import java.util.Objects;
19 import java.util.function.Function;
20
21 /**
22 * Represents a function that accepts three arguments and produces a result. This is the three-arity specialization of
23 * {@link Function}.
24 *
25 * <p>
26 * This is a <a href="package-summary.html">functional interface</a> whose functional method is
27 * {@link #apply(Object, Object, Object)}.
28 * </p>
29 *
30 * @param <T> the type of the first argument to the function
31 * @param <U> the type of the second argument to the function
32 * @param <V> the type of the third argument to the function
33 * @param <R> the type of the result of the function
34 *
35 * @see Function
36 * @since 3.12.0
37 */
38 @FunctionalInterface
39 public interface TriFunction<T, U, V, R> {
40
41 /**
42 * Applies this function to the given arguments.
43 *
44 * @param t the first function argument
45 * @param u the second function argument
46 * @param v the third function argument
47 * @return the function result
48 */
49 R apply(T t, U u, V v);
50
51 /**
52 * Returns a composed function that first applies this function to its input, and then applies the {@code after}
53 * function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the
54 * composed function.
55 *
56 * @param <W> the type of output of the {@code after} function, and of the composed function
57 * @param after the function to apply after this function is applied
58 * @return a composed function that first applies this function and then applies the {@code after} function
59 * @throws NullPointerException if after is null
60 */
61 default <W> TriFunction<T, U, V, W> andThen(final Function<? super R, ? extends W> after) {
62 Objects.requireNonNull(after);
63 return (final T t, final U u, final V v) -> after.apply(apply(t, u, v));
64 }
65 }
103103 /**
104104 * Cached output hashCode (class is immutable).
105105 */
106 private transient int hashCode = 0;
106 private transient int hashCode;
107107 /**
108108 * Cached output toString (class is immutable).
109109 */
110 private transient String toString = null;
110 private transient String toString;
111111 /**
112112 * Cached output toProperString (class is immutable).
113113 */
114 private transient String toProperString = null;
114 private transient String toProperString;
115115
116116 /**
117117 * <p>Constructs a {@code Fraction} instance with the 2 parts
121121 * @param denominator the denominator, for example the seven in 'three sevenths'
122122 */
123123 private Fraction(final int numerator, final int denominator) {
124 super();
125124 this.numerator = numerator;
126125 this.denominator = denominator;
127126 }
178177 if (numerator < 0) {
179178 throw new ArithmeticException("The numerator must not be negative");
180179 }
181 long numeratorValue;
180 final long numeratorValue;
182181 if (whole < 0) {
183182 numeratorValue = whole * (long) denominator - numerator;
184183 } else {
311310 * @throws NumberFormatException if the number format is invalid
312311 */
313312 public static Fraction getFraction(String str) {
314 Validate.notNull(str, "The string must not be null");
313 Validate.notNull(str, "str");
315314 // parse double format
316315 int pos = str.indexOf('.');
317316 if (pos >= 0) {
729728 * cannot be represented in an {@code int}.
730729 */
731730 private Fraction addSub(final Fraction fraction, final boolean isAdd) {
732 Validate.notNull(fraction, "The fraction must not be null");
731 Validate.notNull(fraction, "fraction");
733732 // zero is identity for addition.
734733 if (numerator == 0) {
735734 return isAdd ? fraction : fraction.negate();
777776 * {@code Integer.MAX_VALUE}
778777 */
779778 public Fraction multiplyBy(final Fraction fraction) {
780 Validate.notNull(fraction, "The fraction must not be null");
779 Validate.notNull(fraction, "fraction");
781780 if (numerator == 0 || fraction.numerator == 0) {
782781 return ZERO;
783782 }
800799 * {@code Integer.MAX_VALUE}
801800 */
802801 public Fraction divideBy(final Fraction fraction) {
803 Validate.notNull(fraction, "The fraction must not be null");
802 Validate.notNull(fraction, "fraction");
804803 if (fraction.numerator == 0) {
805804 throw new ArithmeticException("The fraction to divide by must not be zero");
806805 }
3636 * @since 3.4 Changed signature from min(double[]) to min(double...)
3737 */
3838 public static double min(final double... array) {
39 Validate.notNull(array, "The Array must not be null");
39 Validate.notNull(array, "array");
4040 Validate.isTrue(array.length != 0, "Array cannot be empty.");
4141
4242 // Finds and returns min
5858 * @since 3.4 Changed signature from min(float[]) to min(float...)
5959 */
6060 public static float min(final float... array) {
61 Validate.notNull(array, "The Array must not be null");
61 Validate.notNull(array, "array");
6262 Validate.isTrue(array.length != 0, "Array cannot be empty.");
6363
6464 // Finds and returns min
148148 * @since 3.4 Changed signature from max(double[]) to max(double...)
149149 */
150150 public static double max(final double... array) {
151 Validate.notNull(array, "The Array must not be null");
151 Validate.notNull(array, "array");
152152 Validate.isTrue(array.length != 0, "Array cannot be empty.");
153153
154154 // Finds and returns max
170170 * @since 3.4 Changed signature from max(float[]) to max(float...)
171171 */
172172 public static float max(final float... array) {
173 Validate.notNull(array, "The Array must not be null");
173 Validate.notNull(array, "array");
174174 Validate.isTrue(array.length != 0, "Array cannot be empty.");
175175
176176 // Finds and returns max
6969 /** Reusable Float constant for minus one. */
7070 public static final Float FLOAT_MINUS_ONE = Float.valueOf(-1.0f);
7171
72 /**
73 * {@link Integer#MAX_VALUE} as a {@link Long}.
74 *
75 * @since 3.12.0
76 */
77 public static final Long LONG_INT_MAX_VALUE = Long.valueOf(Integer.MAX_VALUE);
78
79 /**
80 * {@link Integer#MIN_VALUE} as a {@link Long}.
81 *
82 * @since 3.12.0
83 */
84 public static final Long LONG_INT_MIN_VALUE = Long.valueOf(Integer.MIN_VALUE);
85
7286
7387 /**
7488 * <p>{@code NumberUtils} instances should NOT be constructed in standard programming.
7892 * to operate.</p>
7993 */
8094 public NumberUtils() {
81 super();
8295 }
8396
8497 //-----------------------------------------------------------------------
655668 }
656669 // Need to deal with all possible hex prefixes here
657670 final String[] hex_prefixes = {"0x", "0X", "-0x", "-0X", "#", "-#"};
671 final int length = str.length();
658672 int pfxLen = 0;
659673 for (final String pfx : hex_prefixes) {
660674 if (str.startsWith(pfx)) {
664678 }
665679 if (pfxLen > 0) { // we have a hex number
666680 char firstSigDigit = 0; // strip leading zeroes
667 for (int i = pfxLen; i < str.length(); i++) {
681 for (int i = pfxLen; i < length; i++) {
668682 firstSigDigit = str.charAt(i);
669683 if (firstSigDigit == '0') { // count leading zeroes
670684 pfxLen++;
672686 break;
673687 }
674688 }
675 final int hexDigits = str.length() - pfxLen;
689 final int hexDigits = length - pfxLen;
676690 if (hexDigits > 16 || hexDigits == 16 && firstSigDigit > '7') { // too many for Long
677691 return createBigInteger(str);
678692 }
681695 }
682696 return createInteger(str);
683697 }
684 final char lastChar = str.charAt(str.length() - 1);
685 String mant;
686 String dec;
687 String exp;
698 final char lastChar = str.charAt(length - 1);
699 final String mant;
700 final String dec;
701 final String exp;
688702 final int decPos = str.indexOf('.');
689703 final int expPos = str.indexOf('e') + str.indexOf('E') + 1; // assumes both not present
690704 // if both e and E are present, this is caught by the checks on expPos (which prevent IOOBE)
692706
693707 if (decPos > -1) { // there is a decimal point
694708 if (expPos > -1) { // there is an exponent
695 if (expPos < decPos || expPos > str.length()) { // prevents double exponent causing IOOBE
709 if (expPos < decPos || expPos > length) { // prevents double exponent causing IOOBE
696710 throw new NumberFormatException(str + " is not a valid number.");
697711 }
698712 dec = str.substring(decPos + 1, expPos);
702716 mant = getMantissa(str, decPos);
703717 } else {
704718 if (expPos > -1) {
705 if (expPos > str.length()) { // prevents double exponent causing IOOBE
719 if (expPos > length) { // prevents double exponent causing IOOBE
706720 throw new NumberFormatException(str + " is not a valid number.");
707721 }
708722 mant = getMantissa(str, expPos);
712726 dec = null;
713727 }
714728 if (!Character.isDigit(lastChar) && lastChar != '.') {
715 if (expPos > -1 && expPos < str.length() - 1) {
716 exp = str.substring(expPos + 1, str.length() - 1);
729 if (expPos > -1 && expPos < length - 1) {
730 exp = str.substring(expPos + 1, length - 1);
717731 } else {
718732 exp = null;
719733 }
720734 //Requesting a specific type..
721 final String numeric = str.substring(0, str.length() - 1);
735 final String numeric = str.substring(0, length - 1);
722736 final boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
723737 switch (lastChar) {
724738 case 'l' :
753767 case 'D' :
754768 try {
755769 final Double d = createDouble(str);
756 if (!(d.isInfinite() || d.floatValue() == 0.0D && !allZeros)) {
770 if (!(d.isInfinite() || d.doubleValue() == 0.0D && !allZeros)) {
757771 return d;
758772 }
759773 } catch (final NumberFormatException nfe) { // NOPMD
772786 }
773787 //User doesn't have a preference on the return type, so let's start
774788 //small and go from there...
775 if (expPos > -1 && expPos < str.length() - 1) {
776 exp = str.substring(expPos + 1, str.length());
789 if (expPos > -1 && expPos < length - 1) {
790 exp = str.substring(expPos + 1);
777791 } else {
778792 exp = null;
779793 }
13041318 * @throws IllegalArgumentException if {@code array} is either {@code null} or empty
13051319 */
13061320 private static void validateArray(final Object array) {
1307 Validate.notNull(array, "The Array must not be null");
1321 Validate.notNull(array, "array");
13081322 Validate.isTrue(Array.getLength(array) != 0, "Array cannot be empty.");
13091323 }
13101324
4444 * Constructs a new MutableBoolean with the default value of false.
4545 */
4646 public MutableBoolean() {
47 super();
4847 }
4948
5049 /**
5352 * @param value the initial value to store
5453 */
5554 public MutableBoolean(final boolean value) {
56 super();
5755 this.value = value;
5856 }
5957
6462 * @throws NullPointerException if the object is null
6563 */
6664 public MutableBoolean(final Boolean value) {
67 super();
6865 this.value = value.booleanValue();
6966 }
7067
4141 * Constructs a new MutableByte with the default value of zero.
4242 */
4343 public MutableByte() {
44 super();
4544 }
4645
4746 /**
5049 * @param value the initial value to store
5150 */
5251 public MutableByte(final byte value) {
53 super();
5452 this.value = value;
5553 }
5654
6159 * @throws NullPointerException if the object is null
6260 */
6361 public MutableByte(final Number value) {
64 super();
6562 this.value = value.byteValue();
6663 }
6764
7370 * @since 2.5
7471 */
7572 public MutableByte(final String value) {
76 super();
7773 this.value = Byte.parseByte(value);
7874 }
7975
3939 * Constructs a new MutableDouble with the default value of zero.
4040 */
4141 public MutableDouble() {
42 super();
4342 }
4443
4544 /**
4847 * @param value the initial value to store
4948 */
5049 public MutableDouble(final double value) {
51 super();
5250 this.value = value;
5351 }
5452
5957 * @throws NullPointerException if the object is null
6058 */
6159 public MutableDouble(final Number value) {
62 super();
6360 this.value = value.doubleValue();
6461 }
6562
7168 * @since 2.5
7269 */
7370 public MutableDouble(final String value) {
74 super();
7571 this.value = Double.parseDouble(value);
7672 }
7773
3939 * Constructs a new MutableFloat with the default value of zero.
4040 */
4141 public MutableFloat() {
42 super();
4342 }
4443
4544 /**
4847 * @param value the initial value to store
4948 */
5049 public MutableFloat(final float value) {
51 super();
5250 this.value = value;
5351 }
5452
5957 * @throws NullPointerException if the object is null
6058 */
6159 public MutableFloat(final Number value) {
62 super();
6360 this.value = value.floatValue();
6461 }
6562
7168 * @since 2.5
7269 */
7370 public MutableFloat(final String value) {
74 super();
7571 this.value = Float.parseFloat(value);
7672 }
7773
4141 * Constructs a new MutableInt with the default value of zero.
4242 */
4343 public MutableInt() {
44 super();
4544 }
4645
4746 /**
5049 * @param value the initial value to store
5150 */
5251 public MutableInt(final int value) {
53 super();
5452 this.value = value;
5553 }
5654
6159 * @throws NullPointerException if the object is null
6260 */
6361 public MutableInt(final Number value) {
64 super();
6562 this.value = value.intValue();
6663 }
6764
7370 * @since 2.5
7471 */
7572 public MutableInt(final String value) {
76 super();
7773 this.value = Integer.parseInt(value);
7874 }
7975
4141 * Constructs a new MutableLong with the default value of zero.
4242 */
4343 public MutableLong() {
44 super();
4544 }
4645
4746 /**
5049 * @param value the initial value to store
5150 */
5251 public MutableLong(final long value) {
53 super();
5452 this.value = value;
5553 }
5654
6159 * @throws NullPointerException if the object is null
6260 */
6361 public MutableLong(final Number value) {
64 super();
6562 this.value = value.longValue();
6663 }
6764
7370 * @since 2.5
7471 */
7572 public MutableLong(final String value) {
76 super();
7773 this.value = Long.parseLong(value);
7874 }
7975
4040 * Constructs a new MutableObject with the default value of {@code null}.
4141 */
4242 public MutableObject() {
43 super();
4443 }
4544
4645 /**
4948 * @param value the initial value to store
5049 */
5150 public MutableObject(final T value) {
52 super();
5351 this.value = value;
5452 }
5553
4141 * Constructs a new MutableShort with the default value of zero.
4242 */
4343 public MutableShort() {
44 super();
4544 }
4645
4746 /**
5049 * @param value the initial value to store
5150 */
5251 public MutableShort(final short value) {
53 super();
5452 this.value = value;
5553 }
5654
6159 * @throws NullPointerException if the object is null
6260 */
6361 public MutableShort(final Number value) {
64 super();
6562 this.value = value.shortValue();
6663 }
6764
7370 * @since 2.5
7471 */
7572 public MutableShort(final String value) {
76 super();
7773 this.value = Short.parseShort(value);
7874 }
7975
5454 * instance to operate.</p>
5555 */
5656 public ConstructorUtils() {
57 super();
5857 }
5958
6059 /**
198197 */
199198 public static <T> Constructor<T> getAccessibleConstructor(final Class<T> cls,
200199 final Class<?>... parameterTypes) {
201 Validate.notNull(cls, "class cannot be null");
200 Validate.notNull(cls, "cls");
202201 try {
203202 return getAccessibleConstructor(cls.getConstructor(parameterTypes));
204203 } catch (final NoSuchMethodException e) {
218217 * @throws NullPointerException if {@code ctor} is {@code null}
219218 */
220219 public static <T> Constructor<T> getAccessibleConstructor(final Constructor<T> ctor) {
221 Validate.notNull(ctor, "constructor cannot be null");
220 Validate.notNull(ctor, "ctor");
222221 return MemberUtils.isAccessible(ctor)
223222 && isAccessible(ctor.getDeclaringClass()) ? ctor : null;
224223 }
243242 */
244243 public static <T> Constructor<T> getMatchingAccessibleConstructor(final Class<T> cls,
245244 final Class<?>... parameterTypes) {
246 Validate.notNull(cls, "class cannot be null");
245 Validate.notNull(cls, "cls");
247246 // see if we can find the constructor directly
248247 // most of the time this works and it's much faster
249248 try {
4747 * </p>
4848 */
4949 public FieldUtils() {
50 super();
5150 }
5251
5352 /**
8584 * in the inheritance hierarchy
8685 */
8786 public static Field getField(final Class<?> cls, final String fieldName, final boolean forceAccess) {
88 Validate.notNull(cls, "The class must not be null");
87 Validate.notNull(cls, "cls");
8988 Validate.isTrue(StringUtils.isNotBlank(fieldName), "The field name must not be blank/empty");
9089 // FIXME is this workaround still needed? lang requires Java 6
9190 // Sun Java 1.3 has a bugged implementation of getField hence we write the
168167 * if the class is {@code null}, or the field name is blank or empty
169168 */
170169 public static Field getDeclaredField(final Class<?> cls, final String fieldName, final boolean forceAccess) {
171 Validate.notNull(cls, "The class must not be null");
170 Validate.notNull(cls, "cls");
172171 Validate.isTrue(StringUtils.isNotBlank(fieldName), "The field name must not be blank/empty");
173172 try {
174173 // only consider the specified class by using getDeclaredField()
213212 * @since 3.2
214213 */
215214 public static List<Field> getAllFieldsList(final Class<?> cls) {
216 Validate.notNull(cls, "The class must not be null");
215 Validate.notNull(cls, "cls");
217216 final List<Field> allFields = new ArrayList<>();
218217 Class<?> currentClass = cls;
219218 while (currentClass != null) {
252251 * @since 3.4
253252 */
254253 public static List<Field> getFieldsListWithAnnotation(final Class<?> cls, final Class<? extends Annotation> annotationCls) {
255 Validate.notNull(annotationCls, "The annotation class must not be null");
254 Validate.notNull(annotationCls, "annotationCls");
256255 final List<Field> allFields = getAllFieldsList(cls);
257256 final List<Field> annotatedFields = new ArrayList<>();
258257 for (final Field field : allFields) {
293292 * if the field is not made accessible
294293 */
295294 public static Object readStaticField(final Field field, final boolean forceAccess) throws IllegalAccessException {
296 Validate.notNull(field, "The field must not be null");
295 Validate.notNull(field, "field");
297296 Validate.isTrue(Modifier.isStatic(field.getModifiers()), "The field '%s' is not static", field.getName());
298297 return readField(field, (Object) null, forceAccess);
299298 }
419418 * if the field is not made accessible
420419 */
421420 public static Object readField(final Field field, final Object target, final boolean forceAccess) throws IllegalAccessException {
422 Validate.notNull(field, "The field must not be null");
421 Validate.notNull(field, "field");
423422 if (forceAccess && !field.isAccessible()) {
424423 field.setAccessible(true);
425424 } else {
463462 * if the named field is not made accessible
464463 */
465464 public static Object readField(final Object target, final String fieldName, final boolean forceAccess) throws IllegalAccessException {
466 Validate.notNull(target, "target object must not be null");
465 Validate.notNull(target, "target");
467466 final Class<?> cls = target.getClass();
468467 final Field field = getField(cls, fieldName, forceAccess);
469468 Validate.isTrue(field != null, "Cannot locate field %s on %s", fieldName, cls);
506505 * if the field is not made accessible
507506 */
508507 public static Object readDeclaredField(final Object target, final String fieldName, final boolean forceAccess) throws IllegalAccessException {
509 Validate.notNull(target, "target object must not be null");
508 Validate.notNull(target, "target");
510509 final Class<?> cls = target.getClass();
511510 final Field field = getDeclaredField(cls, fieldName, forceAccess);
512511 Validate.isTrue(field != null, "Cannot locate declared field %s.%s", cls, fieldName);
547546 * if the field is not made accessible or is {@code final}
548547 */
549548 public static void writeStaticField(final Field field, final Object value, final boolean forceAccess) throws IllegalAccessException {
550 Validate.notNull(field, "The field must not be null");
549 Validate.notNull(field, "field");
551550 Validate.isTrue(Modifier.isStatic(field.getModifiers()), "The field %s.%s is not static", field.getDeclaringClass().getName(),
552551 field.getName());
553552 writeField(field, (Object) null, value, forceAccess);
681680 */
682681 public static void writeField(final Field field, final Object target, final Object value, final boolean forceAccess)
683682 throws IllegalAccessException {
684 Validate.notNull(field, "The field must not be null");
683 Validate.notNull(field, "field");
685684 if (forceAccess && !field.isAccessible()) {
686685 field.setAccessible(true);
687686 } else {
721720 */
722721 @Deprecated
723722 public static void removeFinalModifier(final Field field, final boolean forceAccess) {
724 Validate.notNull(field, "The field must not be null");
723 Validate.notNull(field, "field");
725724
726725 try {
727726 if (Modifier.isFinal(field.getModifiers())) {
790789 */
791790 public static void writeField(final Object target, final String fieldName, final Object value, final boolean forceAccess)
792791 throws IllegalAccessException {
793 Validate.notNull(target, "target object must not be null");
792 Validate.notNull(target, "target");
794793 final Class<?> cls = target.getClass();
795794 final Field field = getField(cls, fieldName, forceAccess);
796795 Validate.isTrue(field != null, "Cannot locate declared field %s.%s", cls.getName(), fieldName);
838837 */
839838 public static void writeDeclaredField(final Object target, final String fieldName, final Object value, final boolean forceAccess)
840839 throws IllegalAccessException {
841 Validate.notNull(target, "target object must not be null");
840 Validate.notNull(target, "target");
842841 final Class<?> cls = target.getClass();
843842 final Field field = getDeclaredField(cls, fieldName, forceAccess);
844843 Validate.isTrue(field != null, "Cannot locate declared field %s.%s", cls.getName(), fieldName);
3333 * instance to operate.</p>
3434 */
3535 public InheritanceUtils() {
36 super();
3736 }
3837
3938 /**
2929 import java.util.LinkedHashSet;
3030 import java.util.List;
3131 import java.util.Map;
32 import java.util.Objects;
3332 import java.util.Set;
33 import java.util.TreeMap;
34 import java.util.stream.Collectors;
3435
3536 import org.apache.commons.lang3.ArrayUtils;
3637 import org.apache.commons.lang3.ClassUtils;
3738 import org.apache.commons.lang3.ClassUtils.Interfaces;
3839 import org.apache.commons.lang3.Validate;
40
41 import static java.util.stream.Collectors.toList;
3942
4043 /**
4144 * <p>Utility reflection methods focused on {@link Method}s, originally from Commons BeanUtils.
7073 * instance to operate.</p>
7174 */
7275 public MethodUtils() {
73 super();
7476 }
7577
7678 /**
739741 */
740742 public static Method getMatchingMethod(final Class<?> cls, final String methodName,
741743 final Class<?>... parameterTypes) {
742 Validate.notNull(cls, "Null class not allowed.");
743 Validate.notEmpty(methodName, "Null or blank methodName not allowed.");
744
745 // Address methods in superclasses
746 Method[] methodArray = cls.getDeclaredMethods();
747 final List<Class<?>> superclassList = ClassUtils.getAllSuperclasses(cls);
748 for (final Class<?> klass : superclassList) {
749 methodArray = ArrayUtils.addAll(methodArray, klass.getDeclaredMethods());
750 }
751
752 Method inexactMatch = null;
753 for (final Method method : methodArray) {
754 if (methodName.equals(method.getName()) &&
755 Objects.deepEquals(parameterTypes, method.getParameterTypes())) {
744 Validate.notNull(cls, "cls");
745 Validate.notEmpty(methodName, "methodName");
746
747 final List<Method> methods = Arrays.stream(cls.getDeclaredMethods())
748 .filter(method -> method.getName().equals(methodName))
749 .collect(toList());
750
751 ClassUtils.getAllSuperclasses(cls).stream()
752 .map(Class::getDeclaredMethods)
753 .flatMap(Arrays::stream)
754 .filter(method -> method.getName().equals(methodName))
755 .forEach(methods::add);
756
757 for (final Method method : methods) {
758 if (Arrays.deepEquals(method.getParameterTypes(), parameterTypes)) {
756759 return method;
757 } else if (methodName.equals(method.getName()) &&
758 ClassUtils.isAssignable(parameterTypes, method.getParameterTypes(), true)) {
759 if ((inexactMatch == null) || (distance(parameterTypes, method.getParameterTypes())
760 < distance(parameterTypes, inexactMatch.getParameterTypes()))) {
761 inexactMatch = method;
762 }
763 }
764
765 }
766 return inexactMatch;
760 }
761 }
762
763 final TreeMap<Integer, List<Method>> candidates = new TreeMap<>();
764
765 methods.stream()
766 .filter(method -> ClassUtils.isAssignable(parameterTypes, method.getParameterTypes(), true))
767 .forEach(method -> {
768 final int distance = distance(parameterTypes, method.getParameterTypes());
769 final List<Method> candidatesAtDistance = candidates.computeIfAbsent(distance, k -> new ArrayList<>());
770 candidatesAtDistance.add(method);
771 });
772
773 if (candidates.isEmpty()) {
774 return null;
775 }
776
777 final List<Method> bestCandidates = candidates.values().iterator().next();
778 if (bestCandidates.size() == 1) {
779 return bestCandidates.get(0);
780 }
781
782 throw new IllegalStateException(
783 String.format("Found multiple candidates for method %s on class %s : %s",
784 methodName + Arrays.stream(parameterTypes).map(String::valueOf).collect(Collectors.joining(",", "(", ")")),
785 cls.getName(),
786 bestCandidates.stream().map(Method::toString).collect(Collectors.joining(",", "[", "]")))
787 );
767788 }
768789
769790 /**
770791 * <p>Returns the aggregate number of inheritance hops between assignable argument class types. Returns -1
771792 * if the arguments aren't assignable. Fills a specific purpose for getMatchingMethod and is not generalized.</p>
772 * @param classArray
773 * @param toClassArray
793 * @param fromClassArray the Class array to calculate the distance from.
794 * @param toClassArray the Class array to calculate the distance to.
774795 * @return the aggregate number of inheritance hops between assignable argument class types.
775796 */
776 private static int distance(final Class<?>[] classArray, final Class<?>[] toClassArray) {
797 private static int distance(final Class<?>[] fromClassArray, final Class<?>[] toClassArray) {
777798 int answer = 0;
778799
779 if (!ClassUtils.isAssignable(classArray, toClassArray, true)) {
800 if (!ClassUtils.isAssignable(fromClassArray, toClassArray, true)) {
780801 return -1;
781802 }
782 for (int offset = 0; offset < classArray.length; offset++) {
803 for (int offset = 0; offset < fromClassArray.length; offset++) {
783804 // Note InheritanceUtils.distance() uses different scoring system.
784 if (classArray[offset].equals(toClassArray[offset])) {
805 final Class<?> aClass = fromClassArray[offset];
806 final Class<?> toClass = toClassArray[offset];
807 if (aClass == null || aClass.equals(toClass)) {
785808 continue;
786 } else if (ClassUtils.isAssignable(classArray[offset], toClassArray[offset], true)
787 && !ClassUtils.isAssignable(classArray[offset], toClassArray[offset], false)) {
809 } else if (ClassUtils.isAssignable(aClass, toClass, true)
810 && !ClassUtils.isAssignable(aClass, toClass, false)) {
788811 answer++;
789812 } else {
790813 answer = answer + 2;
907930 final Class<? extends Annotation> annotationCls,
908931 final boolean searchSupers, final boolean ignoreAccess) {
909932
910 Validate.notNull(cls, "The class must not be null");
911 Validate.notNull(annotationCls, "The annotation class must not be null");
933 Validate.notNull(cls, "cls");
934 Validate.notNull(annotationCls, "annotationCls");
912935 final List<Class<?>> classes = (searchSupers ? getAllSuperclassesAndInterfaces(cls)
913936 : new ArrayList<>());
914937 classes.add(0, cls);
949972 public static <A extends Annotation> A getAnnotation(final Method method, final Class<A> annotationCls,
950973 final boolean searchSupers, final boolean ignoreAccess) {
951974
952 Validate.notNull(method, "The method must not be null");
953 Validate.notNull(annotationCls, "The annotation class must not be null");
975 Validate.notNull(method, "method");
976 Validate.notNull(annotationCls, "annotationCls");
954977 if (!ignoreAccess && !MemberUtils.isAccessible(method)) {
955978 return null;
956979 }
9971020 int interfaceIndex = 0;
9981021 while (interfaceIndex < allInterfaces.size() ||
9991022 superClassIndex < allSuperclasses.size()) {
1000 Class<?> acls;
1023 final Class<?> acls;
10011024 if (interfaceIndex >= allInterfaces.size()) {
10021025 acls = allSuperclasses.get(superClassIndex++);
10031026 } else if ((superClassIndex >= allSuperclasses.size()) || (interfaceIndex < superClassIndex) || !(superClassIndex < interfaceIndex)) {
3838 import org.apache.commons.lang3.builder.Builder;
3939
4040 /**
41 * <p> Utility methods focusing on type inspection, particularly with regard to
42 * generics. </p>
41 * Utility methods focusing on type inspection, particularly with regard to
42 * generics.
4343 *
4444 * @since 3.0
4545 */
4646 public class TypeUtils {
4747
4848 /**
49 * {@link WildcardType} builder.
50 * @since 3.2
51 */
52 public static class WildcardTypeBuilder implements Builder<WildcardType> {
53 /**
54 * Constructor
55 */
56 private WildcardTypeBuilder() {
57 }
58
59 private Type[] upperBounds;
60 private Type[] lowerBounds;
61
62 /**
63 * Specify upper bounds of the wildcard type to build.
64 * @param bounds to set
65 * @return {@code this}
66 */
67 public WildcardTypeBuilder withUpperBounds(final Type... bounds) {
68 this.upperBounds = bounds;
69 return this;
70 }
71
72 /**
73 * Specify lower bounds of the wildcard type to build.
74 * @param bounds to set
75 * @return {@code this}
76 */
77 public WildcardTypeBuilder withLowerBounds(final Type... bounds) {
78 this.lowerBounds = bounds;
79 return this;
80 }
81
82 /**
83 * {@inheritDoc}
84 */
85 @Override
86 public WildcardType build() {
87 return new WildcardTypeImpl(upperBounds, lowerBounds);
88 }
89 }
90
91 /**
9249 * GenericArrayType implementation class.
9350 * @since 3.2
9451 */
10158 */
10259 private GenericArrayTypeImpl(final Type componentType) {
10360 this.componentType = componentType;
61 }
62
63 /**
64 * {@inheritDoc}
65 */
66 @Override
67 public boolean equals(final Object obj) {
68 return obj == this || obj instanceof GenericArrayType && TypeUtils.equals(this, (GenericArrayType) obj);
10469 }
10570
10671 /**
10974 @Override
11075 public Type getGenericComponentType() {
11176 return componentType;
112 }
113
114 /**
115 * {@inheritDoc}
116 */
117 @Override
118 public String toString() {
119 return TypeUtils.toString(this);
120 }
121
122 /**
123 * {@inheritDoc}
124 */
125 @Override
126 public boolean equals(final Object obj) {
127 return obj == this || obj instanceof GenericArrayType && TypeUtils.equals(this, (GenericArrayType) obj);
12877 }
12978
13079 /**
13685 result |= componentType.hashCode();
13786 return result;
13887 }
88
89 /**
90 * {@inheritDoc}
91 */
92 @Override
93 public String toString() {
94 return TypeUtils.toString(this);
95 }
13996 }
14097
14198 /**
163120 * {@inheritDoc}
164121 */
165122 @Override
166 public Type getRawType() {
167 return raw;
123 public boolean equals(final Object obj) {
124 return obj == this || obj instanceof ParameterizedType && TypeUtils.equals(this, ((ParameterizedType) obj));
125 }
126
127 /**
128 * {@inheritDoc}
129 */
130 @Override
131 public Type[] getActualTypeArguments() {
132 return typeArguments.clone();
168133 }
169134
170135 /**
179144 * {@inheritDoc}
180145 */
181146 @Override
182 public Type[] getActualTypeArguments() {
183 return typeArguments.clone();
184 }
185
186 /**
187 * {@inheritDoc}
188 */
189 @Override
190 public String toString() {
191 return TypeUtils.toString(this);
192 }
193
194 /**
195 * {@inheritDoc}
196 */
197 @Override
198 public boolean equals(final Object obj) {
199 return obj == this || obj instanceof ParameterizedType && TypeUtils.equals(this, ((ParameterizedType) obj));
147 public Type getRawType() {
148 return raw;
200149 }
201150
202151 /**
212161 result |= Arrays.hashCode(typeArguments);
213162 return result;
214163 }
164
165 /**
166 * {@inheritDoc}
167 */
168 @Override
169 public String toString() {
170 return TypeUtils.toString(this);
171 }
172 }
173
174 /**
175 * {@link WildcardType} builder.
176 * @since 3.2
177 */
178 public static class WildcardTypeBuilder implements Builder<WildcardType> {
179 private Type[] upperBounds;
180
181 private Type[] lowerBounds;
182 /**
183 * Constructor
184 */
185 private WildcardTypeBuilder() {
186 }
187
188 /**
189 * {@inheritDoc}
190 */
191 @Override
192 public WildcardType build() {
193 return new WildcardTypeImpl(upperBounds, lowerBounds);
194 }
195
196 /**
197 * Specify lower bounds of the wildcard type to build.
198 * @param bounds to set
199 * @return {@code this}
200 */
201 public WildcardTypeBuilder withLowerBounds(final Type... bounds) {
202 this.lowerBounds = bounds;
203 return this;
204 }
205
206 /**
207 * Specify upper bounds of the wildcard type to build.
208 * @param bounds to set
209 * @return {@code this}
210 */
211 public WildcardTypeBuilder withUpperBounds(final Type... bounds) {
212 this.upperBounds = bounds;
213 return this;
214 }
215215 }
216216
217217 /**
236236 * {@inheritDoc}
237237 */
238238 @Override
239 public Type[] getUpperBounds() {
240 return upperBounds.clone();
239 public boolean equals(final Object obj) {
240 return obj == this || obj instanceof WildcardType && TypeUtils.equals(this, (WildcardType) obj);
241241 }
242242
243243 /**
252252 * {@inheritDoc}
253253 */
254254 @Override
255 public String toString() {
256 return TypeUtils.toString(this);
257 }
258
259 /**
260 * {@inheritDoc}
261 */
262 @Override
263 public boolean equals(final Object obj) {
264 return obj == this || obj instanceof WildcardType && TypeUtils.equals(this, (WildcardType) obj);
255 public Type[] getUpperBounds() {
256 return upperBounds.clone();
265257 }
266258
267259 /**
275267 result |= Arrays.hashCode(lowerBounds);
276268 return result;
277269 }
270
271 /**
272 * {@inheritDoc}
273 */
274 @Override
275 public String toString() {
276 return TypeUtils.toString(this);
277 }
278278 }
279279
280280 /**
284284 public static final WildcardType WILDCARD_ALL = wildcardType().withUpperBounds(Object.class).build();
285285
286286 /**
287 * <p>{@code TypeUtils} instances should NOT be constructed in standard
288 * programming. Instead, the class should be used as
289 * {@code TypeUtils.isAssignable(cls, toClass)}.</p> <p>This
290 * constructor is public to permit tools that require a JavaBean instance to
291 * operate.</p>
292 */
293 public TypeUtils() {
294 super();
295 }
296
297 /**
298 * <p>Checks if the subject type may be implicitly cast to the target type
299 * following the Java generics rules. If both types are {@link Class}
300 * objects, the method returns the result of
301 * {@link ClassUtils#isAssignable(Class, Class)}.</p>
302 *
303 * @param type the subject type to be assigned to the target type
304 * @param toType the target type
305 * @return {@code true} if {@code type} is assignable to {@code toType}.
306 */
307 public static boolean isAssignable(final Type type, final Type toType) {
308 return isAssignable(type, toType, null);
309 }
310
311 /**
312 * <p>Checks if the subject type may be implicitly cast to the target type
313 * following the Java generics rules.</p>
314 *
315 * @param type the subject type to be assigned to the target type
316 * @param toType the target type
317 * @param typeVarAssigns optional map of type variable assignments
318 * @return {@code true} if {@code type} is assignable to {@code toType}.
319 */
320 private static boolean isAssignable(final Type type, final Type toType,
321 final Map<TypeVariable<?>, Type> typeVarAssigns) {
322 if (toType == null || toType instanceof Class<?>) {
323 return isAssignable(type, (Class<?>) toType);
324 }
325
326 if (toType instanceof ParameterizedType) {
327 return isAssignable(type, (ParameterizedType) toType, typeVarAssigns);
328 }
329
330 if (toType instanceof GenericArrayType) {
331 return isAssignable(type, (GenericArrayType) toType, typeVarAssigns);
332 }
333
334 if (toType instanceof WildcardType) {
335 return isAssignable(type, (WildcardType) toType, typeVarAssigns);
336 }
337
338 if (toType instanceof TypeVariable<?>) {
339 return isAssignable(type, (TypeVariable<?>) toType, typeVarAssigns);
340 }
341
342 throw new IllegalStateException("found an unhandled type: " + toType);
343 }
344
345 /**
346 * <p>Checks if the subject type may be implicitly cast to the target class
347 * following the Java generics rules.</p>
348 *
349 * @param type the subject type to be assigned to the target type
350 * @param toClass the target class
351 * @return {@code true} if {@code type} is assignable to {@code toClass}.
352 */
353 private static boolean isAssignable(final Type type, final Class<?> toClass) {
354 if (type == null) {
355 // consistency with ClassUtils.isAssignable() behavior
356 return toClass == null || !toClass.isPrimitive();
357 }
358
359 // only a null type can be assigned to null type which
360 // would have cause the previous to return true
361 if (toClass == null) {
362 return false;
363 }
364
365 // all types are assignable to themselves
366 if (toClass.equals(type)) {
287 * Appends {@code types} to {@code builder} with separator {@code sep}.
288 *
289 * @param builder destination
290 * @param sep separator
291 * @param types to append
292 * @return {@code builder}
293 * @since 3.2
294 */
295 private static <T> StringBuilder appendAllTo(final StringBuilder builder, final String sep,
296 @SuppressWarnings("unchecked") final T... types) {
297 Validate.notEmpty(Validate.noNullElements(types));
298 if (types.length > 0) {
299 builder.append(toString(types[0]));
300 for (int i = 1; i < types.length; i++) {
301 builder.append(sep).append(toString(types[i]));
302 }
303 }
304 return builder;
305 }
306
307 private static void appendRecursiveTypes(final StringBuilder builder, final int[] recursiveTypeIndexes,
308 final Type[] argumentTypes) {
309 for (int i = 0; i < recursiveTypeIndexes.length; i++) {
310 appendAllTo(builder.append('<'), ", ", argumentTypes[i].toString()).append('>');
311 }
312
313 final Type[] argumentsFiltered = ArrayUtils.removeAll(argumentTypes, recursiveTypeIndexes);
314
315 if (argumentsFiltered.length > 0) {
316 appendAllTo(builder.append('<'), ", ", argumentsFiltered).append('>');
317 }
318 }
319
320 /**
321 * Formats a {@link Class} as a {@link String}.
322 *
323 * @param cls {@code Class} to format
324 * @return String
325 * @since 3.2
326 */
327 private static String classToString(final Class<?> cls) {
328 if (cls.isArray()) {
329 return toString(cls.getComponentType()) + "[]";
330 }
331
332 final StringBuilder buf = new StringBuilder();
333
334 if (cls.getEnclosingClass() != null) {
335 buf.append(classToString(cls.getEnclosingClass())).append('.').append(cls.getSimpleName());
336 } else {
337 buf.append(cls.getName());
338 }
339 if (cls.getTypeParameters().length > 0) {
340 buf.append('<');
341 appendAllTo(buf, ", ", cls.getTypeParameters());
342 buf.append('>');
343 }
344 return buf.toString();
345 }
346
347 /**
348 * Tests, recursively, whether any of the type parameters associated with {@code type} are bound to variables.
349 *
350 * @param type the type to check for type variables
351 * @return boolean
352 * @since 3.2
353 */
354 public static boolean containsTypeVariables(final Type type) {
355 if (type instanceof TypeVariable<?>) {
367356 return true;
368357 }
369
370358 if (type instanceof Class<?>) {
371 // just comparing two classes
372 return ClassUtils.isAssignable((Class<?>) type, toClass);
373 }
374
359 return ((Class<?>) type).getTypeParameters().length > 0;
360 }
375361 if (type instanceof ParameterizedType) {
376 // only have to compare the raw type to the class
377 return isAssignable(getRawType((ParameterizedType) type), toClass);
378 }
379
380 // *
381 if (type instanceof TypeVariable<?>) {
382 // if any of the bounds are assignable to the class, then the
383 // type is assignable to the class.
384 for (final Type bound : ((TypeVariable<?>) type).getBounds()) {
385 if (isAssignable(bound, toClass)) {
362 for (final Type arg : ((ParameterizedType) type).getActualTypeArguments()) {
363 if (containsTypeVariables(arg)) {
386364 return true;
387365 }
388366 }
389
390367 return false;
391368 }
392
393 // the only classes to which a generic array type can be assigned
394 // are class Object and array classes
369 if (type instanceof WildcardType) {
370 final WildcardType wild = (WildcardType) type;
371 return containsTypeVariables(getImplicitLowerBounds(wild)[0])
372 || containsTypeVariables(getImplicitUpperBounds(wild)[0]);
373 }
395374 if (type instanceof GenericArrayType) {
396 return toClass.equals(Object.class)
397 || toClass.isArray()
398 && isAssignable(((GenericArrayType) type).getGenericComponentType(), toClass
399 .getComponentType());
400 }
401
402 // wildcard types are not assignable to a class (though one would think
403 // "? super Object" would be assignable to Object)
375 return containsTypeVariables(((GenericArrayType) type).getGenericComponentType());
376 }
377 return false;
378 }
379
380 private static boolean containsVariableTypeSameParametrizedTypeBound(final TypeVariable<?> typeVariable,
381 final ParameterizedType parameterizedType) {
382 return ArrayUtils.contains(typeVariable.getBounds(), parameterizedType);
383 }
384
385 /**
386 * Tries to determine the type arguments of a class/interface based on a
387 * super parameterized type's type arguments. This method is the inverse of
388 * {@link #getTypeArguments(Type, Class)} which gets a class/interface's
389 * type arguments based on a subtype. It is far more limited in determining
390 * the type arguments for the subject class's type variables in that it can
391 * only determine those parameters that map from the subject {@link Class}
392 * object to the supertype.
393 *
394 * <p>
395 * Example: {@link java.util.TreeSet
396 * TreeSet} sets its parameter as the parameter for
397 * {@link java.util.NavigableSet NavigableSet}, which in turn sets the
398 * parameter of {@link java.util.SortedSet}, which in turn sets the
399 * parameter of {@link Set}, which in turn sets the parameter of
400 * {@link java.util.Collection}, which in turn sets the parameter of
401 * {@link java.lang.Iterable}. Since {@code TreeSet}'s parameter maps
402 * (indirectly) to {@code Iterable}'s parameter, it will be able to
403 * determine that based on the super type {@code Iterable<? extends
404 * Map<Integer, ? extends Collection<?>>>}, the parameter of
405 * {@code TreeSet} is {@code ? extends Map<Integer, ? extends
406 * Collection<?>>}.
407 * </p>
408 *
409 * @param cls the class whose type parameters are to be determined, not {@code null}
410 * @param superParameterizedType the super type from which {@code cls}'s type
411 * arguments are to be determined, not {@code null}
412 * @return a {@code Map} of the type assignments that could be determined
413 * for the type variables in each type in the inheritance hierarchy from
414 * {@code type} to {@code toClass} inclusive.
415 */
416 public static Map<TypeVariable<?>, Type> determineTypeArguments(final Class<?> cls,
417 final ParameterizedType superParameterizedType) {
418 Validate.notNull(cls, "cls");
419 Validate.notNull(superParameterizedType, "superParameterizedType");
420
421 final Class<?> superClass = getRawType(superParameterizedType);
422
423 // compatibility check
424 if (!isAssignable(cls, superClass)) {
425 return null;
426 }
427
428 if (cls.equals(superClass)) {
429 return getTypeArguments(superParameterizedType, superClass, null);
430 }
431
432 // get the next class in the inheritance hierarchy
433 final Type midType = getClosestParentType(cls, superClass);
434
435 // can only be a class or a parameterized type
436 if (midType instanceof Class<?>) {
437 return determineTypeArguments((Class<?>) midType, superParameterizedType);
438 }
439
440 final ParameterizedType midParameterizedType = (ParameterizedType) midType;
441 final Class<?> midClass = getRawType(midParameterizedType);
442 // get the type variables of the mid class that map to the type
443 // arguments of the super class
444 final Map<TypeVariable<?>, Type> typeVarAssigns = determineTypeArguments(midClass, superParameterizedType);
445 // map the arguments of the mid type to the class type variables
446 mapTypeVariablesToArguments(cls, midParameterizedType, typeVarAssigns);
447
448 return typeVarAssigns;
449 }
450
451 /**
452 * Tests whether {@code t} equals {@code a}.
453 *
454 * @param genericArrayType LHS
455 * @param type RHS
456 * @return boolean
457 * @since 3.2
458 */
459 private static boolean equals(final GenericArrayType genericArrayType, final Type type) {
460 return type instanceof GenericArrayType
461 && equals(genericArrayType.getGenericComponentType(), ((GenericArrayType) type).getGenericComponentType());
462 }
463
464 /**
465 * Tests whether {@code t} equals {@code p}.
466 *
467 * @param parameterizedType LHS
468 * @param type RHS
469 * @return boolean
470 * @since 3.2
471 */
472 private static boolean equals(final ParameterizedType parameterizedType, final Type type) {
473 if (type instanceof ParameterizedType) {
474 final ParameterizedType other = (ParameterizedType) type;
475 if (equals(parameterizedType.getRawType(), other.getRawType())
476 && equals(parameterizedType.getOwnerType(), other.getOwnerType())) {
477 return equals(parameterizedType.getActualTypeArguments(), other.getActualTypeArguments());
478 }
479 }
480 return false;
481 }
482
483 /**
484 * Tests equality of types.
485 *
486 * @param type1 the first type
487 * @param type2 the second type
488 * @return boolean
489 * @since 3.2
490 */
491 public static boolean equals(final Type type1, final Type type2) {
492 if (Objects.equals(type1, type2)) {
493 return true;
494 }
495 if (type1 instanceof ParameterizedType) {
496 return equals((ParameterizedType) type1, type2);
497 }
498 if (type1 instanceof GenericArrayType) {
499 return equals((GenericArrayType) type1, type2);
500 }
501 if (type1 instanceof WildcardType) {
502 return equals((WildcardType) type1, type2);
503 }
504 return false;
505 }
506
507 /**
508 * Tests whether {@code t1} equals {@code t2}.
509 *
510 * @param type1 LHS
511 * @param type2 RHS
512 * @return boolean
513 * @since 3.2
514 */
515 private static boolean equals(final Type[] type1, final Type[] type2) {
516 if (type1.length == type2.length) {
517 for (int i = 0; i < type1.length; i++) {
518 if (!equals(type1[i], type2[i])) {
519 return false;
520 }
521 }
522 return true;
523 }
524 return false;
525 }
526
527 /**
528 * Tests whether {@code t} equals {@code w}.
529 *
530 * @param wildcardType LHS
531 * @param type RHS
532 * @return boolean
533 * @since 3.2
534 */
535 private static boolean equals(final WildcardType wildcardType, final Type type) {
404536 if (type instanceof WildcardType) {
405 return false;
406 }
407
408 throw new IllegalStateException("found an unhandled type: " + type);
409 }
410
411 /**
412 * <p>Checks if the subject type may be implicitly cast to the target
413 * parameterized type following the Java generics rules.</p>
414 *
415 * @param type the subject type to be assigned to the target type
416 * @param toParameterizedType the target parameterized type
417 * @param typeVarAssigns a map with type variables
418 * @return {@code true} if {@code type} is assignable to {@code toType}.
419 */
420 private static boolean isAssignable(final Type type, final ParameterizedType toParameterizedType,
421 final Map<TypeVariable<?>, Type> typeVarAssigns) {
422 if (type == null) {
423 return true;
424 }
425
426 // only a null type can be assigned to null type which
427 // would have cause the previous to return true
428 if (toParameterizedType == null) {
429 return false;
430 }
431
432 // all types are assignable to themselves
433 if (toParameterizedType.equals(type)) {
434 return true;
435 }
436
437 // get the target type's raw type
438 final Class<?> toClass = getRawType(toParameterizedType);
439 // get the subject type's type arguments including owner type arguments
440 // and supertype arguments up to and including the target class.
441 final Map<TypeVariable<?>, Type> fromTypeVarAssigns = getTypeArguments(type, toClass, null);
442
443 // null means the two types are not compatible
444 if (fromTypeVarAssigns == null) {
445 return false;
446 }
447
448 // compatible types, but there's no type arguments. this is equivalent
449 // to comparing Map< ?, ? > to Map, and raw types are always assignable
450 // to parameterized types.
451 if (fromTypeVarAssigns.isEmpty()) {
452 return true;
453 }
454
455 // get the target type's type arguments including owner type arguments
456 final Map<TypeVariable<?>, Type> toTypeVarAssigns = getTypeArguments(toParameterizedType,
457 toClass, typeVarAssigns);
458
459 // now to check each type argument
460 for (final TypeVariable<?> var : toTypeVarAssigns.keySet()) {
461 final Type toTypeArg = unrollVariableAssignments(var, toTypeVarAssigns);
462 final Type fromTypeArg = unrollVariableAssignments(var, fromTypeVarAssigns);
463
464 if (toTypeArg == null && fromTypeArg instanceof Class) {
465 continue;
466 }
467
468 // parameters must either be absent from the subject type, within
469 // the bounds of the wildcard type, or be an exact match to the
470 // parameters of the target type.
471 if (fromTypeArg != null
472 && !toTypeArg.equals(fromTypeArg)
473 && !(toTypeArg instanceof WildcardType && isAssignable(fromTypeArg, toTypeArg,
474 typeVarAssigns))) {
475 return false;
476 }
477 }
478 return true;
479 }
480
481 /**
482 * Look up {@code var} in {@code typeVarAssigns} <em>transitively</em>,
483 * i.e. keep looking until the value found is <em>not</em> a type variable.
484 * @param typeVariable the type variable to look up
485 * @param typeVarAssigns the map used for the look up
486 * @return Type or {@code null} if some variable was not in the map
487 * @since 3.2
488 */
489 private static Type unrollVariableAssignments(TypeVariable<?> typeVariable,
490 final Map<TypeVariable<?>, Type> typeVarAssigns) {
491 Type result;
492 do {
493 result = typeVarAssigns.get(typeVariable);
494 if (result instanceof TypeVariable<?> && !result.equals(typeVariable)) {
495 typeVariable = (TypeVariable<?>) result;
496 continue;
497 }
498 break;
499 } while (true);
537 final WildcardType other = (WildcardType) type;
538 return equals(getImplicitLowerBounds(wildcardType), getImplicitLowerBounds(other))
539 && equals(getImplicitUpperBounds(wildcardType), getImplicitUpperBounds(other));
540 }
541 return false;
542 }
543
544 /**
545 * Helper method to establish the formal parameters for a parameterized type.
546 *
547 * @param mappings map containing the assignments
548 * @param variables expected map keys
549 * @return array of map values corresponding to specified keys
550 */
551 private static Type[] extractTypeArgumentsFrom(final Map<TypeVariable<?>, Type> mappings, final TypeVariable<?>[] variables) {
552 final Type[] result = new Type[variables.length];
553 int index = 0;
554 for (final TypeVariable<?> var : variables) {
555 Validate.isTrue(mappings.containsKey(var), "missing argument mapping for %s", toString(var));
556 result[index++] = mappings.get(var);
557 }
500558 return result;
501559 }
502560
503 /**
504 * <p>Checks if the subject type may be implicitly cast to the target
505 * generic array type following the Java generics rules.</p>
506 *
507 * @param type the subject type to be assigned to the target type
508 * @param toGenericArrayType the target generic array type
509 * @param typeVarAssigns a map with type variables
510 * @return {@code true} if {@code type} is assignable to
511 * {@code toGenericArrayType}.
512 */
513 private static boolean isAssignable(final Type type, final GenericArrayType toGenericArrayType,
514 final Map<TypeVariable<?>, Type> typeVarAssigns) {
515 if (type == null) {
516 return true;
517 }
518
519 // only a null type can be assigned to null type which
520 // would have cause the previous to return true
521 if (toGenericArrayType == null) {
522 return false;
523 }
524
525 // all types are assignable to themselves
526 if (toGenericArrayType.equals(type)) {
527 return true;
528 }
529
530 final Type toComponentType = toGenericArrayType.getGenericComponentType();
531
561 private static int[] findRecursiveTypes(final ParameterizedType parameterizedType) {
562 final Type[] filteredArgumentTypes = Arrays.copyOf(parameterizedType.getActualTypeArguments(),
563 parameterizedType.getActualTypeArguments().length);
564 int[] indexesToRemove = {};
565 for (int i = 0; i < filteredArgumentTypes.length; i++) {
566 if ((filteredArgumentTypes[i] instanceof TypeVariable<?>) && containsVariableTypeSameParametrizedTypeBound(
567 ((TypeVariable<?>) filteredArgumentTypes[i]), parameterizedType)) {
568 indexesToRemove = ArrayUtils.add(indexesToRemove, i);
569 }
570 }
571 return indexesToRemove;
572 }
573
574 /**
575 * Creates a generic array type instance.
576 *
577 * @param componentType the type of the elements of the array. For example the component type of {@code boolean[]}
578 * is {@code boolean}
579 * @return {@link GenericArrayType}
580 * @since 3.2
581 */
582 public static GenericArrayType genericArrayType(final Type componentType) {
583 return new GenericArrayTypeImpl(Validate.notNull(componentType, "componentType"));
584 }
585
586 /**
587 * Formats a {@link GenericArrayType} as a {@link String}.
588 *
589 * @param genericArrayType {@code GenericArrayType} to format
590 * @return String
591 * @since 3.2
592 */
593 private static String genericArrayTypeToString(final GenericArrayType genericArrayType) {
594 return String.format("%s[]", toString(genericArrayType.getGenericComponentType()));
595 }
596
597 /**
598 * Gets the array component type of {@code type}.
599 *
600 * @param type the type to be checked
601 * @return component type or null if type is not an array type
602 */
603 public static Type getArrayComponentType(final Type type) {
532604 if (type instanceof Class<?>) {
533605 final Class<?> cls = (Class<?>) type;
534
535 // compare the component types
536 return cls.isArray()
537 && isAssignable(cls.getComponentType(), toComponentType, typeVarAssigns);
538 }
539
606 return cls.isArray() ? cls.getComponentType() : null;
607 }
540608 if (type instanceof GenericArrayType) {
541 // compare the component types
542 return isAssignable(((GenericArrayType) type).getGenericComponentType(),
543 toComponentType, typeVarAssigns);
544 }
545
609 return ((GenericArrayType) type).getGenericComponentType();
610 }
611 return null;
612 }
613
614 /**
615 * Gets the closest parent type to the
616 * super class specified by {@code superClass}.
617 *
618 * @param cls the class in question
619 * @param superClass the super class
620 * @return the closes parent type
621 */
622 private static Type getClosestParentType(final Class<?> cls, final Class<?> superClass) {
623 // only look at the interfaces if the super class is also an interface
624 if (superClass.isInterface()) {
625 // get the generic interfaces of the subject class
626 final Type[] interfaceTypes = cls.getGenericInterfaces();
627 // will hold the best generic interface match found
628 Type genericInterface = null;
629
630 // find the interface closest to the super class
631 for (final Type midType : interfaceTypes) {
632 Class<?> midClass = null;
633
634 if (midType instanceof ParameterizedType) {
635 midClass = getRawType((ParameterizedType) midType);
636 } else if (midType instanceof Class<?>) {
637 midClass = (Class<?>) midType;
638 } else {
639 throw new IllegalStateException("Unexpected generic"
640 + " interface type found: " + midType);
641 }
642
643 // check if this interface is further up the inheritance chain
644 // than the previously found match
645 if (isAssignable(midClass, superClass)
646 && isAssignable(genericInterface, (Type) midClass)) {
647 genericInterface = midType;
648 }
649 }
650
651 // found a match?
652 if (genericInterface != null) {
653 return genericInterface;
654 }
655 }
656
657 // none of the interfaces were descendants of the target class, so the
658 // super class has to be one, instead
659 return cls.getGenericSuperclass();
660 }
661
662 /**
663 * Gets an array containing the sole type of {@link Object} if
664 * {@link TypeVariable#getBounds()} returns an empty array. Otherwise, it
665 * returns the result of {@link TypeVariable#getBounds()} passed into
666 * {@link #normalizeUpperBounds}.
667 *
668 * @param typeVariable the subject type variable, not {@code null}
669 * @return a non-empty array containing the bounds of the type variable.
670 */
671 public static Type[] getImplicitBounds(final TypeVariable<?> typeVariable) {
672 Validate.notNull(typeVariable, "typeVariable");
673 final Type[] bounds = typeVariable.getBounds();
674
675 return bounds.length == 0 ? new Type[] { Object.class } : normalizeUpperBounds(bounds);
676 }
677
678 /**
679 * Gets an array containing a single value of {@code null} if
680 * {@link WildcardType#getLowerBounds()} returns an empty array. Otherwise,
681 * it returns the result of {@link WildcardType#getLowerBounds()}.
682 *
683 * @param wildcardType the subject wildcard type, not {@code null}
684 * @return a non-empty array containing the lower bounds of the wildcard
685 * type.
686 */
687 public static Type[] getImplicitLowerBounds(final WildcardType wildcardType) {
688 Validate.notNull(wildcardType, "wildcardType");
689 final Type[] bounds = wildcardType.getLowerBounds();
690
691 return bounds.length == 0 ? new Type[] { null } : bounds;
692 }
693
694 /**
695 * Gets an array containing the sole value of {@link Object} if
696 * {@link WildcardType#getUpperBounds()} returns an empty array. Otherwise,
697 * it returns the result of {@link WildcardType#getUpperBounds()}
698 * passed into {@link #normalizeUpperBounds}.
699 *
700 * @param wildcardType the subject wildcard type, not {@code null}
701 * @return a non-empty array containing the upper bounds of the wildcard
702 * type.
703 */
704 public static Type[] getImplicitUpperBounds(final WildcardType wildcardType) {
705 Validate.notNull(wildcardType, "wildcardType");
706 final Type[] bounds = wildcardType.getUpperBounds();
707
708 return bounds.length == 0 ? new Type[] { Object.class } : normalizeUpperBounds(bounds);
709 }
710
711 /**
712 * Transforms the passed in type to a {@link Class} object. Type-checking method of convenience.
713 *
714 * @param parameterizedType the type to be converted
715 * @return the corresponding {@code Class} object
716 * @throws IllegalStateException if the conversion fails
717 */
718 private static Class<?> getRawType(final ParameterizedType parameterizedType) {
719 final Type rawType = parameterizedType.getRawType();
720
721 // check if raw type is a Class object
722 // not currently necessary, but since the return type is Type instead of
723 // Class, there's enough reason to believe that future versions of Java
724 // may return other Type implementations. And type-safety checking is
725 // rarely a bad idea.
726 if (!(rawType instanceof Class<?>)) {
727 throw new IllegalStateException("Wait... What!? Type of rawType: " + rawType);
728 }
729
730 return (Class<?>) rawType;
731 }
732
733 /**
734 * Gets the raw type of a Java type, given its context. Primarily for use
735 * with {@link TypeVariable}s and {@link GenericArrayType}s, or when you do
736 * not know the runtime type of {@code type}: if you know you have a
737 * {@link Class} instance, it is already raw; if you know you have a
738 * {@link ParameterizedType}, its raw type is only a method call away.
739 *
740 * @param type to resolve
741 * @param assigningType type to be resolved against
742 * @return the resolved {@link Class} object or {@code null} if
743 * the type could not be resolved
744 */
745 public static Class<?> getRawType(final Type type, final Type assigningType) {
746 if (type instanceof Class<?>) {
747 // it is raw, no problem
748 return (Class<?>) type;
749 }
750
751 if (type instanceof ParameterizedType) {
752 // simple enough to get the raw type of a ParameterizedType
753 return getRawType((ParameterizedType) type);
754 }
755
756 if (type instanceof TypeVariable<?>) {
757 if (assigningType == null) {
758 return null;
759 }
760
761 // get the entity declaring this type variable
762 final Object genericDeclaration = ((TypeVariable<?>) type).getGenericDeclaration();
763
764 // can't get the raw type of a method- or constructor-declared type
765 // variable
766 if (!(genericDeclaration instanceof Class<?>)) {
767 return null;
768 }
769
770 // get the type arguments for the declaring class/interface based
771 // on the enclosing type
772 final Map<TypeVariable<?>, Type> typeVarAssigns = getTypeArguments(assigningType,
773 (Class<?>) genericDeclaration);
774
775 // enclosingType has to be a subclass (or subinterface) of the
776 // declaring type
777 if (typeVarAssigns == null) {
778 return null;
779 }
780
781 // get the argument assigned to this type variable
782 final Type typeArgument = typeVarAssigns.get(type);
783
784 if (typeArgument == null) {
785 return null;
786 }
787
788 // get the argument for this type variable
789 return getRawType(typeArgument, assigningType);
790 }
791
792 if (type instanceof GenericArrayType) {
793 // get raw component type
794 final Class<?> rawComponentType = getRawType(((GenericArrayType) type)
795 .getGenericComponentType(), assigningType);
796
797 // create array type from raw component type and return its class
798 return Array.newInstance(rawComponentType, 0).getClass();
799 }
800
801 // (hand-waving) this is not the method you're looking for
546802 if (type instanceof WildcardType) {
547 // so long as one of the upper bounds is assignable, it's good
548 for (final Type bound : getImplicitUpperBounds((WildcardType) type)) {
549 if (isAssignable(bound, toGenericArrayType)) {
550 return true;
551 }
552 }
553
554 return false;
555 }
556
557 if (type instanceof TypeVariable<?>) {
558 // probably should remove the following logic and just return false.
559 // type variables cannot specify arrays as bounds.
560 for (final Type bound : getImplicitBounds((TypeVariable<?>) type)) {
561 if (isAssignable(bound, toGenericArrayType)) {
562 return true;
563 }
564 }
565
566 return false;
567 }
568
569 if (type instanceof ParameterizedType) {
570 // the raw type of a parameterized type is never an array or
571 // generic array, otherwise the declaration would look like this:
572 // Collection[]< ? extends String > collection;
573 return false;
574 }
575
576 throw new IllegalStateException("found an unhandled type: " + type);
577 }
578
579 /**
580 * <p>Checks if the subject type may be implicitly cast to the target
581 * wildcard type following the Java generics rules.</p>
582 *
583 * @param type the subject type to be assigned to the target type
584 * @param toWildcardType the target wildcard type
585 * @param typeVarAssigns a map with type variables
586 * @return {@code true} if {@code type} is assignable to
587 * {@code toWildcardType}.
588 */
589 private static boolean isAssignable(final Type type, final WildcardType toWildcardType,
590 final Map<TypeVariable<?>, Type> typeVarAssigns) {
591 if (type == null) {
592 return true;
593 }
594
595 // only a null type can be assigned to null type which
596 // would have cause the previous to return true
597 if (toWildcardType == null) {
598 return false;
599 }
600
601 // all types are assignable to themselves
602 if (toWildcardType.equals(type)) {
603 return true;
604 }
605
606 final Type[] toUpperBounds = getImplicitUpperBounds(toWildcardType);
607 final Type[] toLowerBounds = getImplicitLowerBounds(toWildcardType);
608
609 if (type instanceof WildcardType) {
610 final WildcardType wildcardType = (WildcardType) type;
611 final Type[] upperBounds = getImplicitUpperBounds(wildcardType);
612 final Type[] lowerBounds = getImplicitLowerBounds(wildcardType);
613
614 for (Type toBound : toUpperBounds) {
615 // if there are assignments for unresolved type variables,
616 // now's the time to substitute them.
617 toBound = substituteTypeVariables(toBound, typeVarAssigns);
618
619 // each upper bound of the subject type has to be assignable to
620 // each
621 // upper bound of the target type
622 for (final Type bound : upperBounds) {
623 if (!isAssignable(bound, toBound, typeVarAssigns)) {
624 return false;
625 }
626 }
627 }
628
629 for (Type toBound : toLowerBounds) {
630 // if there are assignments for unresolved type variables,
631 // now's the time to substitute them.
632 toBound = substituteTypeVariables(toBound, typeVarAssigns);
633
634 // each lower bound of the target type has to be assignable to
635 // each
636 // lower bound of the subject type
637 for (final Type bound : lowerBounds) {
638 if (!isAssignable(toBound, bound, typeVarAssigns)) {
639 return false;
640 }
641 }
642 }
643 return true;
644 }
645
646 for (final Type toBound : toUpperBounds) {
647 // if there are assignments for unresolved type variables,
648 // now's the time to substitute them.
649 if (!isAssignable(type, substituteTypeVariables(toBound, typeVarAssigns),
650 typeVarAssigns)) {
651 return false;
652 }
653 }
654
655 for (final Type toBound : toLowerBounds) {
656 // if there are assignments for unresolved type variables,
657 // now's the time to substitute them.
658 if (!isAssignable(substituteTypeVariables(toBound, typeVarAssigns), type,
659 typeVarAssigns)) {
660 return false;
661 }
662 }
663 return true;
664 }
665
666 /**
667 * <p>Checks if the subject type may be implicitly cast to the target type
668 * variable following the Java generics rules.</p>
669 *
670 * @param type the subject type to be assigned to the target type
671 * @param toTypeVariable the target type variable
672 * @param typeVarAssigns a map with type variables
673 * @return {@code true} if {@code type} is assignable to
674 * {@code toTypeVariable}.
675 */
676 private static boolean isAssignable(final Type type, final TypeVariable<?> toTypeVariable,
677 final Map<TypeVariable<?>, Type> typeVarAssigns) {
678 if (type == null) {
679 return true;
680 }
681
682 // only a null type can be assigned to null type which
683 // would have cause the previous to return true
684 if (toTypeVariable == null) {
685 return false;
686 }
687
688 // all types are assignable to themselves
689 if (toTypeVariable.equals(type)) {
690 return true;
691 }
692
693 if (type instanceof TypeVariable<?>) {
694 // a type variable is assignable to another type variable, if
695 // and only if the former is the latter, extends the latter, or
696 // is otherwise a descendant of the latter.
697 final Type[] bounds = getImplicitBounds((TypeVariable<?>) type);
698
699 for (final Type bound : bounds) {
700 if (isAssignable(bound, toTypeVariable, typeVarAssigns)) {
701 return true;
702 }
703 }
704 }
705
706 if (type instanceof Class<?> || type instanceof ParameterizedType
707 || type instanceof GenericArrayType || type instanceof WildcardType) {
708 return false;
709 }
710
711 throw new IllegalStateException("found an unhandled type: " + type);
712 }
713
714 /**
715 * <p>Find the mapping for {@code type} in {@code typeVarAssigns}.</p>
716 *
717 * @param type the type to be replaced
718 * @param typeVarAssigns the map with type variables
719 * @return the replaced type
720 * @throws IllegalArgumentException if the type cannot be substituted
721 */
722 private static Type substituteTypeVariables(final Type type, final Map<TypeVariable<?>, Type> typeVarAssigns) {
723 if (type instanceof TypeVariable<?> && typeVarAssigns != null) {
724 final Type replacementType = typeVarAssigns.get(type);
725
726 if (replacementType == null) {
727 throw new IllegalArgumentException("missing assignment type for type variable "
728 + type);
729 }
730 return replacementType;
731 }
732 return type;
733 }
734
735 /**
736 * <p>Retrieves all the type arguments for this parameterized type
803 return null;
804 }
805
806 throw new IllegalArgumentException("unknown type: " + type);
807 }
808
809 /**
810 * Gets a map of the type arguments of a class in the context of {@code toClass}.
811 *
812 * @param cls the class in question
813 * @param toClass the context class
814 * @param subtypeVarAssigns a map with type variables
815 * @return the {@code Map} with type arguments
816 */
817 private static Map<TypeVariable<?>, Type> getTypeArguments(Class<?> cls, final Class<?> toClass,
818 final Map<TypeVariable<?>, Type> subtypeVarAssigns) {
819 // make sure they're assignable
820 if (!isAssignable(cls, toClass)) {
821 return null;
822 }
823
824 // can't work with primitives
825 if (cls.isPrimitive()) {
826 // both classes are primitives?
827 if (toClass.isPrimitive()) {
828 // dealing with widening here. No type arguments to be
829 // harvested with these two types.
830 return new HashMap<>();
831 }
832
833 // work with wrapper the wrapper class instead of the primitive
834 cls = ClassUtils.primitiveToWrapper(cls);
835 }
836
837 // create a copy of the incoming map, or an empty one if it's null
838 final HashMap<TypeVariable<?>, Type> typeVarAssigns = subtypeVarAssigns == null ? new HashMap<>()
839 : new HashMap<>(subtypeVarAssigns);
840
841 // has target class been reached?
842 if (toClass.equals(cls)) {
843 return typeVarAssigns;
844 }
845
846 // walk the inheritance hierarchy until the target class is reached
847 return getTypeArguments(getClosestParentType(cls, toClass), toClass, typeVarAssigns);
848 }
849
850 /**
851 * Gets all the type arguments for this parameterized type
737852 * including owner hierarchy arguments such as
738853 * {@code Outer<K, V>.Inner<T>.DeepInner<E>} .
739854 * The arguments are returned in a
740855 * {@link Map} specifying the argument type for each {@link TypeVariable}.
741 * </p>
742856 *
743857 * @param type specifies the subject parameterized type from which to
744858 * harvest the parameters.
750864 }
751865
752866 /**
753 * <p>Gets the type arguments of a class/interface based on a subtype. For
867 * Gets a map of the type arguments of a parameterized type in the context of {@code toClass}.
868 *
869 * @param parameterizedType the parameterized type
870 * @param toClass the class
871 * @param subtypeVarAssigns a map with type variables
872 * @return the {@code Map} with type arguments
873 */
874 private static Map<TypeVariable<?>, Type> getTypeArguments(
875 final ParameterizedType parameterizedType, final Class<?> toClass,
876 final Map<TypeVariable<?>, Type> subtypeVarAssigns) {
877 final Class<?> cls = getRawType(parameterizedType);
878
879 // make sure they're assignable
880 if (!isAssignable(cls, toClass)) {
881 return null;
882 }
883
884 final Type ownerType = parameterizedType.getOwnerType();
885 final Map<TypeVariable<?>, Type> typeVarAssigns;
886
887 if (ownerType instanceof ParameterizedType) {
888 // get the owner type arguments first
889 final ParameterizedType parameterizedOwnerType = (ParameterizedType) ownerType;
890 typeVarAssigns = getTypeArguments(parameterizedOwnerType,
891 getRawType(parameterizedOwnerType), subtypeVarAssigns);
892 } else {
893 // no owner, prep the type variable assignments map
894 typeVarAssigns = subtypeVarAssigns == null ? new HashMap<>()
895 : new HashMap<>(subtypeVarAssigns);
896 }
897
898 // get the subject parameterized type's arguments
899 final Type[] typeArgs = parameterizedType.getActualTypeArguments();
900 // and get the corresponding type variables from the raw class
901 final TypeVariable<?>[] typeParams = cls.getTypeParameters();
902
903 // map the arguments to their respective type variables
904 for (int i = 0; i < typeParams.length; i++) {
905 final Type typeArg = typeArgs[i];
906 typeVarAssigns.put(
907 typeParams[i],
908 typeVarAssigns.getOrDefault(typeArg, typeArg)
909 );
910 }
911
912 if (toClass.equals(cls)) {
913 // target class has been reached. Done.
914 return typeVarAssigns;
915 }
916
917 // walk the inheritance hierarchy until the target class is reached
918 return getTypeArguments(getClosestParentType(cls, toClass), toClass, typeVarAssigns);
919 }
920
921 /**
922 * Gets the type arguments of a class/interface based on a subtype. For
754923 * instance, this method will determine that both of the parameters for the
755924 * interface {@link Map} are {@link Object} for the subtype
756925 * {@link java.util.Properties Properties} even though the subtype does not
757 * directly implement the {@code Map} interface.</p>
758 * <p>This method returns {@code null} if {@code type} is not assignable to
926 * directly implement the {@code Map} interface.
927 *
928 * <p>
929 * This method returns {@code null} if {@code type} is not assignable to
759930 * {@code toClass}. It returns an empty map if none of the classes or
760 * interfaces in its inheritance hierarchy specify any type arguments.</p>
761 * <p>A side effect of this method is that it also retrieves the type
931 * interfaces in its inheritance hierarchy specify any type arguments.
932 * </p>
933 *
934 * <p>
935 * A side effect of this method is that it also retrieves the type
762936 * arguments for the classes and interfaces that are part of the hierarchy
763937 * between {@code type} and {@code toClass}. So with the above
764938 * example, this method will also determine that the type arguments for
771945 * this method will look at the inheritance hierarchy of only one of the
772946 * implementations/subclasses; the first interface encountered that isn't a
773947 * subinterface to one of the others in the {@code type} to
774 * {@code toClass} hierarchy.</p>
948 * {@code toClass} hierarchy.
949 * </p>
775950 *
776951 * @param type the type from which to determine the type parameters of
777952 * {@code toClass}
786961 }
787962
788963 /**
789 * <p>Return a map of the type arguments of {@code type} in the context of {@code toClass}.</p>
964 * Gets a map of the type arguments of {@code type} in the context of {@code toClass}.
790965 *
791966 * @param type the type in question
792967 * @param toClass the class
8351010 }
8361011
8371012 /**
838 * <p>Return a map of the type arguments of a parameterized type in the context of {@code toClass}.</p>
839 *
840 * @param parameterizedType the parameterized type
841 * @param toClass the class
842 * @param subtypeVarAssigns a map with type variables
843 * @return the {@code Map} with type arguments
844 */
845 private static Map<TypeVariable<?>, Type> getTypeArguments(
846 final ParameterizedType parameterizedType, final Class<?> toClass,
847 final Map<TypeVariable<?>, Type> subtypeVarAssigns) {
848 final Class<?> cls = getRawType(parameterizedType);
849
850 // make sure they're assignable
851 if (!isAssignable(cls, toClass)) {
852 return null;
853 }
854
855 final Type ownerType = parameterizedType.getOwnerType();
856 Map<TypeVariable<?>, Type> typeVarAssigns;
857
858 if (ownerType instanceof ParameterizedType) {
859 // get the owner type arguments first
860 final ParameterizedType parameterizedOwnerType = (ParameterizedType) ownerType;
861 typeVarAssigns = getTypeArguments(parameterizedOwnerType,
862 getRawType(parameterizedOwnerType), subtypeVarAssigns);
863 } else {
864 // no owner, prep the type variable assignments map
865 typeVarAssigns = subtypeVarAssigns == null ? new HashMap<>()
866 : new HashMap<>(subtypeVarAssigns);
867 }
868
869 // get the subject parameterized type's arguments
870 final Type[] typeArgs = parameterizedType.getActualTypeArguments();
871 // and get the corresponding type variables from the raw class
872 final TypeVariable<?>[] typeParams = cls.getTypeParameters();
873
874 // map the arguments to their respective type variables
875 for (int i = 0; i < typeParams.length; i++) {
876 final Type typeArg = typeArgs[i];
877 typeVarAssigns.put(
878 typeParams[i],
879 typeVarAssigns.getOrDefault(typeArg, typeArg)
880 );
881 }
882
883 if (toClass.equals(cls)) {
884 // target class has been reached. Done.
885 return typeVarAssigns;
886 }
887
888 // walk the inheritance hierarchy until the target class is reached
889 return getTypeArguments(getClosestParentType(cls, toClass), toClass, typeVarAssigns);
890 }
891
892 /**
893 * <p>Return a map of the type arguments of a class in the context of {@code toClass}.</p>
894 *
895 * @param cls the class in question
896 * @param toClass the context class
897 * @param subtypeVarAssigns a map with type variables
898 * @return the {@code Map} with type arguments
899 */
900 private static Map<TypeVariable<?>, Type> getTypeArguments(Class<?> cls, final Class<?> toClass,
901 final Map<TypeVariable<?>, Type> subtypeVarAssigns) {
902 // make sure they're assignable
903 if (!isAssignable(cls, toClass)) {
904 return null;
905 }
906
907 // can't work with primitives
908 if (cls.isPrimitive()) {
909 // both classes are primitives?
910 if (toClass.isPrimitive()) {
911 // dealing with widening here. No type arguments to be
912 // harvested with these two types.
913 return new HashMap<>();
914 }
915
916 // work with wrapper the wrapper class instead of the primitive
917 cls = ClassUtils.primitiveToWrapper(cls);
918 }
919
920 // create a copy of the incoming map, or an empty one if it's null
921 final HashMap<TypeVariable<?>, Type> typeVarAssigns = subtypeVarAssigns == null ? new HashMap<>()
922 : new HashMap<>(subtypeVarAssigns);
923
924 // has target class been reached?
925 if (toClass.equals(cls)) {
926 return typeVarAssigns;
927 }
928
929 // walk the inheritance hierarchy until the target class is reached
930 return getTypeArguments(getClosestParentType(cls, toClass), toClass, typeVarAssigns);
931 }
932
933 /**
934 * <p>Tries to determine the type arguments of a class/interface based on a
935 * super parameterized type's type arguments. This method is the inverse of
936 * {@link #getTypeArguments(Type, Class)} which gets a class/interface's
937 * type arguments based on a subtype. It is far more limited in determining
938 * the type arguments for the subject class's type variables in that it can
939 * only determine those parameters that map from the subject {@link Class}
940 * object to the supertype.</p> <p>Example: {@link java.util.TreeSet
941 * TreeSet} sets its parameter as the parameter for
942 * {@link java.util.NavigableSet NavigableSet}, which in turn sets the
943 * parameter of {@link java.util.SortedSet}, which in turn sets the
944 * parameter of {@link Set}, which in turn sets the parameter of
945 * {@link java.util.Collection}, which in turn sets the parameter of
946 * {@link java.lang.Iterable}. Since {@code TreeSet}'s parameter maps
947 * (indirectly) to {@code Iterable}'s parameter, it will be able to
948 * determine that based on the super type {@code Iterable<? extends
949 * Map<Integer, ? extends Collection<?>>>}, the parameter of
950 * {@code TreeSet} is {@code ? extends Map<Integer, ? extends
951 * Collection<?>>}.</p>
952 *
953 * @param cls the class whose type parameters are to be determined, not {@code null}
954 * @param superType the super type from which {@code cls}'s type
955 * arguments are to be determined, not {@code null}
956 * @return a {@code Map} of the type assignments that could be determined
957 * for the type variables in each type in the inheritance hierarchy from
958 * {@code type} to {@code toClass} inclusive.
959 */
960 public static Map<TypeVariable<?>, Type> determineTypeArguments(final Class<?> cls,
961 final ParameterizedType superType) {
962 Validate.notNull(cls, "cls is null");
963 Validate.notNull(superType, "superType is null");
964
965 final Class<?> superClass = getRawType(superType);
966
967 // compatibility check
968 if (!isAssignable(cls, superClass)) {
969 return null;
970 }
971
972 if (cls.equals(superClass)) {
973 return getTypeArguments(superType, superClass, null);
974 }
975
976 // get the next class in the inheritance hierarchy
977 final Type midType = getClosestParentType(cls, superClass);
978
979 // can only be a class or a parameterized type
980 if (midType instanceof Class<?>) {
981 return determineTypeArguments((Class<?>) midType, superType);
982 }
983
984 final ParameterizedType midParameterizedType = (ParameterizedType) midType;
985 final Class<?> midClass = getRawType(midParameterizedType);
986 // get the type variables of the mid class that map to the type
987 // arguments of the super class
988 final Map<TypeVariable<?>, Type> typeVarAssigns = determineTypeArguments(midClass, superType);
989 // map the arguments of the mid type to the class type variables
990 mapTypeVariablesToArguments(cls, midParameterizedType, typeVarAssigns);
991
992 return typeVarAssigns;
993 }
994
995 /**
996 * <p>Performs a mapping of type variables.</p>
1013 * Tests whether the specified type denotes an array type.
1014 *
1015 * @param type the type to be checked
1016 * @return {@code true} if {@code type} is an array class or a {@link GenericArrayType}.
1017 */
1018 public static boolean isArrayType(final Type type) {
1019 return type instanceof GenericArrayType || type instanceof Class<?> && ((Class<?>) type).isArray();
1020 }
1021
1022 /**
1023 * Tests if the subject type may be implicitly cast to the target class
1024 * following the Java generics rules.
1025 *
1026 * @param type the subject type to be assigned to the target type
1027 * @param toClass the target class
1028 * @return {@code true} if {@code type} is assignable to {@code toClass}.
1029 */
1030 private static boolean isAssignable(final Type type, final Class<?> toClass) {
1031 if (type == null) {
1032 // consistency with ClassUtils.isAssignable() behavior
1033 return toClass == null || !toClass.isPrimitive();
1034 }
1035
1036 // only a null type can be assigned to null type which
1037 // would have cause the previous to return true
1038 if (toClass == null) {
1039 return false;
1040 }
1041
1042 // all types are assignable to themselves
1043 if (toClass.equals(type)) {
1044 return true;
1045 }
1046
1047 if (type instanceof Class<?>) {
1048 // just comparing two classes
1049 return ClassUtils.isAssignable((Class<?>) type, toClass);
1050 }
1051
1052 if (type instanceof ParameterizedType) {
1053 // only have to compare the raw type to the class
1054 return isAssignable(getRawType((ParameterizedType) type), toClass);
1055 }
1056
1057 // *
1058 if (type instanceof TypeVariable<?>) {
1059 // if any of the bounds are assignable to the class, then the
1060 // type is assignable to the class.
1061 for (final Type bound : ((TypeVariable<?>) type).getBounds()) {
1062 if (isAssignable(bound, toClass)) {
1063 return true;
1064 }
1065 }
1066
1067 return false;
1068 }
1069
1070 // the only classes to which a generic array type can be assigned
1071 // are class Object and array classes
1072 if (type instanceof GenericArrayType) {
1073 return toClass.equals(Object.class)
1074 || toClass.isArray()
1075 && isAssignable(((GenericArrayType) type).getGenericComponentType(), toClass
1076 .getComponentType());
1077 }
1078
1079 // wildcard types are not assignable to a class (though one would think
1080 // "? super Object" would be assignable to Object)
1081 if (type instanceof WildcardType) {
1082 return false;
1083 }
1084
1085 throw new IllegalStateException("found an unhandled type: " + type);
1086 }
1087
1088 /**
1089 * Tests if the subject type may be implicitly cast to the target
1090 * generic array type following the Java generics rules.
1091 *
1092 * @param type the subject type to be assigned to the target type
1093 * @param toGenericArrayType the target generic array type
1094 * @param typeVarAssigns a map with type variables
1095 * @return {@code true} if {@code type} is assignable to
1096 * {@code toGenericArrayType}.
1097 */
1098 private static boolean isAssignable(final Type type, final GenericArrayType toGenericArrayType,
1099 final Map<TypeVariable<?>, Type> typeVarAssigns) {
1100 if (type == null) {
1101 return true;
1102 }
1103
1104 // only a null type can be assigned to null type which
1105 // would have cause the previous to return true
1106 if (toGenericArrayType == null) {
1107 return false;
1108 }
1109
1110 // all types are assignable to themselves
1111 if (toGenericArrayType.equals(type)) {
1112 return true;
1113 }
1114
1115 final Type toComponentType = toGenericArrayType.getGenericComponentType();
1116
1117 if (type instanceof Class<?>) {
1118 final Class<?> cls = (Class<?>) type;
1119
1120 // compare the component types
1121 return cls.isArray()
1122 && isAssignable(cls.getComponentType(), toComponentType, typeVarAssigns);
1123 }
1124
1125 if (type instanceof GenericArrayType) {
1126 // compare the component types
1127 return isAssignable(((GenericArrayType) type).getGenericComponentType(),
1128 toComponentType, typeVarAssigns);
1129 }
1130
1131 if (type instanceof WildcardType) {
1132 // so long as one of the upper bounds is assignable, it's good
1133 for (final Type bound : getImplicitUpperBounds((WildcardType) type)) {
1134 if (isAssignable(bound, toGenericArrayType)) {
1135 return true;
1136 }
1137 }
1138
1139 return false;
1140 }
1141
1142 if (type instanceof TypeVariable<?>) {
1143 // probably should remove the following logic and just return false.
1144 // type variables cannot specify arrays as bounds.
1145 for (final Type bound : getImplicitBounds((TypeVariable<?>) type)) {
1146 if (isAssignable(bound, toGenericArrayType)) {
1147 return true;
1148 }
1149 }
1150
1151 return false;
1152 }
1153
1154 if (type instanceof ParameterizedType) {
1155 // the raw type of a parameterized type is never an array or
1156 // generic array, otherwise the declaration would look like this:
1157 // Collection[]< ? extends String > collection;
1158 return false;
1159 }
1160
1161 throw new IllegalStateException("found an unhandled type: " + type);
1162 }
1163
1164 /**
1165 * Tests if the subject type may be implicitly cast to the target
1166 * parameterized type following the Java generics rules.
1167 *
1168 * @param type the subject type to be assigned to the target type
1169 * @param toParameterizedType the target parameterized type
1170 * @param typeVarAssigns a map with type variables
1171 * @return {@code true} if {@code type} is assignable to {@code toType}.
1172 */
1173 private static boolean isAssignable(final Type type, final ParameterizedType toParameterizedType,
1174 final Map<TypeVariable<?>, Type> typeVarAssigns) {
1175 if (type == null) {
1176 return true;
1177 }
1178
1179 // only a null type can be assigned to null type which
1180 // would have cause the previous to return true
1181 if (toParameterizedType == null) {
1182 return false;
1183 }
1184
1185 // cannot cast an array type to a parameterized type.
1186 if (type instanceof GenericArrayType) {
1187 return false;
1188 }
1189
1190 // all types are assignable to themselves
1191 if (toParameterizedType.equals(type)) {
1192 return true;
1193 }
1194
1195 // get the target type's raw type
1196 final Class<?> toClass = getRawType(toParameterizedType);
1197 // get the subject type's type arguments including owner type arguments
1198 // and supertype arguments up to and including the target class.
1199 final Map<TypeVariable<?>, Type> fromTypeVarAssigns = getTypeArguments(type, toClass, null);
1200
1201 // null means the two types are not compatible
1202 if (fromTypeVarAssigns == null) {
1203 return false;
1204 }
1205
1206 // compatible types, but there's no type arguments. this is equivalent
1207 // to comparing Map< ?, ? > to Map, and raw types are always assignable
1208 // to parameterized types.
1209 if (fromTypeVarAssigns.isEmpty()) {
1210 return true;
1211 }
1212
1213 // get the target type's type arguments including owner type arguments
1214 final Map<TypeVariable<?>, Type> toTypeVarAssigns = getTypeArguments(toParameterizedType,
1215 toClass, typeVarAssigns);
1216
1217 // now to check each type argument
1218 for (final TypeVariable<?> var : toTypeVarAssigns.keySet()) {
1219 final Type toTypeArg = unrollVariableAssignments(var, toTypeVarAssigns);
1220 final Type fromTypeArg = unrollVariableAssignments(var, fromTypeVarAssigns);
1221
1222 if (toTypeArg == null && fromTypeArg instanceof Class) {
1223 continue;
1224 }
1225
1226 // parameters must either be absent from the subject type, within
1227 // the bounds of the wildcard type, or be an exact match to the
1228 // parameters of the target type.
1229 if (fromTypeArg != null && toTypeArg != null
1230 && !toTypeArg.equals(fromTypeArg)
1231 && !(toTypeArg instanceof WildcardType && isAssignable(fromTypeArg, toTypeArg,
1232 typeVarAssigns))) {
1233 return false;
1234 }
1235 }
1236 return true;
1237 }
1238
1239 /**
1240 * Tests if the subject type may be implicitly cast to the target type
1241 * following the Java generics rules. If both types are {@link Class}
1242 * objects, the method returns the result of
1243 * {@link ClassUtils#isAssignable(Class, Class)}.
1244 *
1245 * @param type the subject type to be assigned to the target type
1246 * @param toType the target type
1247 * @return {@code true} if {@code type} is assignable to {@code toType}.
1248 */
1249 public static boolean isAssignable(final Type type, final Type toType) {
1250 return isAssignable(type, toType, null);
1251 }
1252
1253 /**
1254 * Tests if the subject type may be implicitly cast to the target type
1255 * following the Java generics rules.
1256 *
1257 * @param type the subject type to be assigned to the target type
1258 * @param toType the target type
1259 * @param typeVarAssigns optional map of type variable assignments
1260 * @return {@code true} if {@code type} is assignable to {@code toType}.
1261 */
1262 private static boolean isAssignable(final Type type, final Type toType,
1263 final Map<TypeVariable<?>, Type> typeVarAssigns) {
1264 if (toType == null || toType instanceof Class<?>) {
1265 return isAssignable(type, (Class<?>) toType);
1266 }
1267
1268 if (toType instanceof ParameterizedType) {
1269 return isAssignable(type, (ParameterizedType) toType, typeVarAssigns);
1270 }
1271
1272 if (toType instanceof GenericArrayType) {
1273 return isAssignable(type, (GenericArrayType) toType, typeVarAssigns);
1274 }
1275
1276 if (toType instanceof WildcardType) {
1277 return isAssignable(type, (WildcardType) toType, typeVarAssigns);
1278 }
1279
1280 if (toType instanceof TypeVariable<?>) {
1281 return isAssignable(type, (TypeVariable<?>) toType, typeVarAssigns);
1282 }
1283
1284 throw new IllegalStateException("found an unhandled type: " + toType);
1285 }
1286
1287 /**
1288 * Tests if the subject type may be implicitly cast to the target type
1289 * variable following the Java generics rules.
1290 *
1291 * @param type the subject type to be assigned to the target type
1292 * @param toTypeVariable the target type variable
1293 * @param typeVarAssigns a map with type variables
1294 * @return {@code true} if {@code type} is assignable to
1295 * {@code toTypeVariable}.
1296 */
1297 private static boolean isAssignable(final Type type, final TypeVariable<?> toTypeVariable,
1298 final Map<TypeVariable<?>, Type> typeVarAssigns) {
1299 if (type == null) {
1300 return true;
1301 }
1302
1303 // only a null type can be assigned to null type which
1304 // would have cause the previous to return true
1305 if (toTypeVariable == null) {
1306 return false;
1307 }
1308
1309 // all types are assignable to themselves
1310 if (toTypeVariable.equals(type)) {
1311 return true;
1312 }
1313
1314 if (type instanceof TypeVariable<?>) {
1315 // a type variable is assignable to another type variable, if
1316 // and only if the former is the latter, extends the latter, or
1317 // is otherwise a descendant of the latter.
1318 final Type[] bounds = getImplicitBounds((TypeVariable<?>) type);
1319
1320 for (final Type bound : bounds) {
1321 if (isAssignable(bound, toTypeVariable, typeVarAssigns)) {
1322 return true;
1323 }
1324 }
1325 }
1326
1327 if (type instanceof Class<?> || type instanceof ParameterizedType
1328 || type instanceof GenericArrayType || type instanceof WildcardType) {
1329 return false;
1330 }
1331
1332 throw new IllegalStateException("found an unhandled type: " + type);
1333 }
1334
1335 /**
1336 * Tests if the subject type may be implicitly cast to the target
1337 * wildcard type following the Java generics rules.
1338 *
1339 * @param type the subject type to be assigned to the target type
1340 * @param toWildcardType the target wildcard type
1341 * @param typeVarAssigns a map with type variables
1342 * @return {@code true} if {@code type} is assignable to
1343 * {@code toWildcardType}.
1344 */
1345 private static boolean isAssignable(final Type type, final WildcardType toWildcardType,
1346 final Map<TypeVariable<?>, Type> typeVarAssigns) {
1347 if (type == null) {
1348 return true;
1349 }
1350
1351 // only a null type can be assigned to null type which
1352 // would have cause the previous to return true
1353 if (toWildcardType == null) {
1354 return false;
1355 }
1356
1357 // all types are assignable to themselves
1358 if (toWildcardType.equals(type)) {
1359 return true;
1360 }
1361
1362 final Type[] toUpperBounds = getImplicitUpperBounds(toWildcardType);
1363 final Type[] toLowerBounds = getImplicitLowerBounds(toWildcardType);
1364
1365 if (type instanceof WildcardType) {
1366 final WildcardType wildcardType = (WildcardType) type;
1367 final Type[] upperBounds = getImplicitUpperBounds(wildcardType);
1368 final Type[] lowerBounds = getImplicitLowerBounds(wildcardType);
1369
1370 for (Type toBound : toUpperBounds) {
1371 // if there are assignments for unresolved type variables,
1372 // now's the time to substitute them.
1373 toBound = substituteTypeVariables(toBound, typeVarAssigns);
1374
1375 // each upper bound of the subject type has to be assignable to
1376 // each
1377 // upper bound of the target type
1378 for (final Type bound : upperBounds) {
1379 if (!isAssignable(bound, toBound, typeVarAssigns)) {
1380 return false;
1381 }
1382 }
1383 }
1384
1385 for (Type toBound : toLowerBounds) {
1386 // if there are assignments for unresolved type variables,
1387 // now's the time to substitute them.
1388 toBound = substituteTypeVariables(toBound, typeVarAssigns);
1389
1390 // each lower bound of the target type has to be assignable to
1391 // each
1392 // lower bound of the subject type
1393 for (final Type bound : lowerBounds) {
1394 if (!isAssignable(toBound, bound, typeVarAssigns)) {
1395 return false;
1396 }
1397 }
1398 }
1399 return true;
1400 }
1401
1402 for (final Type toBound : toUpperBounds) {
1403 // if there are assignments for unresolved type variables,
1404 // now's the time to substitute them.
1405 if (!isAssignable(type, substituteTypeVariables(toBound, typeVarAssigns),
1406 typeVarAssigns)) {
1407 return false;
1408 }
1409 }
1410
1411 for (final Type toBound : toLowerBounds) {
1412 // if there are assignments for unresolved type variables,
1413 // now's the time to substitute them.
1414 if (!isAssignable(substituteTypeVariables(toBound, typeVarAssigns), type,
1415 typeVarAssigns)) {
1416 return false;
1417 }
1418 }
1419 return true;
1420 }
1421
1422 /**
1423 * Tests if the given value can be assigned to the target type
1424 * following the Java generics rules.
1425 *
1426 * @param value the value to be checked
1427 * @param type the target type
1428 * @return {@code true} if {@code value} is an instance of {@code type}.
1429 */
1430 public static boolean isInstance(final Object value, final Type type) {
1431 if (type == null) {
1432 return false;
1433 }
1434
1435 return value == null ? !(type instanceof Class<?>) || !((Class<?>) type).isPrimitive()
1436 : isAssignable(value.getClass(), type, null);
1437 }
1438
1439 /**
1440 * Maps type variables.
9971441 *
9981442 * @param <T> the generic type of the class in question
9991443 * @param cls the class in question
10401484 }
10411485
10421486 /**
1043 * <p>Get the closest parent type to the
1044 * super class specified by {@code superClass}.</p>
1045 *
1046 * @param cls the class in question
1047 * @param superClass the super class
1048 * @return the closes parent type
1049 */
1050 private static Type getClosestParentType(final Class<?> cls, final Class<?> superClass) {
1051 // only look at the interfaces if the super class is also an interface
1052 if (superClass.isInterface()) {
1053 // get the generic interfaces of the subject class
1054 final Type[] interfaceTypes = cls.getGenericInterfaces();
1055 // will hold the best generic interface match found
1056 Type genericInterface = null;
1057
1058 // find the interface closest to the super class
1059 for (final Type midType : interfaceTypes) {
1060 Class<?> midClass = null;
1061
1062 if (midType instanceof ParameterizedType) {
1063 midClass = getRawType((ParameterizedType) midType);
1064 } else if (midType instanceof Class<?>) {
1065 midClass = (Class<?>) midType;
1066 } else {
1067 throw new IllegalStateException("Unexpected generic"
1068 + " interface type found: " + midType);
1069 }
1070
1071 // check if this interface is further up the inheritance chain
1072 // than the previously found match
1073 if (isAssignable(midClass, superClass)
1074 && isAssignable(genericInterface, (Type) midClass)) {
1075 genericInterface = midType;
1076 }
1077 }
1078
1079 // found a match?
1080 if (genericInterface != null) {
1081 return genericInterface;
1082 }
1083 }
1084
1085 // none of the interfaces were descendants of the target class, so the
1086 // super class has to be one, instead
1087 return cls.getGenericSuperclass();
1088 }
1089
1090 /**
1091 * <p>Checks if the given value can be assigned to the target type
1092 * following the Java generics rules.</p>
1093 *
1094 * @param value the value to be checked
1095 * @param type the target type
1096 * @return {@code true} if {@code value} is an instance of {@code type}.
1097 */
1098 public static boolean isInstance(final Object value, final Type type) {
1099 if (type == null) {
1100 return false;
1101 }
1102
1103 return value == null ? !(type instanceof Class<?>) || !((Class<?>) type).isPrimitive()
1104 : isAssignable(value.getClass(), type, null);
1105 }
1106
1107 /**
1108 * <p>This method strips out the redundant upper bound types in type
1487 * Strips out the redundant upper bound types in type
11091488 * variable types and wildcard types (or it would with wildcard types if
1110 * multiple upper bounds were allowed).</p> <p>Example, with the variable
1111 * type declaration:
1489 * multiple upper bounds were allowed).
1490 *
1491 * <p>
1492 * Example, with the variable type declaration:
1493 * </p>
11121494 *
11131495 * <pre>&lt;K extends java.util.Collection&lt;String&gt; &amp;
11141496 * java.util.List&lt;String&gt;&gt;</pre>
11261508 * redundant types.
11271509 */
11281510 public static Type[] normalizeUpperBounds(final Type[] bounds) {
1129 Validate.notNull(bounds, "null value specified for bounds array");
1511 Validate.notNull(bounds, "bounds");
11301512 // don't bother if there's only one (or none) type
11311513 if (bounds.length < 2) {
11321514 return bounds;
11531535 }
11541536
11551537 /**
1156 * <p>Returns an array containing the sole type of {@link Object} if
1157 * {@link TypeVariable#getBounds()} returns an empty array. Otherwise, it
1158 * returns the result of {@link TypeVariable#getBounds()} passed into
1159 * {@link #normalizeUpperBounds}.</p>
1160 *
1161 * @param typeVariable the subject type variable, not {@code null}
1162 * @return a non-empty array containing the bounds of the type variable.
1163 */
1164 public static Type[] getImplicitBounds(final TypeVariable<?> typeVariable) {
1165 Validate.notNull(typeVariable, "typeVariable is null");
1166 final Type[] bounds = typeVariable.getBounds();
1167
1168 return bounds.length == 0 ? new Type[] { Object.class } : normalizeUpperBounds(bounds);
1169 }
1170
1171 /**
1172 * <p>Returns an array containing the sole value of {@link Object} if
1173 * {@link WildcardType#getUpperBounds()} returns an empty array. Otherwise,
1174 * it returns the result of {@link WildcardType#getUpperBounds()}
1175 * passed into {@link #normalizeUpperBounds}.</p>
1176 *
1177 * @param wildcardType the subject wildcard type, not {@code null}
1178 * @return a non-empty array containing the upper bounds of the wildcard
1179 * type.
1180 */
1181 public static Type[] getImplicitUpperBounds(final WildcardType wildcardType) {
1182 Validate.notNull(wildcardType, "wildcardType is null");
1183 final Type[] bounds = wildcardType.getUpperBounds();
1184
1185 return bounds.length == 0 ? new Type[] { Object.class } : normalizeUpperBounds(bounds);
1186 }
1187
1188 /**
1189 * <p>Returns an array containing a single value of {@code null} if
1190 * {@link WildcardType#getLowerBounds()} returns an empty array. Otherwise,
1191 * it returns the result of {@link WildcardType#getLowerBounds()}.</p>
1192 *
1193 * @param wildcardType the subject wildcard type, not {@code null}
1194 * @return a non-empty array containing the lower bounds of the wildcard
1195 * type.
1196 */
1197 public static Type[] getImplicitLowerBounds(final WildcardType wildcardType) {
1198 Validate.notNull(wildcardType, "wildcardType is null");
1199 final Type[] bounds = wildcardType.getLowerBounds();
1200
1201 return bounds.length == 0 ? new Type[] { null } : bounds;
1202 }
1203
1204 /**
1205 * <p>Determines whether or not specified types satisfy the bounds of their
1538 * Creates a parameterized type instance.
1539 *
1540 * @param rawClass the raw class to create a parameterized type instance for
1541 * @param typeVariableMap the map used for parameterization
1542 * @return {@link ParameterizedType}
1543 * @since 3.2
1544 */
1545 public static final ParameterizedType parameterize(final Class<?> rawClass,
1546 final Map<TypeVariable<?>, Type> typeVariableMap) {
1547 Validate.notNull(rawClass, "rawClass");
1548 Validate.notNull(typeVariableMap, "typeVariableMap");
1549 return parameterizeWithOwner(null, rawClass,
1550 extractTypeArgumentsFrom(typeVariableMap, rawClass.getTypeParameters()));
1551 }
1552
1553 /**
1554 * Creates a parameterized type instance.
1555 *
1556 * @param rawClass the raw class to create a parameterized type instance for
1557 * @param typeArguments the types used for parameterization
1558 * @return {@link ParameterizedType}
1559 * @since 3.2
1560 */
1561 public static final ParameterizedType parameterize(final Class<?> rawClass, final Type... typeArguments) {
1562 return parameterizeWithOwner(null, rawClass, typeArguments);
1563 }
1564
1565 /**
1566 * Formats a {@link ParameterizedType} as a {@link String}.
1567 *
1568 * @param parameterizedType {@code ParameterizedType} to format
1569 * @return String
1570 * @since 3.2
1571 */
1572 private static String parameterizedTypeToString(final ParameterizedType parameterizedType) {
1573 final StringBuilder builder = new StringBuilder();
1574
1575 final Type useOwner = parameterizedType.getOwnerType();
1576 final Class<?> raw = (Class<?>) parameterizedType.getRawType();
1577
1578 if (useOwner == null) {
1579 builder.append(raw.getName());
1580 } else {
1581 if (useOwner instanceof Class<?>) {
1582 builder.append(((Class<?>) useOwner).getName());
1583 } else {
1584 builder.append(useOwner.toString());
1585 }
1586 builder.append('.').append(raw.getSimpleName());
1587 }
1588
1589 final int[] recursiveTypeIndexes = findRecursiveTypes(parameterizedType);
1590
1591 if (recursiveTypeIndexes.length > 0) {
1592 appendRecursiveTypes(builder, recursiveTypeIndexes, parameterizedType.getActualTypeArguments());
1593 } else {
1594 appendAllTo(builder.append('<'), ", ", parameterizedType.getActualTypeArguments()).append('>');
1595 }
1596
1597 return builder.toString();
1598 }
1599
1600 /**
1601 * Creates a parameterized type instance.
1602 *
1603 * @param owner the owning type
1604 * @param rawClass the raw class to create a parameterized type instance for
1605 * @param typeVariableMap the map used for parameterization
1606 * @return {@link ParameterizedType}
1607 * @since 3.2
1608 */
1609 public static final ParameterizedType parameterizeWithOwner(final Type owner, final Class<?> rawClass,
1610 final Map<TypeVariable<?>, Type> typeVariableMap) {
1611 Validate.notNull(rawClass, "rawClass");
1612 Validate.notNull(typeVariableMap, "typeVariableMap");
1613 return parameterizeWithOwner(owner, rawClass,
1614 extractTypeArgumentsFrom(typeVariableMap, rawClass.getTypeParameters()));
1615 }
1616
1617 /**
1618 * Creates a parameterized type instance.
1619 *
1620 * @param owner the owning type
1621 * @param rawClass the raw class to create a parameterized type instance for
1622 * @param typeArguments the types used for parameterization
1623 *
1624 * @return {@link ParameterizedType}
1625 * @since 3.2
1626 */
1627 public static final ParameterizedType parameterizeWithOwner(final Type owner, final Class<?> rawClass,
1628 final Type... typeArguments) {
1629 Validate.notNull(rawClass, "rawClass");
1630 final Type useOwner;
1631 if (rawClass.getEnclosingClass() == null) {
1632 Validate.isTrue(owner == null, "no owner allowed for top-level %s", rawClass);
1633 useOwner = null;
1634 } else if (owner == null) {
1635 useOwner = rawClass.getEnclosingClass();
1636 } else {
1637 Validate.isTrue(isAssignable(owner, rawClass.getEnclosingClass()),
1638 "%s is invalid owner type for parameterized %s", owner, rawClass);
1639 useOwner = owner;
1640 }
1641 Validate.noNullElements(typeArguments, "null type argument at index %s");
1642 Validate.isTrue(rawClass.getTypeParameters().length == typeArguments.length,
1643 "invalid number of type parameters specified: expected %d, got %d", rawClass.getTypeParameters().length,
1644 typeArguments.length);
1645
1646 return new ParameterizedTypeImpl(rawClass, useOwner, typeArguments);
1647 }
1648
1649 /**
1650 * Finds the mapping for {@code type} in {@code typeVarAssigns}.
1651 *
1652 * @param type the type to be replaced
1653 * @param typeVarAssigns the map with type variables
1654 * @return the replaced type
1655 * @throws IllegalArgumentException if the type cannot be substituted
1656 */
1657 private static Type substituteTypeVariables(final Type type, final Map<TypeVariable<?>, Type> typeVarAssigns) {
1658 if (type instanceof TypeVariable<?> && typeVarAssigns != null) {
1659 final Type replacementType = typeVarAssigns.get(type);
1660
1661 if (replacementType == null) {
1662 throw new IllegalArgumentException("missing assignment type for type variable "
1663 + type);
1664 }
1665 return replacementType;
1666 }
1667 return type;
1668 }
1669
1670 /**
1671 * Formats a {@link TypeVariable} including its {@link GenericDeclaration}.
1672 *
1673 * @param typeVariable the type variable to create a String representation for, not {@code null}
1674 * @return String
1675 * @since 3.2
1676 */
1677 public static String toLongString(final TypeVariable<?> typeVariable) {
1678 Validate.notNull(typeVariable, "typeVariable");
1679 final StringBuilder buf = new StringBuilder();
1680 final GenericDeclaration d = typeVariable.getGenericDeclaration();
1681 if (d instanceof Class<?>) {
1682 Class<?> c = (Class<?>) d;
1683 while (true) {
1684 if (c.getEnclosingClass() == null) {
1685 buf.insert(0, c.getName());
1686 break;
1687 }
1688 buf.insert(0, c.getSimpleName()).insert(0, '.');
1689 c = c.getEnclosingClass();
1690 }
1691 } else if (d instanceof Type) {// not possible as of now
1692 buf.append(toString((Type) d));
1693 } else {
1694 buf.append(d);
1695 }
1696 return buf.append(':').append(typeVariableToString(typeVariable)).toString();
1697 }
1698
1699 private static <T> String toString(final T object) {
1700 return object instanceof Type ? toString((Type) object) : object.toString();
1701 }
1702
1703 /**
1704 * Formats a given type as a Java-esque String.
1705 *
1706 * @param type the type to create a String representation for, not {@code null}
1707 * @return String
1708 * @since 3.2
1709 */
1710 public static String toString(final Type type) {
1711 Validate.notNull(type);
1712 if (type instanceof Class<?>) {
1713 return classToString((Class<?>) type);
1714 }
1715 if (type instanceof ParameterizedType) {
1716 return parameterizedTypeToString((ParameterizedType) type);
1717 }
1718 if (type instanceof WildcardType) {
1719 return wildcardTypeToString((WildcardType) type);
1720 }
1721 if (type instanceof TypeVariable<?>) {
1722 return typeVariableToString((TypeVariable<?>) type);
1723 }
1724 if (type instanceof GenericArrayType) {
1725 return genericArrayTypeToString((GenericArrayType) type);
1726 }
1727 throw new IllegalArgumentException(ObjectUtils.identityToString(type));
1728 }
1729
1730 /**
1731 * Determines whether or not specified types satisfy the bounds of their
12061732 * mapped type variables. When a type parameter extends another (such as
12071733 * {@code <T, S extends T>}), uses another as a type parameter (such as
12081734 * {@code <T, S extends Comparable>>}), or otherwise depends on
12091735 * another type variable to be specified, the dependencies must be included
1210 * in {@code typeVarAssigns}.</p>
1211 *
1212 * @param typeVarAssigns specifies the potential types to be assigned to the
1736 * in {@code typeVarAssigns}.
1737 *
1738 * @param typeVariableMap specifies the potential types to be assigned to the
12131739 * type variables, not {@code null}.
12141740 * @return whether or not the types can be assigned to their respective type
12151741 * variables.
12161742 */
1217 public static boolean typesSatisfyVariables(final Map<TypeVariable<?>, Type> typeVarAssigns) {
1218 Validate.notNull(typeVarAssigns, "typeVarAssigns is null");
1743 public static boolean typesSatisfyVariables(final Map<TypeVariable<?>, Type> typeVariableMap) {
1744 Validate.notNull(typeVariableMap, "typeVariableMap");
12191745 // all types must be assignable to all the bounds of their mapped
12201746 // type variable.
1221 for (final Map.Entry<TypeVariable<?>, Type> entry : typeVarAssigns.entrySet()) {
1747 for (final Map.Entry<TypeVariable<?>, Type> entry : typeVariableMap.entrySet()) {
12221748 final TypeVariable<?> typeVar = entry.getKey();
12231749 final Type type = entry.getValue();
12241750
12251751 for (final Type bound : getImplicitBounds(typeVar)) {
1226 if (!isAssignable(type, substituteTypeVariables(bound, typeVarAssigns),
1227 typeVarAssigns)) {
1752 if (!isAssignable(type, substituteTypeVariables(bound, typeVariableMap),
1753 typeVariableMap)) {
12281754 return false;
12291755 }
12301756 }
12331759 }
12341760
12351761 /**
1236 * <p>Transforms the passed in type to a {@link Class} object. Type-checking method of convenience.</p>
1237 *
1238 * @param parameterizedType the type to be converted
1239 * @return the corresponding {@code Class} object
1240 * @throws IllegalStateException if the conversion fails
1241 */
1242 private static Class<?> getRawType(final ParameterizedType parameterizedType) {
1243 final Type rawType = parameterizedType.getRawType();
1244
1245 // check if raw type is a Class object
1246 // not currently necessary, but since the return type is Type instead of
1247 // Class, there's enough reason to believe that future versions of Java
1248 // may return other Type implementations. And type-safety checking is
1249 // rarely a bad idea.
1250 if (!(rawType instanceof Class<?>)) {
1251 throw new IllegalStateException("Wait... What!? Type of rawType: " + rawType);
1252 }
1253
1254 return (Class<?>) rawType;
1255 }
1256
1257 /**
1258 * <p>Get the raw type of a Java type, given its context. Primarily for use
1259 * with {@link TypeVariable}s and {@link GenericArrayType}s, or when you do
1260 * not know the runtime type of {@code type}: if you know you have a
1261 * {@link Class} instance, it is already raw; if you know you have a
1262 * {@link ParameterizedType}, its raw type is only a method call away.</p>
1263 *
1264 * @param type to resolve
1265 * @param assigningType type to be resolved against
1266 * @return the resolved {@link Class} object or {@code null} if
1267 * the type could not be resolved
1268 */
1269 public static Class<?> getRawType(final Type type, final Type assigningType) {
1270 if (type instanceof Class<?>) {
1271 // it is raw, no problem
1272 return (Class<?>) type;
1273 }
1274
1275 if (type instanceof ParameterizedType) {
1276 // simple enough to get the raw type of a ParameterizedType
1277 return getRawType((ParameterizedType) type);
1278 }
1279
1280 if (type instanceof TypeVariable<?>) {
1281 if (assigningType == null) {
1282 return null;
1283 }
1284
1285 // get the entity declaring this type variable
1286 final Object genericDeclaration = ((TypeVariable<?>) type).getGenericDeclaration();
1287
1288 // can't get the raw type of a method- or constructor-declared type
1289 // variable
1290 if (!(genericDeclaration instanceof Class<?>)) {
1291 return null;
1292 }
1293
1294 // get the type arguments for the declaring class/interface based
1295 // on the enclosing type
1296 final Map<TypeVariable<?>, Type> typeVarAssigns = getTypeArguments(assigningType,
1297 (Class<?>) genericDeclaration);
1298
1299 // enclosingType has to be a subclass (or subinterface) of the
1300 // declaring type
1301 if (typeVarAssigns == null) {
1302 return null;
1303 }
1304
1305 // get the argument assigned to this type variable
1306 final Type typeArgument = typeVarAssigns.get(type);
1307
1308 if (typeArgument == null) {
1309 return null;
1310 }
1311
1312 // get the argument for this type variable
1313 return getRawType(typeArgument, assigningType);
1314 }
1315
1316 if (type instanceof GenericArrayType) {
1317 // get raw component type
1318 final Class<?> rawComponentType = getRawType(((GenericArrayType) type)
1319 .getGenericComponentType(), assigningType);
1320
1321 // create array type from raw component type and return its class
1322 return Array.newInstance(rawComponentType, 0).getClass();
1323 }
1324
1325 // (hand-waving) this is not the method you're looking for
1326 if (type instanceof WildcardType) {
1327 return null;
1328 }
1329
1330 throw new IllegalArgumentException("unknown type: " + type);
1331 }
1332
1333 /**
1334 * Learn whether the specified type denotes an array type.
1335 * @param type the type to be checked
1336 * @return {@code true} if {@code type} is an array class or a {@link GenericArrayType}.
1337 */
1338 public static boolean isArrayType(final Type type) {
1339 return type instanceof GenericArrayType || type instanceof Class<?> && ((Class<?>) type).isArray();
1340 }
1341
1342 /**
1343 * Gets the array component type of {@code type}.
1344 * @param type the type to be checked
1345 * @return component type or null if type is not an array type
1346 */
1347 public static Type getArrayComponentType(final Type type) {
1348 if (type instanceof Class<?>) {
1349 final Class<?> cls = (Class<?>) type;
1350 return cls.isArray() ? cls.getComponentType() : null;
1351 }
1352 if (type instanceof GenericArrayType) {
1353 return ((GenericArrayType) type).getGenericComponentType();
1354 }
1355 return null;
1762 * Formats a {@link TypeVariable} as a {@link String}.
1763 *
1764 * @param typeVariable {@code TypeVariable} to format
1765 * @return String
1766 * @since 3.2
1767 */
1768 private static String typeVariableToString(final TypeVariable<?> typeVariable) {
1769 final StringBuilder buf = new StringBuilder(typeVariable.getName());
1770 final Type[] bounds = typeVariable.getBounds();
1771 if (bounds.length > 0 && !(bounds.length == 1 && Object.class.equals(bounds[0]))) {
1772 buf.append(" extends ");
1773 appendAllTo(buf, " & ", typeVariable.getBounds());
1774 }
1775 return buf.toString();
1776 }
1777
1778 /**
1779 * Unrolls variables in a type bounds array.
1780 *
1781 * @param typeArguments assignments {@link Map}
1782 * @param bounds in which to expand variables
1783 * @return {@code bounds} with any variables reassigned
1784 * @since 3.2
1785 */
1786 private static Type[] unrollBounds(final Map<TypeVariable<?>, Type> typeArguments, final Type[] bounds) {
1787 Type[] result = bounds;
1788 int i = 0;
1789 for (; i < result.length; i++) {
1790 final Type unrolled = unrollVariables(typeArguments, result[i]);
1791 if (unrolled == null) {
1792 result = ArrayUtils.remove(result, i--);
1793 } else {
1794 result[i] = unrolled;
1795 }
1796 }
1797 return result;
1798 }
1799
1800 /**
1801 * Look up {@code var} in {@code typeVarAssigns} <em>transitively</em>,
1802 * i.e. keep looking until the value found is <em>not</em> a type variable.
1803 *
1804 * @param typeVariable the type variable to look up
1805 * @param typeVarAssigns the map used for the look up
1806 * @return Type or {@code null} if some variable was not in the map
1807 * @since 3.2
1808 */
1809 private static Type unrollVariableAssignments(TypeVariable<?> typeVariable,
1810 final Map<TypeVariable<?>, Type> typeVarAssigns) {
1811 Type result;
1812 do {
1813 result = typeVarAssigns.get(typeVariable);
1814 if (result instanceof TypeVariable<?> && !result.equals(typeVariable)) {
1815 typeVariable = (TypeVariable<?>) result;
1816 continue;
1817 }
1818 break;
1819 } while (true);
1820 return result;
13561821 }
13571822
13581823 /**
13991864 }
14001865
14011866 /**
1402 * Local helper method to unroll variables in a type bounds array.
1403 *
1404 * @param typeArguments assignments {@link Map}
1405 * @param bounds in which to expand variables
1406 * @return {@code bounds} with any variables reassigned
1407 * @since 3.2
1408 */
1409 private static Type[] unrollBounds(final Map<TypeVariable<?>, Type> typeArguments, final Type[] bounds) {
1410 Type[] result = bounds;
1411 int i = 0;
1412 for (; i < result.length; i++) {
1413 final Type unrolled = unrollVariables(typeArguments, result[i]);
1414 if (unrolled == null) {
1415 result = ArrayUtils.remove(result, i--);
1416 } else {
1417 result[i] = unrolled;
1418 }
1419 }
1420 return result;
1421 }
1422
1423 /**
1424 * Learn, recursively, whether any of the type parameters associated with {@code type} are bound to variables.
1425 *
1426 * @param type the type to check for type variables
1427 * @return boolean
1428 * @since 3.2
1429 */
1430 public static boolean containsTypeVariables(final Type type) {
1431 if (type instanceof TypeVariable<?>) {
1432 return true;
1433 }
1434 if (type instanceof Class<?>) {
1435 return ((Class<?>) type).getTypeParameters().length > 0;
1436 }
1437 if (type instanceof ParameterizedType) {
1438 for (final Type arg : ((ParameterizedType) type).getActualTypeArguments()) {
1439 if (containsTypeVariables(arg)) {
1440 return true;
1441 }
1442 }
1443 return false;
1444 }
1445 if (type instanceof WildcardType) {
1446 final WildcardType wild = (WildcardType) type;
1447 return containsTypeVariables(getImplicitLowerBounds(wild)[0])
1448 || containsTypeVariables(getImplicitUpperBounds(wild)[0]);
1449 }
1450 return false;
1451 }
1452
1453 /**
1454 * Create a parameterized type instance.
1455 *
1456 * @param rawClass the raw class to create a parameterized type instance for
1457 * @param typeArguments the types used for parameterization
1458 * @return {@link ParameterizedType}
1459 * @since 3.2
1460 */
1461 public static final ParameterizedType parameterize(final Class<?> rawClass, final Type... typeArguments) {
1462 return parameterizeWithOwner(null, rawClass, typeArguments);
1463 }
1464
1465 /**
1466 * Create a parameterized type instance.
1467 *
1468 * @param rawClass the raw class to create a parameterized type instance for
1469 * @param typeArgMappings the mapping used for parameterization
1470 * @return {@link ParameterizedType}
1471 * @since 3.2
1472 */
1473 public static final ParameterizedType parameterize(final Class<?> rawClass,
1474 final Map<TypeVariable<?>, Type> typeArgMappings) {
1475 Validate.notNull(rawClass, "raw class is null");
1476 Validate.notNull(typeArgMappings, "typeArgMappings is null");
1477 return parameterizeWithOwner(null, rawClass,
1478 extractTypeArgumentsFrom(typeArgMappings, rawClass.getTypeParameters()));
1479 }
1480
1481 /**
1482 * Create a parameterized type instance.
1483 *
1484 * @param owner the owning type
1485 * @param rawClass the raw class to create a parameterized type instance for
1486 * @param typeArguments the types used for parameterization
1487 *
1488 * @return {@link ParameterizedType}
1489 * @since 3.2
1490 */
1491 public static final ParameterizedType parameterizeWithOwner(final Type owner, final Class<?> rawClass,
1492 final Type... typeArguments) {
1493 Validate.notNull(rawClass, "raw class is null");
1494 final Type useOwner;
1495 if (rawClass.getEnclosingClass() == null) {
1496 Validate.isTrue(owner == null, "no owner allowed for top-level %s", rawClass);
1497 useOwner = null;
1498 } else if (owner == null) {
1499 useOwner = rawClass.getEnclosingClass();
1500 } else {
1501 Validate.isTrue(isAssignable(owner, rawClass.getEnclosingClass()),
1502 "%s is invalid owner type for parameterized %s", owner, rawClass);
1503 useOwner = owner;
1504 }
1505 Validate.noNullElements(typeArguments, "null type argument at index %s");
1506 Validate.isTrue(rawClass.getTypeParameters().length == typeArguments.length,
1507 "invalid number of type parameters specified: expected %d, got %d", rawClass.getTypeParameters().length,
1508 typeArguments.length);
1509
1510 return new ParameterizedTypeImpl(rawClass, useOwner, typeArguments);
1511 }
1512
1513 /**
1514 * Create a parameterized type instance.
1515 *
1516 * @param owner the owning type
1517 * @param rawClass the raw class to create a parameterized type instance for
1518 * @param typeArgMappings the mapping used for parameterization
1519 * @return {@link ParameterizedType}
1520 * @since 3.2
1521 */
1522 public static final ParameterizedType parameterizeWithOwner(final Type owner, final Class<?> rawClass,
1523 final Map<TypeVariable<?>, Type> typeArgMappings) {
1524 Validate.notNull(rawClass, "raw class is null");
1525 Validate.notNull(typeArgMappings, "typeArgMappings is null");
1526 return parameterizeWithOwner(owner, rawClass,
1527 extractTypeArgumentsFrom(typeArgMappings, rawClass.getTypeParameters()));
1528 }
1529
1530 /**
1531 * Helper method to establish the formal parameters for a parameterized type.
1532 * @param mappings map containing the assignments
1533 * @param variables expected map keys
1534 * @return array of map values corresponding to specified keys
1535 */
1536 private static Type[] extractTypeArgumentsFrom(final Map<TypeVariable<?>, Type> mappings, final TypeVariable<?>[] variables) {
1537 final Type[] result = new Type[variables.length];
1538 int index = 0;
1539 for (final TypeVariable<?> var : variables) {
1540 Validate.isTrue(mappings.containsKey(var), "missing argument mapping for %s", toString(var));
1541 result[index++] = mappings.get(var);
1542 }
1543 return result;
1544 }
1545
1546 /**
15471867 * Gets a {@link WildcardTypeBuilder}.
1868 *
15481869 * @return {@link WildcardTypeBuilder}
15491870 * @since 3.2
15501871 */
15531874 }
15541875
15551876 /**
1556 * Create a generic array type instance.
1557 *
1558 * @param componentType the type of the elements of the array. For example the component type of {@code boolean[]}
1559 * is {@code boolean}
1560 * @return {@link GenericArrayType}
1561 * @since 3.2
1562 */
1563 public static GenericArrayType genericArrayType(final Type componentType) {
1564 return new GenericArrayTypeImpl(Validate.notNull(componentType, "componentType is null"));
1565 }
1566
1567 /**
1568 * Check equality of types.
1569 *
1570 * @param type1 the first type
1571 * @param type2 the second type
1572 * @return boolean
1573 * @since 3.2
1574 */
1575 public static boolean equals(final Type type1, final Type type2) {
1576 if (Objects.equals(type1, type2)) {
1577 return true;
1578 }
1579 if (type1 instanceof ParameterizedType) {
1580 return equals((ParameterizedType) type1, type2);
1581 }
1582 if (type1 instanceof GenericArrayType) {
1583 return equals((GenericArrayType) type1, type2);
1584 }
1585 if (type1 instanceof WildcardType) {
1586 return equals((WildcardType) type1, type2);
1587 }
1588 return false;
1589 }
1590
1591 /**
1592 * Learn whether {@code t} equals {@code p}.
1593 * @param parameterizedType LHS
1594 * @param type RHS
1595 * @return boolean
1596 * @since 3.2
1597 */
1598 private static boolean equals(final ParameterizedType parameterizedType, final Type type) {
1599 if (type instanceof ParameterizedType) {
1600 final ParameterizedType other = (ParameterizedType) type;
1601 if (equals(parameterizedType.getRawType(), other.getRawType())
1602 && equals(parameterizedType.getOwnerType(), other.getOwnerType())) {
1603 return equals(parameterizedType.getActualTypeArguments(), other.getActualTypeArguments());
1604 }
1605 }
1606 return false;
1607 }
1608
1609 /**
1610 * Learn whether {@code t} equals {@code a}.
1611 * @param genericArrayType LHS
1612 * @param type RHS
1613 * @return boolean
1614 * @since 3.2
1615 */
1616 private static boolean equals(final GenericArrayType genericArrayType, final Type type) {
1617 return type instanceof GenericArrayType
1618 && equals(genericArrayType.getGenericComponentType(), ((GenericArrayType) type).getGenericComponentType());
1619 }
1620
1621 /**
1622 * Learn whether {@code t} equals {@code w}.
1623 * @param wildcardType LHS
1624 * @param type RHS
1625 * @return boolean
1626 * @since 3.2
1627 */
1628 private static boolean equals(final WildcardType wildcardType, final Type type) {
1629 if (type instanceof WildcardType) {
1630 final WildcardType other = (WildcardType) type;
1631 return equals(getImplicitLowerBounds(wildcardType), getImplicitLowerBounds(other))
1632 && equals(getImplicitUpperBounds(wildcardType), getImplicitUpperBounds(other));
1633 }
1634 return false;
1635 }
1636
1637 /**
1638 * Learn whether {@code t1} equals {@code t2}.
1639 * @param type1 LHS
1640 * @param type2 RHS
1641 * @return boolean
1642 * @since 3.2
1643 */
1644 private static boolean equals(final Type[] type1, final Type[] type2) {
1645 if (type1.length == type2.length) {
1646 for (int i = 0; i < type1.length; i++) {
1647 if (!equals(type1[i], type2[i])) {
1648 return false;
1649 }
1650 }
1651 return true;
1652 }
1653 return false;
1654 }
1655
1656 /**
1657 * Present a given type as a Java-esque String.
1658 *
1659 * @param type the type to create a String representation for, not {@code null}
1660 * @return String
1661 * @since 3.2
1662 */
1663 public static String toString(final Type type) {
1664 Validate.notNull(type);
1665 if (type instanceof Class<?>) {
1666 return classToString((Class<?>) type);
1667 }
1668 if (type instanceof ParameterizedType) {
1669 return parameterizedTypeToString((ParameterizedType) type);
1670 }
1671 if (type instanceof WildcardType) {
1672 return wildcardTypeToString((WildcardType) type);
1673 }
1674 if (type instanceof TypeVariable<?>) {
1675 return typeVariableToString((TypeVariable<?>) type);
1676 }
1677 if (type instanceof GenericArrayType) {
1678 return genericArrayTypeToString((GenericArrayType) type);
1679 }
1680 throw new IllegalArgumentException(ObjectUtils.identityToString(type));
1681 }
1682
1683 /**
1684 * Format a {@link TypeVariable} including its {@link GenericDeclaration}.
1685 *
1686 * @param var the type variable to create a String representation for, not {@code null}
1687 * @return String
1688 * @since 3.2
1689 */
1690 public static String toLongString(final TypeVariable<?> var) {
1691 Validate.notNull(var, "var is null");
1692 final StringBuilder buf = new StringBuilder();
1693 final GenericDeclaration d = var.getGenericDeclaration();
1694 if (d instanceof Class<?>) {
1695 Class<?> c = (Class<?>) d;
1696 while (true) {
1697 if (c.getEnclosingClass() == null) {
1698 buf.insert(0, c.getName());
1699 break;
1700 }
1701 buf.insert(0, c.getSimpleName()).insert(0, '.');
1702 c = c.getEnclosingClass();
1703 }
1704 } else if (d instanceof Type) {// not possible as of now
1705 buf.append(toString((Type) d));
1706 } else {
1707 buf.append(d);
1708 }
1709 return buf.append(':').append(typeVariableToString(var)).toString();
1710 }
1711
1712 /**
1713 * Wrap the specified {@link Type} in a {@link Typed} wrapper.
1714 *
1715 * @param <T> inferred generic type
1716 * @param type to wrap
1717 * @return Typed&lt;T&gt;
1718 * @since 3.2
1719 */
1720 public static <T> Typed<T> wrap(final Type type) {
1721 return () -> type;
1722 }
1723
1724 /**
1725 * Wrap the specified {@link Class} in a {@link Typed} wrapper.
1726 *
1727 * @param <T> generic type
1728 * @param type to wrap
1729 * @return Typed&lt;T&gt;
1730 * @since 3.2
1731 */
1732 public static <T> Typed<T> wrap(final Class<T> type) {
1733 return wrap((Type) type);
1734 }
1735
1736 /**
1737 * Format a {@link Class} as a {@link String}.
1738 * @param cls {@code Class} to format
1739 * @return String
1740 * @since 3.2
1741 */
1742 private static String classToString(final Class<?> cls) {
1743 if (cls.isArray()) {
1744 return toString(cls.getComponentType()) + "[]";
1745 }
1746
1747 final StringBuilder buf = new StringBuilder();
1748
1749 if (cls.getEnclosingClass() != null) {
1750 buf.append(classToString(cls.getEnclosingClass())).append('.').append(cls.getSimpleName());
1751 } else {
1752 buf.append(cls.getName());
1753 }
1754 if (cls.getTypeParameters().length > 0) {
1755 buf.append('<');
1756 appendAllTo(buf, ", ", cls.getTypeParameters());
1757 buf.append('>');
1758 }
1759 return buf.toString();
1760 }
1761
1762 /**
1763 * Format a {@link TypeVariable} as a {@link String}.
1764 * @param typeVariable {@code TypeVariable} to format
1765 * @return String
1766 * @since 3.2
1767 */
1768 private static String typeVariableToString(final TypeVariable<?> typeVariable) {
1769 final StringBuilder buf = new StringBuilder(typeVariable.getName());
1770 final Type[] bounds = typeVariable.getBounds();
1771 if (bounds.length > 0 && !(bounds.length == 1 && Object.class.equals(bounds[0]))) {
1772 buf.append(" extends ");
1773 appendAllTo(buf, " & ", typeVariable.getBounds());
1774 }
1775 return buf.toString();
1776 }
1777
1778 /**
1779 * Format a {@link ParameterizedType} as a {@link String}.
1780 * @param parameterizedType {@code ParameterizedType} to format
1781 * @return String
1782 * @since 3.2
1783 */
1784 private static String parameterizedTypeToString(final ParameterizedType parameterizedType) {
1785 final StringBuilder builder = new StringBuilder();
1786
1787 final Type useOwner = parameterizedType.getOwnerType();
1788 final Class<?> raw = (Class<?>) parameterizedType.getRawType();
1789
1790 if (useOwner == null) {
1791 builder.append(raw.getName());
1792 } else {
1793 if (useOwner instanceof Class<?>) {
1794 builder.append(((Class<?>) useOwner).getName());
1795 } else {
1796 builder.append(useOwner.toString());
1797 }
1798 builder.append('.').append(raw.getSimpleName());
1799 }
1800
1801 final int[] recursiveTypeIndexes = findRecursiveTypes(parameterizedType);
1802
1803 if (recursiveTypeIndexes.length > 0) {
1804 appendRecursiveTypes(builder, recursiveTypeIndexes, parameterizedType.getActualTypeArguments());
1805 } else {
1806 appendAllTo(builder.append('<'), ", ", parameterizedType.getActualTypeArguments()).append('>');
1807 }
1808
1809 return builder.toString();
1810 }
1811
1812 private static void appendRecursiveTypes(final StringBuilder builder, final int[] recursiveTypeIndexes,
1813 final Type[] argumentTypes) {
1814 for (int i = 0; i < recursiveTypeIndexes.length; i++) {
1815 appendAllTo(builder.append('<'), ", ", argumentTypes[i].toString()).append('>');
1816 }
1817
1818 final Type[] argumentsFiltered = ArrayUtils.removeAll(argumentTypes, recursiveTypeIndexes);
1819
1820 if (argumentsFiltered.length > 0) {
1821 appendAllTo(builder.append('<'), ", ", argumentsFiltered).append('>');
1822 }
1823 }
1824
1825 private static int[] findRecursiveTypes(final ParameterizedType parameterizedType) {
1826 final Type[] filteredArgumentTypes = Arrays.copyOf(parameterizedType.getActualTypeArguments(),
1827 parameterizedType.getActualTypeArguments().length);
1828 int[] indexesToRemove = {};
1829 for (int i = 0; i < filteredArgumentTypes.length; i++) {
1830 if (filteredArgumentTypes[i] instanceof TypeVariable<?>) {
1831 if (containsVariableTypeSameParametrizedTypeBound(((TypeVariable<?>) filteredArgumentTypes[i]),
1832 parameterizedType)) {
1833 indexesToRemove = ArrayUtils.add(indexesToRemove, i);
1834 }
1835 }
1836 }
1837 return indexesToRemove;
1838 }
1839
1840 private static boolean containsVariableTypeSameParametrizedTypeBound(final TypeVariable<?> typeVariable,
1841 final ParameterizedType parameterizedType) {
1842 return ArrayUtils.contains(typeVariable.getBounds(), parameterizedType);
1843 }
1844
1845 /**
1846 * Format a {@link WildcardType} as a {@link String}.
1877 * Formats a {@link WildcardType} as a {@link String}.
1878 *
18471879 * @param wildcardType {@code WildcardType} to format
18481880 * @return String
18491881 * @since 3.2
18611893 }
18621894
18631895 /**
1864 * Format a {@link GenericArrayType} as a {@link String}.
1865 * @param genericArrayType {@code GenericArrayType} to format
1866 * @return String
1867 * @since 3.2
1868 */
1869 private static String genericArrayTypeToString(final GenericArrayType genericArrayType) {
1870 return String.format("%s[]", toString(genericArrayType.getGenericComponentType()));
1871 }
1872
1873 /**
1874 * Append {@code types} to {@code builder} with separator {@code sep}.
1875 * @param builder destination
1876 * @param sep separator
1877 * @param types to append
1878 * @return {@code builder}
1879 * @since 3.2
1880 */
1881 private static <T> StringBuilder appendAllTo(final StringBuilder builder, final String sep,
1882 @SuppressWarnings("unchecked") final T... types) {
1883 Validate.notEmpty(Validate.noNullElements(types));
1884 if (types.length > 0) {
1885 builder.append(toString(types[0]));
1886 for (int i = 1; i < types.length; i++) {
1887 builder.append(sep).append(toString(types[i]));
1888 }
1889 }
1890 return builder;
1891 }
1892
1893 private static <T> String toString(final T object) {
1894 return object instanceof Type ? toString((Type) object) : object.toString();
1896 * Wraps the specified {@link Class} in a {@link Typed} wrapper.
1897 *
1898 * @param <T> generic type
1899 * @param type to wrap
1900 * @return Typed&lt;T&gt;
1901 * @since 3.2
1902 */
1903 public static <T> Typed<T> wrap(final Class<T> type) {
1904 return wrap((Type) type);
1905 }
1906
1907 /**
1908 * Wraps the specified {@link Type} in a {@link Typed} wrapper.
1909 *
1910 * @param <T> inferred generic type
1911 * @param type to wrap
1912 * @return Typed&lt;T&gt;
1913 * @since 3.2
1914 */
1915 public static <T> Typed<T> wrap(final Type type) {
1916 return () -> type;
1917 }
1918
1919 /**
1920 * {@code TypeUtils} instances should NOT be constructed in standard
1921 * programming. Instead, the class should be used as
1922 * {@code TypeUtils.isAssignable(cls, toClass)}.
1923 * <p>
1924 * This constructor is public to permit tools that require a JavaBean instance
1925 * to operate.
1926 * </p>
1927 */
1928 public TypeUtils() {
18951929 }
18961930
18971931 }
4343 * not to throw Exceptions, at least not checked Exceptions, AKA instances
4444 * of {@link Exception}. This enforces the use of constructs like
4545 * <pre>
46 * Consumer&lt;java.lang.reflect.Method&gt; consumer = (m) -&gt; {
46 * Consumer&lt;java.lang.reflect.Method&gt; consumer = m -&gt; {
4747 * try {
4848 * m.invoke(o, args);
4949 * } catch (Throwable t) {
6565 */
6666 public class Streams {
6767
68 /**
69 * A Collector type for arrays.
70 *
71 * @param <O> The array type.
72 */
6873 public static class ArrayCollector<O> implements Collector<O, List<O>, O[]> {
6974 private static final Set<Characteristics> characteristics = Collections.emptySet();
7075 private final Class<O> elementType;
7176
77 /**
78 * Constructs a new instance for the given element type.
79 *
80 * @param elementType The element type.
81 */
7282 public ArrayCollector(final Class<O> elementType) {
7383 this.elementType = elementType;
7484 }
2525 import java.util.Map;
2626 import java.util.Objects;
2727
28 import org.apache.commons.lang3.LocaleUtils;
2829 import org.apache.commons.lang3.ObjectUtils;
2930 import org.apache.commons.lang3.Validate;
3031
3738 * and the formats supported by {@code java.text.MessageFormat} can be overridden
3839 * at the format and/or format style level (see MessageFormat). A "format element"
3940 * embedded in the message pattern is specified (<b>()?</b> signifies optionality):<br>
40 * {@code {}<i>argument-number</i><b>(</b>{@code ,}<i>format-name</i><b>
41 * (</b>{@code ,}<i>format-style</i><b>)?)?</b>{@code }}
41 * <code>{</code><i>argument-number</i><b>(</b>{@code ,}<i>format-name</i><b>
42 * (</b>{@code ,}<i>format-style</i><b>)?)?</b><code>}</code>
4243 *
4344 * <p>
4445 * <i>format-name</i> and <i>format-style</i> values are trimmed of surrounding whitespace
117118 /**
118119 * Create a new ExtendedMessageFormat.
119120 *
120 * @param pattern the pattern to use, not null
121 * @param locale the locale to use, not null
122 * @param registry the registry of format factories, may be null
121 * @param pattern the pattern to use, not null.
122 * @param locale the locale to use.
123 * @param registry the registry of format factories, may be null.
123124 * @throws IllegalArgumentException in case of a bad pattern.
124125 */
125126 public ExtendedMessageFormat(final String pattern, final Locale locale, final Map<String, ? extends FormatFactory> registry) {
126127 super(DUMMY_PATTERN);
127 setLocale(locale);
128 setLocale(LocaleUtils.toLocale(locale));
128129 this.registry = registry;
129130 applyPattern(pattern);
130131 }
5353 * instance to operate.</p>
5454 */
5555 public FormattableUtils() {
56 super();
5756 }
5857
5958 //-----------------------------------------------------------------------
114114 * @param initialCapacity the initial capacity, zero or less will be converted to 32
115115 */
116116 public StrBuilder(int initialCapacity) {
117 super();
118117 if (initialCapacity <= 0) {
119118 initialCapacity = CAPACITY;
120119 }
128127 * @param str the string to copy, null treated as blank string
129128 */
130129 public StrBuilder(final String str) {
131 super();
132130 if (str == null) {
133131 buffer = new char[CAPACITY];
134132 } else {
284282 }
285283
286284 /**
285 * Checks is the string builder is not empty (convenience Collections API style method).
286 * <p>
287 * This method is the same as checking {@link #length()} and is provided to match the
288 * API of Collections.
289 *
290 * @return {@code true} if the size is greater than {@code 0}.
291 * @since 3.12.0
292 */
293 public boolean isNotEmpty() {
294 return size > 0;
295 }
296
297 /**
287298 * Clears the string builder (convenience Collections API style method).
288299 * <p>
289300 * This method does not reduce the size of the internal character buffer.
433444 *
434445 * @param readable object to read from
435446 * @return the number of characters read
436 * @throws IOException if an I/O error occurs
447 * @throws IOException if an I/O error occurs.
437448 *
438449 * @since 3.4
439450 * @see #appendTo(Appendable)
13911402 * @since 2.3
13921403 */
13931404 public StrBuilder appendSeparator(final char separator) {
1394 if (size() > 0) {
1405 if (isNotEmpty()) {
13951406 append(separator);
13961407 }
13971408 return this;
14091420 * @since 2.5
14101421 */
14111422 public StrBuilder appendSeparator(final char standard, final char defaultIfEmpty) {
1412 if (size() > 0) {
1423 if (isNotEmpty()) {
14131424 append(standard);
14141425 } else {
14151426 append(defaultIfEmpty);
29292940 * Default constructor.
29302941 */
29312942 StrBuilderTokenizer() {
2932 super();
29332943 }
29342944
29352945 /** {@inheritDoc} */
29662976 * Default constructor.
29672977 */
29682978 StrBuilderReader() {
2969 super();
29702979 }
29712980
29722981 /** {@inheritDoc} */
30533062 * Default constructor.
30543063 */
30553064 StrBuilderWriter() {
3056 super();
30573065 }
30583066
30593067 /** {@inheritDoc} */
3333 * @param <V> Unused.
3434 * @since 2.2
3535 * @deprecated as of 3.6, use commons-text
36 * <a href="https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/StringLookupFactory.html">
36 * <a href="https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/lookup/StringLookupFactory.html">
3737 * StringLookupFactory</a> instead
3838 */
3939 @Deprecated
9393 * Constructor.
9494 */
9595 protected StrLookup() {
96 super();
9796 }
9897
9998 /**
1717
1818 import java.util.Arrays;
1919
20 import org.apache.commons.lang3.ArraySorter;
2021 import org.apache.commons.lang3.StringUtils;
2122
2223 /**
2829 *
2930 * @since 2.2
3031 * @deprecated as of 3.6, use commons-text
31 * <a href="https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/StringMatcherFactory.html">
32 * <a href="https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/matcher/StringMatcherFactory.html">
3233 * StringMatcherFactory</a> instead
3334 */
3435 @Deprecated
216217 * Constructor.
217218 */
218219 protected StrMatcher() {
219 super();
220220 }
221221
222222 /**
284284 * @param chars the characters to match, must not be null
285285 */
286286 CharSetMatcher(final char[] chars) {
287 super();
288 this.chars = chars.clone();
289 Arrays.sort(this.chars);
287 this.chars = ArraySorter.sort(chars.clone());
290288 }
291289
292290 /**
318316 * @param ch the character to match
319317 */
320318 CharMatcher(final char ch) {
321 super();
322319 this.ch = ch;
323320 }
324321
351348 * @param str the string to match, must not be null
352349 */
353350 StringMatcher(final String str) {
354 super();
355351 chars = str.toCharArray();
356352 }
357353
395391 * Constructs a new instance of {@code NoMatcher}.
396392 */
397393 NoMatcher() {
398 super();
399394 }
400395
401396 /**
423418 * Constructs a new instance of {@code TrimMatcher}.
424419 */
425420 TrimMatcher() {
426 super();
427421 }
428422
429423 /**
172172 /**
173173 * Whether escapes should be preserved. Default is false;
174174 */
175 private boolean preserveEscapes = false;
175 private boolean preserveEscapes;
176176
177177 //-----------------------------------------------------------------------
178178 /**
772772 bufEnd);
773773 if (startMatchLen == 0) {
774774 pos++;
775 } else // found variable start marker
776 if (pos > offset && chars[pos - 1] == escape) {
777 // escaped
778 if (preserveEscapes) {
779 pos++;
780 continue;
781 }
782 buf.deleteCharAt(pos - 1);
783 chars = buf.buffer; // in case buffer was altered
784 lengthChange--;
785 altered = true;
786 bufEnd--;
775787 } else {
776 // found variable start marker
777 if (pos > offset && chars[pos - 1] == escape) {
778 // escaped
779 if (preserveEscapes) {
780 pos++;
788 // find suffix
789 final int startPos = pos;
790 pos += startMatchLen;
791 int endMatchLen = 0;
792 int nestedVarCount = 0;
793 while (pos < bufEnd) {
794 if (substitutionInVariablesEnabled
795 && (endMatchLen = pfxMatcher.isMatch(chars,
796 pos, offset, bufEnd)) != 0) {
797 // found a nested variable start
798 nestedVarCount++;
799 pos += endMatchLen;
781800 continue;
782801 }
783 buf.deleteCharAt(pos - 1);
784 chars = buf.buffer; // in case buffer was altered
785 lengthChange--;
786 altered = true;
787 bufEnd--;
788 } else {
789 // find suffix
790 final int startPos = pos;
791 pos += startMatchLen;
792 int endMatchLen = 0;
793 int nestedVarCount = 0;
794 while (pos < bufEnd) {
795 if (substitutionInVariablesEnabled
796 && (endMatchLen = pfxMatcher.isMatch(chars,
797 pos, offset, bufEnd)) != 0) {
798 // found a nested variable start
799 nestedVarCount++;
802
803 endMatchLen = suffMatcher.isMatch(chars, pos, offset,
804 bufEnd);
805 if (endMatchLen == 0) {
806 pos++;
807 } else {
808 // found variable end marker
809 if (nestedVarCount == 0) {
810 String varNameExpr = new String(chars, startPos
811 + startMatchLen, pos - startPos
812 - startMatchLen);
813 if (substitutionInVariablesEnabled) {
814 final StrBuilder bufName = new StrBuilder(varNameExpr);
815 substitute(bufName, 0, bufName.length());
816 varNameExpr = bufName.toString();
817 }
800818 pos += endMatchLen;
801 continue;
802 }
803
804 endMatchLen = suffMatcher.isMatch(chars, pos, offset,
805 bufEnd);
806 if (endMatchLen == 0) {
807 pos++;
808 } else {
809 // found variable end marker
810 if (nestedVarCount == 0) {
811 String varNameExpr = new String(chars, startPos
812 + startMatchLen, pos - startPos
813 - startMatchLen);
814 if (substitutionInVariablesEnabled) {
815 final StrBuilder bufName = new StrBuilder(varNameExpr);
816 substitute(bufName, 0, bufName.length());
817 varNameExpr = bufName.toString();
818 }
819 pos += endMatchLen;
820 final int endPos = pos;
821
822 String varName = varNameExpr;
823 String varDefaultValue = null;
824
825 if (valueDelimMatcher != null) {
826 final char [] varNameExprChars = varNameExpr.toCharArray();
827 int valueDelimiterMatchLen = 0;
828 for (int i = 0; i < varNameExprChars.length; i++) {
829 // if there's any nested variable when nested variable substitution disabled, then stop resolving name and default value.
830 if (!substitutionInVariablesEnabled
831 && pfxMatcher.isMatch(varNameExprChars, i, i, varNameExprChars.length) != 0) {
832 break;
833 }
834 if ((valueDelimiterMatchLen = valueDelimMatcher.isMatch(varNameExprChars, i)) != 0) {
835 varName = varNameExpr.substring(0, i);
836 varDefaultValue = varNameExpr.substring(i + valueDelimiterMatchLen);
837 break;
838 }
819 final int endPos = pos;
820
821 String varName = varNameExpr;
822 String varDefaultValue = null;
823
824 if (valueDelimMatcher != null) {
825 final char [] varNameExprChars = varNameExpr.toCharArray();
826 int valueDelimiterMatchLen = 0;
827 for (int i = 0; i < varNameExprChars.length; i++) {
828 // if there's any nested variable when nested variable substitution disabled, then stop resolving name and default value.
829 if (!substitutionInVariablesEnabled
830 && pfxMatcher.isMatch(varNameExprChars, i, i, varNameExprChars.length) != 0) {
831 break;
832 }
833 if ((valueDelimiterMatchLen = valueDelimMatcher.isMatch(varNameExprChars, i)) != 0) {
834 varName = varNameExpr.substring(0, i);
835 varDefaultValue = varNameExpr.substring(i + valueDelimiterMatchLen);
836 break;
839837 }
840838 }
841
842 // on the first call initialize priorVariables
843 if (priorVariables == null) {
844 priorVariables = new ArrayList<>();
845 priorVariables.add(new String(chars,
846 offset, length));
847 }
848
849 // handle cyclic substitution
850 checkCyclicSubstitution(varName, priorVariables);
851 priorVariables.add(varName);
852
853 // resolve the variable
854 String varValue = resolveVariable(varName, buf,
855 startPos, endPos);
856 if (varValue == null) {
857 varValue = varDefaultValue;
858 }
859 if (varValue != null) {
860 // recursive replace
861 final int varLen = varValue.length();
862 buf.replace(startPos, endPos, varValue);
863 altered = true;
864 int change = substitute(buf, startPos,
865 varLen, priorVariables);
866 change = change
867 + varLen - (endPos - startPos);
868 pos += change;
869 bufEnd += change;
870 lengthChange += change;
871 chars = buf.buffer; // in case buffer was
872 // altered
873 }
874
875 // remove variable from the cyclic stack
876 priorVariables
877 .remove(priorVariables.size() - 1);
878 break;
879839 }
880 nestedVarCount--;
881 pos += endMatchLen;
840
841 // on the first call initialize priorVariables
842 if (priorVariables == null) {
843 priorVariables = new ArrayList<>();
844 priorVariables.add(new String(chars,
845 offset, length));
846 }
847
848 // handle cyclic substitution
849 checkCyclicSubstitution(varName, priorVariables);
850 priorVariables.add(varName);
851
852 // resolve the variable
853 String varValue = resolveVariable(varName, buf,
854 startPos, endPos);
855 if (varValue == null) {
856 varValue = varDefaultValue;
857 }
858 if (varValue != null) {
859 // recursive replace
860 final int varLen = varValue.length();
861 buf.replace(startPos, endPos, varValue);
862 altered = true;
863 int change = substitute(buf, startPos,
864 varLen, priorVariables);
865 change = change
866 + varLen - (endPos - startPos);
867 pos += change;
868 bufEnd += change;
869 lengthChange += change;
870 chars = buf.buffer; // in case buffer was
871 // altered
872 }
873
874 // remove variable from the cyclic stack
875 priorVariables
876 .remove(priorVariables.size() - 1);
877 break;
882878 }
879 nestedVarCount--;
880 pos += endMatchLen;
883881 }
884882 }
885883 }
125125 private StrMatcher trimmerMatcher = StrMatcher.noneMatcher();
126126
127127 /** Whether to return empty tokens as null */
128 private boolean emptyAsNull = false;
128 private boolean emptyAsNull;
129129 /** Whether to ignore empty tokens */
130130 private boolean ignoreEmptyTokens = true;
131131
239239 * This constructor is normally used with {@link #reset(String)}.
240240 */
241241 public StrTokenizer() {
242 super();
243242 this.chars = null;
244243 }
245244
250249 * @param input the string which is to be parsed
251250 */
252251 public StrTokenizer(final String input) {
253 super();
254252 if (input != null) {
255253 chars = input.toCharArray();
256254 } else {
324322 * @param input the string which is to be parsed, not cloned
325323 */
326324 public StrTokenizer(final char[] input) {
327 super();
328325 this.chars = ArrayUtils.clone(input);
329326 }
330327
4545 * instance to operate.</p>
4646 */
4747 public WordUtils() {
48 super();
4948 }
5049
5150 // Wrapping
315314 wrappedLine.append(newLineStr);
316315 offset = spaceToWrapAt + 1;
317316
317 } else // really long word or URL
318 if (wrapLongWords) {
319 // wrap really long word one line at a time
320 wrappedLine.append(str, offset, wrapLength + offset);
321 wrappedLine.append(newLineStr);
322 offset += wrapLength;
318323 } else {
319 // really long word or URL
320 if (wrapLongWords) {
321 // wrap really long word one line at a time
322 wrappedLine.append(str, offset, wrapLength + offset);
324 // do not wrap really long word, just extend beyond limit
325 matcher = patternToWrapOn.matcher(str.substring(offset + wrapLength));
326 if (matcher.find()) {
327 spaceToWrapAt = matcher.start() + offset + wrapLength;
328 }
329
330 if (spaceToWrapAt >= 0) {
331 wrappedLine.append(str, offset, spaceToWrapAt);
323332 wrappedLine.append(newLineStr);
324 offset += wrapLength;
333 offset = spaceToWrapAt + 1;
325334 } else {
326 // do not wrap really long word, just extend beyond limit
327 matcher = patternToWrapOn.matcher(str.substring(offset + wrapLength));
328 if (matcher.find()) {
329 spaceToWrapAt = matcher.start() + offset + wrapLength;
330 }
331
332 if (spaceToWrapAt >= 0) {
333 wrappedLine.append(str, offset, spaceToWrapAt);
334 wrappedLine.append(newLineStr);
335 offset = spaceToWrapAt + 1;
336 } else {
337 wrappedLine.append(str, offset, str.length());
338 offset = inputLineLength;
339 }
335 wrappedLine.append(str, offset, str.length());
336 offset = inputLineLength;
340337 }
341338 }
342339 }
2626 *
2727 * @since 3.0
2828 * @deprecated as of 3.6, use commons-text
29 * <a href="https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/AggregateTranslator.html">
29 * <a href="https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/translate/AggregateTranslator.html">
3030 * AggregateTranslator</a> instead
3131 */
3232 @Deprecated
107107 if (codepoint < below || codepoint > above) {
108108 return false;
109109 }
110 } else {
111 if (codepoint >= below && codepoint <= above) {
112 return false;
113 }
110 } else if (codepoint >= below && codepoint <= above) {
111 return false;
114112 }
115113
116114 out.write("&#");
2525 * Translate XML numeric entities of the form &amp;#[xX]?\d+;? to
2626 * the specific codepoint.
2727 *
28 * Note that the semi-colon is optional.
28 * Note that the semicolon is optional.
2929 *
3030 * @since 3.0
3131 * @deprecated as of 3.6, use commons-text
3535 @Deprecated
3636 public class NumericEntityUnescaper extends CharSequenceTranslator {
3737
38 /** Enumerates NumericEntityUnescaper options for unescaping. */
3839 public enum OPTION {
39 semiColonRequired, semiColonOptional, errorIfNoSemiColon
40
41 /**
42 * Require a semicolon.
43 */
44 semiColonRequired,
45
46 /**
47 * Do not require a semicolon.
48 */
49 semiColonOptional,
50
51 /**
52 * Throw an exception if a semicolon is missing.
53 */
54 errorIfNoSemiColon
4055 }
4156
4257 // TODO?: Create an OptionsSet class to hide some of the conditional logic below
4661 * Create a UnicodeUnescaper.
4762 *
4863 * The constructor takes a list of options, only one type of which is currently
49 * available (whether to allow, error or ignore the semi-colon on the end of a
64 * available (whether to allow, error or ignore the semicolon on the end of a
5065 * numeric entity to being missing).
5166 *
5267 * For example, to support numeric entities without a ';':
117132 }
118133 }
119134
120 int entityValue;
135 final int entityValue;
121136 try {
122137 if (isHex) {
123138 entityValue = Integer.parseInt(input.subSequence(start, end).toString(), 16);
107107 if (codepoint < below || codepoint > above) {
108108 return false;
109109 }
110 } else {
111 if (codepoint >= below && codepoint <= above) {
112 return false;
113 }
110 } else if (codepoint >= below && codepoint <= above) {
111 return false;
114112 }
115113
116114 // TODO: Handle potential + sign per various Unicode escape implementations
3333 */
3434 @Override
3535 public boolean translate(final int codepoint, final Writer out) throws IOException {
36 if (codepoint >= Character.MIN_SURROGATE && codepoint <= Character.MAX_SURROGATE) {
37 // It's a surrogate. Write nothing and say we've translated.
38 return true;
39 }
36 // true: It's a surrogate. Write nothing and say we've translated.
37 return codepoint >= Character.MIN_SURROGATE && codepoint <= Character.MAX_SURROGATE;
4038 // It's not a surrogate. Don't translate it.
41 return false;
4239 }
4340 }
4441
3939 * @param calendar A Calendar.
4040 */
4141 public CalendarUtils(final Calendar calendar) {
42 super();
4342 this.calendar = Objects.requireNonNull(calendar, "calendar");
4443 }
4544
200200 * to operate.</p>
201201 */
202202 public DateFormatUtils() {
203 super();
204203 }
205204
206205 /**
2525 import java.util.TimeZone;
2626 import java.util.concurrent.TimeUnit;
2727
28 import org.apache.commons.lang3.LocaleUtils;
2829 import org.apache.commons.lang3.Validate;
2930
3031 /**
4445 * <p>
4546 * Several methods are provided for adding to {@code Date} objects, of the form
4647 * {@code addXXX(Date date, int amount)}. It is important to note these methods
47 * use a {@code Calendar} internally (with default timezone and locale) and may
48 * use a {@code Calendar} internally (with default time zone and locale) and may
4849 * be affected by changes to daylight saving time (DST).
4950 * </p>
5051 *
145146 * instance to operate.</p>
146147 */
147148 public DateUtils() {
148 super();
149149 }
150150
151151 //-----------------------------------------------------------------------
367367 }
368368
369369 final TimeZone tz = TimeZone.getDefault();
370 final Locale lcl = locale == null ? Locale.getDefault() : locale;
370 final Locale lcl = LocaleUtils.toLocale(locale);
371371 final ParsePosition pos = new ParsePosition(0);
372372 final Calendar calendar = Calendar.getInstance(tz, lcl);
373373 calendar.setLenient(lenient);
686686 * 28 Mar 2002 14:00:00.000. If this was passed with MONTH, it
687687 * would return 1 April 2002 0:00:00.000.</p>
688688 *
689 * <p>For a date in a timezone that handles the change to daylight
689 * <p>For a date in a time zone that handles the change to daylight
690690 * saving time, rounding to Calendar.HOUR_OF_DAY will behave as follows.
691691 * Suppose daylight saving time begins at 02:00 on March 30. Rounding a
692692 * date that crosses this time would produce the following values:
720720 * 28 Mar 2002 14:00:00.000. If this was passed with MONTH, it
721721 * would return 1 April 2002 0:00:00.000.</p>
722722 *
723 * <p>For a date in a timezone that handles the change to daylight
723 * <p>For a date in a time zone that handles the change to daylight
724724 * saving time, rounding to Calendar.HOUR_OF_DAY will behave as follows.
725725 * Suppose daylight saving time begins at 02:00 on March 30. Rounding a
726726 * date that crosses this time would produce the following values:
760760 * 28 Mar 2002 14:00:00.000. If this was passed with MONTH, it
761761 * would return 1 April 2002 0:00:00.000.</p>
762762 *
763 * <p>For a date in a timezone that handles the change to daylight
763 * <p>For a date in a time zone that handles the change to daylight
764764 * saving time, rounding to Calendar.HOUR_OF_DAY will behave as follows.
765765 * Suppose daylight saving time begins at 02:00 on March 30. Rounding a
766766 * date that crosses this time would produce the following values:
17851785 }
17861786
17871787 private static void validateDateNotNull(final Date date) {
1788 Validate.notNull(date, "The date must not be null");
1788 Validate.notNull(date, "date");
17891789 }
17901790
17911791 //-----------------------------------------------------------------------
18031803 * @param endFinal end date (inclusive)
18041804 */
18051805 DateIterator(final Calendar startFinal, final Calendar endFinal) {
1806 super();
18071806 this.endFinal = endFinal;
18081807 spot = startFinal;
18091808 spot.add(Calendar.DATE, -1);
5656 * to operate.</p>
5757 */
5858 public DurationFormatUtils() {
59 super();
6059 }
6160
6261 /**
254253 /**
255254 * <p>Formats the time gap as a string, using the specified format.
256255 * Padding the left hand side of numbers with zeroes is optional and
257 * the timezone may be specified. </p>
256 * the time zone may be specified. </p>
258257 *
259258 * <p>When calculating the difference between months/days, it chooses to
260259 * calculate months first. So when working out the number of months and
288287
289288 final Token[] tokens = lexx(format);
290289
291 // timezones get funky around 0, so normalizing everything to GMT
290 // time zones get funky around 0, so normalizing everything to GMT
292291 // stops the hours being off
293292 final Calendar start = Calendar.getInstance(timezone);
294293 start.setTime(new Date(startMillis));
343342 } else {
344343 // there are no M's in the format string
345344
346 if ( !Token.containsTokenWithValue(tokens, y) ) {
345 if (!Token.containsTokenWithValue(tokens, y)) {
347346 int target = end.get(Calendar.YEAR);
348347 if (months < 0) {
349348 // target is end-year -1
368367 years = 0;
369368 }
370369
371 while ( start.get(Calendar.MONTH) != end.get(Calendar.MONTH) ) {
370 while (start.get(Calendar.MONTH) != end.get(Calendar.MONTH)) {
372371 days += start.getActualMaximum(Calendar.DAY_OF_MONTH);
373372 start.add(Calendar.MONTH, 1);
374373 }
431430 final int count = token.getCount();
432431 if (value instanceof StringBuilder) {
433432 buffer.append(value.toString());
434 } else {
435 if (value.equals(y)) {
436 buffer.append(paddedValue(years, padWithZeros, count));
437 lastOutputSeconds = false;
438 } else if (value.equals(M)) {
439 buffer.append(paddedValue(months, padWithZeros, count));
440 lastOutputSeconds = false;
441 } else if (value.equals(d)) {
442 buffer.append(paddedValue(days, padWithZeros, count));
443 lastOutputSeconds = false;
444 } else if (value.equals(H)) {
445 buffer.append(paddedValue(hours, padWithZeros, count));
446 lastOutputSeconds = false;
447 } else if (value.equals(m)) {
448 buffer.append(paddedValue(minutes, padWithZeros, count));
449 lastOutputSeconds = false;
450 } else if (value.equals(s)) {
451 buffer.append(paddedValue(seconds, padWithZeros, count));
452 lastOutputSeconds = true;
453 } else if (value.equals(S)) {
454 if (lastOutputSeconds) {
455 // ensure at least 3 digits are displayed even if padding is not selected
456 final int width = padWithZeros ? Math.max(3, count) : 3;
457 buffer.append(paddedValue(milliseconds, true, width));
458 } else {
459 buffer.append(paddedValue(milliseconds, padWithZeros, count));
460 }
461 lastOutputSeconds = false;
462 }
433 } else if (value.equals(y)) {
434 buffer.append(paddedValue(years, padWithZeros, count));
435 lastOutputSeconds = false;
436 } else if (value.equals(M)) {
437 buffer.append(paddedValue(months, padWithZeros, count));
438 lastOutputSeconds = false;
439 } else if (value.equals(d)) {
440 buffer.append(paddedValue(days, padWithZeros, count));
441 lastOutputSeconds = false;
442 } else if (value.equals(H)) {
443 buffer.append(paddedValue(hours, padWithZeros, count));
444 lastOutputSeconds = false;
445 } else if (value.equals(m)) {
446 buffer.append(paddedValue(minutes, padWithZeros, count));
447 lastOutputSeconds = false;
448 } else if (value.equals(s)) {
449 buffer.append(paddedValue(seconds, padWithZeros, count));
450 lastOutputSeconds = true;
451 } else if (value.equals(S)) {
452 if (lastOutputSeconds) {
453 // ensure at least 3 digits are displayed even if padding is not selected
454 final int width = padWithZeros ? Math.max(3, count) : 3;
455 buffer.append(paddedValue(milliseconds, true, width));
456 } else {
457 buffer.append(paddedValue(milliseconds, padWithZeros, count));
458 }
459 lastOutputSeconds = false;
463460 }
464461 }
465462 return buffer.toString();
479476 return padWithZeros ? StringUtils.leftPad(longString, count, '0') : longString;
480477 }
481478
482 static final Object y = "y";
483 static final Object M = "M";
484 static final Object d = "d";
485 static final Object H = "H";
486 static final Object m = "m";
487 static final Object s = "s";
488 static final Object S = "S";
479 static final String y = "y";
480 static final String M = "M";
481 static final String d = "d";
482 static final String H = "H";
483 static final String m = "m";
484 static final String s = "s";
485 static final String S = "S";
489486
490487 /**
491488 * Parses a classic date format string into Tokens
507504 buffer.append(ch); // buffer can't be null if inLiteral is true
508505 continue;
509506 }
510 Object value = null;
507 String value = null;
511508 switch (ch) {
512509 // TODO: Need to handle escaping of '
513510 case '\'':
563560 if (inLiteral) { // i.e. we have not found the end of the literal
564561 throw new IllegalArgumentException("Unmatched quote in format: " + format);
565562 }
566 return list.toArray(new Token[0]);
567 }
568
569 //-----------------------------------------------------------------------
563 return list.toArray(Token.EMPTY_ARRAY);
564 }
565
570566 /**
571567 * Element that is parsed from the format pattern.
572568 */
573569 static class Token {
570
571 /** Empty array. */
572 private static final Token[] EMPTY_ARRAY = new Token[0];
574573
575574 /**
576575 * Helper method to determine if a set of tokens contain a value
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.commons.lang3.time;
18
19 import java.time.Duration;
20 import java.time.temporal.ChronoUnit;
21 import java.util.Objects;
22 import java.util.concurrent.TimeUnit;
23
24 import org.apache.commons.lang3.ObjectUtils;
25 import org.apache.commons.lang3.Range;
26 import org.apache.commons.lang3.function.FailableBiConsumer;
27 import org.apache.commons.lang3.math.NumberUtils;
28
29 /**
30 * Utilities for {@link Duration}.
31 *
32 * @since 3.12.0
33 */
34 public class DurationUtils {
35
36 /**
37 * An Integer Range that accepts Longs.
38 */
39 static final Range<Long> LONG_TO_INT_RANGE = Range.between(NumberUtils.LONG_INT_MIN_VALUE,
40 NumberUtils.LONG_INT_MAX_VALUE);
41
42 /**
43 * Accepts the function with the duration as a long milliseconds and int nanoseconds.
44 *
45 * @param <T> The function exception.
46 * @param consumer Accepting function.
47 * @param duration The duration to pick apart.
48 * @throws T See the function signature.
49 */
50 public static <T extends Throwable> void accept(final FailableBiConsumer<Long, Integer, T> consumer, final Duration duration)
51 throws T {
52 if (consumer != null && duration != null) {
53 consumer.accept(duration.toMillis(), getNanosOfMiili(duration));
54 }
55 }
56
57 /**
58 * Gets the nanosecond part of a Duration converted to milliseconds.
59 * <p>
60 * Handy when calling an API that takes a long of milliseconds and an int of nanoseconds. For example,
61 * {@link Object#wait(long, int)} and {@link Thread#sleep(long, int)}.
62 * </p>
63 * <p>
64 * Note that is this different from {@link Duration#getNano()} because a duration are seconds and nanoseconds.
65 * </p>
66 *
67 * @param duration The duration to query.
68 * @return nanoseconds between 0 and 999,999.
69 */
70 public static int getNanosOfMiili(final Duration duration) {
71 return duration.getNano() % 1_000_000;
72 }
73
74 /**
75 * Tests whether the given Duration is positive (&gt;0).
76 *
77 * @param duration the value to test
78 * @return whether the given Duration is positive (&gt;0).
79 */
80 public static boolean isPositive(final Duration duration) {
81 return !duration.isNegative() && !duration.isZero();
82 }
83
84 /**
85 * Converts a {@link TimeUnit} to a {@link ChronoUnit}.
86 *
87 * @param timeUnit A non-null TimeUnit.
88 * @return The corresponding ChronoUnit.
89 */
90 static ChronoUnit toChronoUnit(final TimeUnit timeUnit) {
91 // TODO when using Java >= 9: Use TimeUnit.toChronoUnit().
92 switch (Objects.requireNonNull(timeUnit)) {
93 case NANOSECONDS:
94 return ChronoUnit.NANOS;
95 case MICROSECONDS:
96 return ChronoUnit.MICROS;
97 case MILLISECONDS:
98 return ChronoUnit.MILLIS;
99 case SECONDS:
100 return ChronoUnit.SECONDS;
101 case MINUTES:
102 return ChronoUnit.MINUTES;
103 case HOURS:
104 return ChronoUnit.HOURS;
105 case DAYS:
106 return ChronoUnit.DAYS;
107 default:
108 throw new IllegalArgumentException(timeUnit.toString());
109 }
110 }
111
112 /**
113 * Converts an amount and TimeUnit into a Duration.
114 *
115 * @param amount the amount of the duration, measured in terms of the unit, positive or negative
116 * @param timeUnit the unit that the duration is measured in, must have an exact duration, not null
117 * @return a Duration.
118 */
119 public static Duration toDuration(final long amount, final TimeUnit timeUnit) {
120 return Duration.of(amount, toChronoUnit(timeUnit));
121 }
122
123 /**
124 * Converts a Duration to milliseconds bound to an int (instead of a long).
125 * <p>
126 * Handy for low-level APIs that take millisecond timeouts in ints rather than longs.
127 * </p>
128 * <ul>
129 * <li>If the duration milliseconds are greater than {@link Integer#MAX_VALUE}, then return
130 * {@link Integer#MAX_VALUE}.</li>
131 * <li>If the duration milliseconds are lesser than {@link Integer#MIN_VALUE}, then return
132 * {@link Integer#MIN_VALUE}.</li>
133 * </ul>
134 *
135 * @param duration The duration to convert, not null.
136 * @return int milliseconds.
137 */
138 public static int toMillisInt(final Duration duration) {
139 Objects.requireNonNull(duration, "duration");
140 // intValue() does not do a narrowing conversion here
141 return LONG_TO_INT_RANGE.fit(Long.valueOf(duration.toMillis())).intValue();
142 }
143
144 /**
145 * Returns the given non-null value or {@link Duration#ZERO} if null.
146 *
147 * @param duration The duration to test.
148 * @return The given duration or {@link Duration#ZERO}.
149 */
150 public static Duration zeroIfNull(final Duration duration) {
151 return ObjectUtils.defaultIfNull(duration, Duration.ZERO);
152 }
153
154 }
9898 */
9999 public static final int SHORT = DateFormat.SHORT;
100100
101 private static final FormatCache<FastDateFormat> cache= new FormatCache<FastDateFormat>() {
101 private static final FormatCache<FastDateFormat> cache = new FormatCache<FastDateFormat>() {
102102 @Override
103103 protected FastDateFormat createInstance(final String pattern, final TimeZone timeZone, final Locale locale) {
104104 return new FastDateFormat(pattern, timeZone, locale);
394394 * @throws NullPointerException if pattern, timeZone, or locale is null.
395395 */
396396 protected FastDateFormat(final String pattern, final TimeZone timeZone, final Locale locale, final Date centuryStart) {
397 printer= new FastDatePrinter(pattern, timeZone, locale);
398 parser= new FastDateParser(pattern, timeZone, locale, centuryStart);
397 printer = new FastDatePrinter(pattern, timeZone, locale);
398 parser = new FastDateParser(pattern, timeZone, locale, centuryStart);
399399 }
400400
401401 // Format methods
3737 import java.util.concurrent.ConcurrentMap;
3838 import java.util.regex.Matcher;
3939 import java.util.regex.Pattern;
40
41 import org.apache.commons.lang3.LocaleUtils;
4042
4143 /**
4244 * <p>FastDateParser is a fast and thread-safe version of
121123 *
122124 * @since 3.5
123125 */
124 protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale, final Date centuryStart) {
126 protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale,
127 final Date centuryStart) {
125128 this.pattern = pattern;
126129 this.timeZone = timeZone;
127 this.locale = locale;
128
129 final Calendar definingCalendar = Calendar.getInstance(timeZone, locale);
130
131 int centuryStartYear;
132 if (centuryStart!=null) {
130 this.locale = LocaleUtils.toLocale(locale);
131
132 final Calendar definingCalendar = Calendar.getInstance(timeZone, this.locale);
133
134 final int centuryStartYear;
135 if (centuryStart != null) {
133136 definingCalendar.setTime(centuryStart);
134 centuryStartYear= definingCalendar.get(Calendar.YEAR);
135 } else if (locale.equals(JAPANESE_IMPERIAL)) {
136 centuryStartYear= 0;
137 centuryStartYear = definingCalendar.get(Calendar.YEAR);
138 } else if (this.locale.equals(JAPANESE_IMPERIAL)) {
139 centuryStartYear = 0;
137140 } else {
138141 // from 80 years ago to 20 years from now
139142 definingCalendar.setTime(new Date());
140 centuryStartYear= definingCalendar.get(Calendar.YEAR)-80;
141 }
142 century= centuryStartYear / 100 * 100;
143 startYear= centuryStartYear - century;
143 centuryStartYear = definingCalendar.get(Calendar.YEAR) - 80;
144 }
145 century = centuryStartYear / 100 * 100;
146 startYear = centuryStartYear - century;
144147
145148 init(definingCalendar);
146149 }
147150
148151 /**
149 * Initialize derived fields from defining fields.
152 * Initializes derived fields from defining fields.
150153 * This is called from constructor and from readObject (de-serialization)
151154 *
152155 * @param definingCalendar the {@link java.util.Calendar} instance used to initialize this FastDateParser
157160 final StrategyParser fm = new StrategyParser(definingCalendar);
158161 for (;;) {
159162 final StrategyAndWidth field = fm.getNextStrategy();
160 if (field==null) {
163 if (field == null) {
161164 break;
162165 }
163166 patterns.add(field);
171174 * Holds strategy and field width
172175 */
173176 private static class StrategyAndWidth {
177
174178 final Strategy strategy;
175179 final int width;
176180
185189 }
186190 final Strategy nextStrategy = lt.next().strategy;
187191 lt.previous();
188 return nextStrategy.isNumber() ?width :0;
189 }
192 return nextStrategy.isNumber() ? width : 0;
193 }
194
195 @Override
196 public String toString() {
197 return "StrategyAndWidth [strategy=" + strategy + ", width=" + width + "]";
198 }
190199 }
191200
192201 /**
283292 // Basics
284293 //-----------------------------------------------------------------------
285294 /**
286 * <p>Compare another object for equality with this object.</p>
295 * <p>Compares another object for equality with this object.</p>
287296 *
288297 * @param obj the object to compare to
289298 * @return {@code true}if equal to this instance
294303 return false;
295304 }
296305 final FastDateParser other = (FastDateParser) obj;
297 return pattern.equals(other.pattern)
298 && timeZone.equals(other.timeZone)
299 && locale.equals(other.locale);
300 }
301
302 /**
303 * <p>Return a hash code compatible with equals.</p>
306 return pattern.equals(other.pattern) && timeZone.equals(other.timeZone) && locale.equals(other.locale);
307 }
308
309 /**
310 * <p>Returns a hash code compatible with equals.</p>
304311 *
305312 * @return a hash code compatible with equals
306313 */
310317 }
311318
312319 /**
313 * <p>Get a string version of this formatter.</p>
320 * <p>Gets a string version of this formatter.</p>
314321 *
315322 * @return a debugging string
316323 */
317324 @Override
318325 public String toString() {
319 return "FastDateParser[" + pattern + "," + locale + "," + timeZone.getID() + "]";
326 return "FastDateParser[" + pattern + ", " + locale + ", " + timeZone.getID() + "]";
327 }
328
329 /**
330 * Converts all state of this instance to a String handy for debugging.
331 *
332 * @return a string.
333 * @since 3.12.0
334 */
335 public String toStringAll() {
336 return "FastDateParser [pattern=" + pattern + ", timeZone=" + timeZone + ", locale=" + locale + ", century="
337 + century + ", startYear=" + startYear + ", patterns=" + patterns + "]";
320338 }
321339
322340 // Serializing
323 //-----------------------------------------------------------------------
324 /**
325 * Create the object after serialization. This implementation reinitializes the
341 /**
342 * Creates the object after serialization. This implementation reinitializes the
326343 * transient properties.
327344 *
328345 * @param in ObjectInputStream from which the object is being deserialized.
350367 @Override
351368 public Date parse(final String source) throws ParseException {
352369 final ParsePosition pp = new ParsePosition(0);
353 final Date date= parse(source, pp);
370 final Date date = parse(source, pp);
354371 if (date == null) {
355372 // Add a note re supported date range
356373 if (locale.equals(JAPANESE_IMPERIAL)) {
357 throw new ParseException(
358 "(The " +locale + " locale does not support dates before 1868 AD)\n" +
359 "Unparseable date: \""+source, pp.getErrorIndex());
360 }
361 throw new ParseException("Unparseable date: "+source, pp.getErrorIndex());
374 throw new ParseException("(The " + locale + " locale does not support dates before 1868 AD)\n"
375 + "Unparseable date: \"" + source, pp.getErrorIndex());
376 }
377 throw new ParseException("Unparseable date: " + source, pp.getErrorIndex());
362378 }
363379 return date;
364380 }
386402 @Override
387403 public Date parse(final String source, final ParsePosition pos) {
388404 // timing tests indicate getting new instance is 19% faster than cloning
389 final Calendar cal= Calendar.getInstance(timeZone, locale);
405 final Calendar cal = Calendar.getInstance(timeZone, locale);
390406 cal.clear();
391407
392408 return parse(source, pos, cal) ? cal.getTime() : null;
393409 }
394410
395411 /**
396 * Parse a formatted date string according to the format. Updates the Calendar with parsed fields.
412 * Parses a formatted date string according to the format. Updates the Calendar with parsed fields.
397413 * Upon success, the ParsePosition index is updated to indicate how much of the source text was consumed.
398414 * Not all source text needs to be consumed. Upon parse failure, ParsePosition error index is updated to
399415 * the offset of the source text which does not match the supplied format.
451467
452468 /**
453469 * Gets the short and long values displayed for a field
454 * @param cal The calendar to obtain the short and long values
470 * @param calendar The calendar to obtain the short and long values
455471 * @param locale The locale of display names
456472 * @param field The field of interest
457473 * @param regex The regular expression to build
458474 * @return The map of string display names to field values
459475 */
460 private static Map<String, Integer> appendDisplayNames(final Calendar cal, final Locale locale, final int field, final StringBuilder regex) {
476 private static Map<String, Integer> appendDisplayNames(final Calendar calendar, Locale locale, final int field,
477 final StringBuilder regex) {
461478 final Map<String, Integer> values = new HashMap<>();
462
463 final Map<String, Integer> displayNames = cal.getDisplayNames(field, Calendar.ALL_STYLES, locale);
479 locale = LocaleUtils.toLocale(locale);
480 final Map<String, Integer> displayNames = calendar.getDisplayNames(field, Calendar.ALL_STYLES, locale);
464481 final TreeSet<String> sorted = new TreeSet<>(LONGER_FIRST_LOWERCASE);
465482 for (final Map.Entry<String, Integer> displayName : displayNames.entrySet()) {
466483 final String key = displayName.getKey().toLowerCase(locale);
475492 }
476493
477494 /**
478 * Adjust dates to be within appropriate century
495 * Adjusts dates to be within appropriate century
479496 * @param twoDigitYear The year to adjust
480497 * @return A value between centuryStart(inclusive) to centuryStart+100(exclusive)
481498 */
488505 * A strategy to parse a single field from the parsing pattern
489506 */
490507 private abstract static class Strategy {
491 /**
492 * Is this field a number?
493 * The default implementation returns false.
508
509 /**
510 * Is this field a number? The default implementation returns false.
494511 *
495512 * @return true, if field is a number
496513 */
498515 return false;
499516 }
500517
501 abstract boolean parse(FastDateParser parser, Calendar calendar, String source, ParsePosition pos, int maxWidth);
518 abstract boolean parse(FastDateParser parser, Calendar calendar, String source, ParsePosition pos,
519 int maxWidth);
502520 }
503521
504522 /**
506524 */
507525 private abstract static class PatternStrategy extends Strategy {
508526
509 private Pattern pattern;
527 Pattern pattern;
510528
511529 void createPattern(final StringBuilder regex) {
512530 createPattern(regex.toString());
517535 }
518536
519537 /**
520 * Is this field a number?
521 * The default implementation returns false.
538 * Is this field a number? The default implementation returns false.
522539 *
523540 * @return true, if field is a number
524541 */
528545 }
529546
530547 @Override
531 boolean parse(final FastDateParser parser, final Calendar calendar, final String source, final ParsePosition pos, final int maxWidth) {
548 boolean parse(final FastDateParser parser, final Calendar calendar, final String source,
549 final ParsePosition pos, final int maxWidth) {
532550 final Matcher matcher = pattern.matcher(source.substring(pos.getIndex()));
533551 if (!matcher.lookingAt()) {
534552 pos.setErrorIndex(pos.getIndex());
539557 return true;
540558 }
541559
542 abstract void setCalendar(FastDateParser parser, Calendar cal, String value);
543 }
544
545 /**
546 * Obtain a Strategy given a field from a SimpleDateFormat pattern
560 abstract void setCalendar(FastDateParser parser, Calendar calendar, String value);
561
562 /**
563 * Converts this instance to a handy debug string.
564 *
565 * @since 3.12.0
566 */
567 @Override
568 public String toString() {
569 return getClass().getSimpleName() + " [pattern=" + pattern + "]";
570 }
571
572 }
573
574 /**
575 * Gets a Strategy given a field from a SimpleDateFormat pattern
547576 * @param f A sub-sequence of the SimpleDateFormat pattern
548577 * @param definingCalendar The calendar to obtain the short and long values
549578 * @return The Strategy that will handle parsing for the field
550579 */
551580 private Strategy getStrategy(final char f, final int width, final Calendar definingCalendar) {
552 switch(f) {
581 switch (f) {
553582 default:
554 throw new IllegalArgumentException("Format '"+f+"' not supported");
583 throw new IllegalArgumentException("Format '" + f + "' not supported");
555584 case 'D':
556585 return DAY_OF_YEAR_STRATEGY;
557586 case 'E':
560589 return DAY_OF_WEEK_IN_MONTH_STRATEGY;
561590 case 'G':
562591 return getLocaleSpecificStrategy(Calendar.ERA, definingCalendar);
563 case 'H': // Hour in day (0-23)
592 case 'H': // Hour in day (0-23)
564593 return HOUR_OF_DAY_STRATEGY;
565 case 'K': // Hour in am/pm (0-11)
594 case 'K': // Hour in am/pm (0-11)
566595 return HOUR_STRATEGY;
567596 case 'M':
568 return width>=3 ?getLocaleSpecificStrategy(Calendar.MONTH, definingCalendar) :NUMBER_MONTH_STRATEGY;
597 return width >= 3 ? getLocaleSpecificStrategy(Calendar.MONTH, definingCalendar) : NUMBER_MONTH_STRATEGY;
569598 case 'S':
570599 return MILLISECOND_STRATEGY;
571600 case 'W':
574603 return getLocaleSpecificStrategy(Calendar.AM_PM, definingCalendar);
575604 case 'd':
576605 return DAY_OF_MONTH_STRATEGY;
577 case 'h': // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0
606 case 'h': // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0
578607 return HOUR12_STRATEGY;
579 case 'k': // Hour in day (1-24), i.e. midnight is 24, not 0
608 case 'k': // Hour in day (1-24), i.e. midnight is 24, not 0
580609 return HOUR24_OF_DAY_STRATEGY;
581610 case 'm':
582611 return MINUTE_STRATEGY;
588617 return WEEK_OF_YEAR_STRATEGY;
589618 case 'y':
590619 case 'Y':
591 return width>2 ?LITERAL_YEAR_STRATEGY :ABBREVIATED_YEAR_STRATEGY;
620 return width > 2 ? LITERAL_YEAR_STRATEGY : ABBREVIATED_YEAR_STRATEGY;
592621 case 'X':
593622 return ISO8601TimeZoneStrategy.getStrategy(width);
594623 case 'Z':
595 if (width==2) {
624 if (width == 2) {
596625 return ISO8601TimeZoneStrategy.ISO_8601_3_STRATEGY;
597626 }
598627 //$FALL-THROUGH$
628657 final ConcurrentMap<Locale, Strategy> cache = getCache(field);
629658 Strategy strategy = cache.get(locale);
630659 if (strategy == null) {
631 strategy = field == Calendar.ZONE_OFFSET
632 ? new TimeZoneStrategy(locale)
633 : new CaseInsensitiveTextStrategy(field, definingCalendar, locale);
660 strategy = field == Calendar.ZONE_OFFSET ? new TimeZoneStrategy(locale)
661 : new CaseInsensitiveTextStrategy(field, definingCalendar, locale);
634662 final Strategy inCache = cache.putIfAbsent(locale, strategy);
635663 if (inCache != null) {
636664 return inCache;
648676
649677 /**
650678 * Constructs a Strategy that ensures the formatField has literal text
679 *
651680 * @param formatField The literal text to match
652681 */
653682 CopyQuotedStrategy(final String formatField) {
663692 }
664693
665694 @Override
666 boolean parse(final FastDateParser parser, final Calendar calendar, final String source, final ParsePosition pos, final int maxWidth) {
695 boolean parse(final FastDateParser parser, final Calendar calendar, final String source,
696 final ParsePosition pos, final int maxWidth) {
667697 for (int idx = 0; idx < formatField.length(); ++idx) {
668698 final int sIdx = idx + pos.getIndex();
669699 if (sIdx == source.length()) {
678708 pos.setIndex(formatField.length() + pos.getIndex());
679709 return true;
680710 }
711
712 /**
713 * Converts this instance to a handy debug string.
714 *
715 * @since 3.12.0
716 */
717 @Override
718 public String toString() {
719 return "CopyQuotedStrategy [formatField=" + formatField + "]";
720 }
681721 }
682722
683723 /**
684724 * A strategy that handles a text field in the parsing pattern
685725 */
686 private static class CaseInsensitiveTextStrategy extends PatternStrategy {
726 private static class CaseInsensitiveTextStrategy extends PatternStrategy {
687727 private final int field;
688728 final Locale locale;
689729 private final Map<String, Integer> lKeyValues;
690730
691731 /**
692732 * Constructs a Strategy that parses a Text field
693 * @param field The Calendar field
694 * @param definingCalendar The Calendar to use
695 * @param locale The Locale to use
733 *
734 * @param field The Calendar field
735 * @param definingCalendar The Calendar to use
736 * @param locale The Locale to use
696737 */
697738 CaseInsensitiveTextStrategy(final int field, final Calendar definingCalendar, final Locale locale) {
698739 this.field = field;
699 this.locale = locale;
740 this.locale = LocaleUtils.toLocale(locale);
700741
701742 final StringBuilder regex = new StringBuilder();
702743 regex.append("((?iu)");
703744 lKeyValues = appendDisplayNames(definingCalendar, locale, field, regex);
704 regex.setLength(regex.length()-1);
745 regex.setLength(regex.length() - 1);
705746 regex.append(")");
706747 createPattern(regex);
707748 }
710751 * {@inheritDoc}
711752 */
712753 @Override
713 void setCalendar(final FastDateParser parser, final Calendar cal, final String value) {
754 void setCalendar(final FastDateParser parser, final Calendar calendar, final String value) {
714755 final String lowerCase = value.toLowerCase(locale);
715756 Integer iVal = lKeyValues.get(lowerCase);
716757 if (iVal == null) {
717758 // match missing the optional trailing period
718759 iVal = lKeyValues.get(lowerCase + '.');
719760 }
720 cal.set(field, iVal.intValue());
761 calendar.set(field, iVal.intValue());
762 }
763
764 /**
765 * Converts this instance to a handy debug string.
766 *
767 * @since 3.12.0
768 */
769 @Override
770 public String toString() {
771 return "CaseInsensitiveTextStrategy [field=" + field + ", locale=" + locale + ", lKeyValues=" + lKeyValues
772 + ", pattern=" + pattern + "]";
721773 }
722774 }
723775
726778 * A strategy that handles a number field in the parsing pattern
727779 */
728780 private static class NumberStrategy extends Strategy {
781
729782 private final int field;
730783
731784 /**
732785 * Constructs a Strategy that parses a Number field
786 *
733787 * @param field The Calendar field
734788 */
735789 NumberStrategy(final int field) {
736 this.field= field;
790 this.field = field;
737791 }
738792
739793 /**
745799 }
746800
747801 @Override
748 boolean parse(final FastDateParser parser, final Calendar calendar, final String source, final ParsePosition pos, final int maxWidth) {
802 boolean parse(final FastDateParser parser, final Calendar calendar, final String source,
803 final ParsePosition pos, final int maxWidth) {
749804 int idx = pos.getIndex();
750805 int last = source.length();
751806
786841
787842 /**
788843 * Make any modifications to parsed integer
844 *
789845 * @param parser The parser
790846 * @param iValue The parsed integer
791847 * @return The modified value
794850 return iValue;
795851 }
796852
853 /**
854 * Converts this instance to a handy debug string.
855 *
856 * @since 3.12.0
857 */
858 @Override
859 public String toString() {
860 return "NumberStrategy [field=" + field + "]";
861 }
797862 }
798863
799864 private static final Strategy ABBREVIATED_YEAR_STRATEGY = new NumberStrategy(Calendar.YEAR) {
807872 };
808873
809874 /**
810 * A strategy that handles a timezone field in the parsing pattern
875 * A strategy that handles a time zone field in the parsing pattern
811876 */
812877 static class TimeZoneStrategy extends PatternStrategy {
813878 private static final String RFC_822_TIME_ZONE = "[+-]\\d{4}";
814879 private static final String GMT_OPTION = TimeZones.GMT_ID + "[+-]\\d{1,2}:\\d{2}";
815880
816881 private final Locale locale;
817 private final Map<String, TzInfo> tzNames= new HashMap<>();
882 private final Map<String, TzInfo> tzNames = new HashMap<>();
818883
819884 private static class TzInfo {
820 TimeZone zone;
821 int dstOffset;
885 final TimeZone zone;
886 final int dstOffset;
822887
823888 TzInfo(final TimeZone tz, final boolean useDst) {
824889 zone = tz;
825 dstOffset = useDst ?tz.getDSTSavings() :0;
890 dstOffset = useDst ? tz.getDSTSavings() : 0;
826891 }
827892 }
828893
833898
834899 /**
835900 * Constructs a Strategy that parses a TimeZone
901 *
836902 * @param locale The Locale
837903 */
838904 TimeZoneStrategy(final Locale locale) {
839 this.locale = locale;
905 this.locale = LocaleUtils.toLocale(locale);
840906
841907 final StringBuilder sb = new StringBuilder();
842 sb.append("((?iu)" + RFC_822_TIME_ZONE + "|" + GMT_OPTION );
908 sb.append("((?iu)" + RFC_822_TIME_ZONE + "|" + GMT_OPTION);
843909
844910 final Set<String> sorted = new TreeSet<>(LONGER_FIRST_LOWERCASE);
845911
890956 * {@inheritDoc}
891957 */
892958 @Override
893 void setCalendar(final FastDateParser parser, final Calendar cal, final String timeZone) {
959 void setCalendar(final FastDateParser parser, final Calendar calendar, final String timeZone) {
894960 final TimeZone tz = FastTimeZone.getGmtTimeZone(timeZone);
895961 if (tz != null) {
896 cal.setTimeZone(tz);
962 calendar.setTimeZone(tz);
897963 } else {
898964 final String lowerCase = timeZone.toLowerCase(locale);
899965 TzInfo tzInfo = tzNames.get(lowerCase);
901967 // match missing the optional trailing period
902968 tzInfo = tzNames.get(lowerCase + '.');
903969 }
904 cal.set(Calendar.DST_OFFSET, tzInfo.dstOffset);
905 cal.set(Calendar.ZONE_OFFSET, tzInfo.zone.getRawOffset());
906 }
907 }
970 calendar.set(Calendar.DST_OFFSET, tzInfo.dstOffset);
971 calendar.set(Calendar.ZONE_OFFSET, tzInfo.zone.getRawOffset());
972 }
973 }
974
975 /**
976 * Converts this instance to a handy debug string.
977 *
978 * @since 3.12.0
979 */
980 @Override
981 public String toString() {
982 return "TimeZoneStrategy [locale=" + locale + ", tzNames=" + tzNames + ", pattern=" + pattern + "]";
983 }
984
908985 }
909986
910987 private static class ISO8601TimeZoneStrategy extends PatternStrategy {
922999 * {@inheritDoc}
9231000 */
9241001 @Override
925 void setCalendar(final FastDateParser parser, final Calendar cal, final String value) {
926 cal.setTimeZone(FastTimeZone.getGmtTimeZone(value));
1002 void setCalendar(final FastDateParser parser, final Calendar calendar, final String value) {
1003 calendar.setTimeZone(FastTimeZone.getGmtTimeZone(value));
9271004 }
9281005
9291006 private static final Strategy ISO_8601_1_STRATEGY = new ISO8601TimeZoneStrategy("(Z|(?:[+-]\\d{2}))");
3030 import java.util.concurrent.ConcurrentHashMap;
3131 import java.util.concurrent.ConcurrentMap;
3232
33 import org.apache.commons.lang3.LocaleUtils;
3334 import org.apache.commons.lang3.exception.ExceptionUtils;
3435
3536 /**
8990 // taking the value and adding (mathematically) the ASCII value for '0'.
9091 // So, don't change this code! It works and is very fast.
9192
93 /** Empty array. */
94 private static final Rule[] EMPTY_RULE_ARRAY = new Rule[0];
95
9296 /**
9397 * Required for serialization support.
9498 *
149153 protected FastDatePrinter(final String pattern, final TimeZone timeZone, final Locale locale) {
150154 mPattern = pattern;
151155 mTimeZone = timeZone;
152 mLocale = locale;
156 mLocale = LocaleUtils.toLocale(locale);
153157
154158 init();
155159 }
159163 */
160164 private void init() {
161165 final List<Rule> rulesList = parsePattern();
162 mRules = rulesList.toArray(new Rule[0]);
166 mRules = rulesList.toArray(EMPTY_RULE_ARRAY);
163167
164168 int len = 0;
165169 for (int i=mRules.length; --i >= 0; ) {
773777 *
774778 * @param buf the output buffer
775779 * @param calendar calendar to be appended
776 * @throws IOException if an I/O error occurs
780 * @throws IOException if an I/O error occurs.
777781 */
778782 void appendTo(Appendable buf, Calendar calendar) throws IOException;
779783 }
787791 *
788792 * @param buffer the output buffer
789793 * @param value the value to be appended
790 * @throws IOException if an I/O error occurs
794 * @throws IOException if an I/O error occurs.
791795 */
792796 void appendTo(Appendable buffer, int value) throws IOException;
793797 }
958962 *
959963 */
960964 UnpaddedMonthField() {
961 super();
962965 }
963966
964967 /**
10911094 * Constructs an instance of {@code TwoDigitYearField}.
10921095 */
10931096 TwoDigitYearField() {
1094 super();
10951097 }
10961098
10971099 /**
11151117 */
11161118 @Override
11171119 public final void appendTo(final Appendable buffer, final int value) throws IOException {
1118 appendDigits(buffer, value);
1120 appendDigits(buffer, value % 100);
11191121 }
11201122 }
11211123
11291131 * Constructs an instance of {@code TwoDigitMonthField}.
11301132 */
11311133 TwoDigitMonthField() {
1132 super();
11331134 }
11341135
11351136 /**
13441345 * @param style the style
13451346 */
13461347 TimeZoneNameRule(final TimeZone timeZone, final Locale locale, final int style) {
1347 mLocale = locale;
1348 mLocale = LocaleUtils.toLocale(locale);
13481349 mStyle = style;
13491350
13501351 mStandard = getTimeZoneDisplay(timeZone, false, style, locale);
15301531 *
15311532 * @param timeZone the time zone
15321533 * @param daylight adjust the style for daylight saving time if {@code true}
1533 * @param style the timezone style
1534 * @param locale the timezone locale
1534 * @param style the time zone style
1535 * @param locale the time zone locale
15351536 */
15361537 TimeZoneDisplayKey(final TimeZone timeZone,
15371538 final boolean daylight, final int style, final Locale locale) {
15411542 } else {
15421543 mStyle = style;
15431544 }
1544 mLocale = locale;
1545 mLocale = LocaleUtils.toLocale(locale);
15451546 }
15461547
15471548 /**
6969 * i.e. <em>[GMT] (+|-) Hours [[:] Minutes]</em>
7070 *
7171 * @param id A GMT custom id (or Olson id
72 * @return A timezone
72 * @return A time zone
7373 */
7474 public static TimeZone getTimeZone(final String id) {
7575 final TimeZone tz = getGmtTimeZone(id);
2424 import java.util.concurrent.ConcurrentHashMap;
2525 import java.util.concurrent.ConcurrentMap;
2626
27 import org.apache.commons.lang3.LocaleUtils;
2728 import org.apache.commons.lang3.Validate;
2829
2930 /**
30 * <p>FormatCache is a cache and factory for {@link Format}s.</p>
31 * FormatCache is a cache and factory for {@link Format}s.
3132 *
3233 * @since 3.0
3334 */
3738 /**
3839 * No date or no time. Used in same parameters as DateFormat.SHORT or DateFormat.LONG
3940 */
40 static final int NONE= -1;
41
42 private final ConcurrentMap<MultipartKey, F> cInstanceCache
43 = new ConcurrentHashMap<>(7);
44
45 private static final ConcurrentMap<MultipartKey, String> cDateTimeInstanceCache
46 = new ConcurrentHashMap<>(7);
47
48 /**
49 * <p>Gets a formatter instance using the default pattern in the
50 * default timezone and locale.</p>
41 static final int NONE = -1;
42
43 private final ConcurrentMap<ArrayKey, F> cInstanceCache = new ConcurrentHashMap<>(7);
44
45 private static final ConcurrentMap<ArrayKey, String> cDateTimeInstanceCache = new ConcurrentHashMap<>(7);
46
47 /**
48 * Gets a formatter instance using the default pattern in the
49 * default time zone and locale.
5150 *
5251 * @return a date/time formatter
5352 */
5655 }
5756
5857 /**
59 * <p>Gets a formatter instance using the specified pattern, time zone
60 * and locale.</p>
58 * Gets a formatter instance using the specified pattern, time zone
59 * and locale.
6160 *
6261 * @param pattern {@link java.text.SimpleDateFormat} compatible
6362 * pattern, non-null
6867 * @throws IllegalArgumentException if pattern is invalid
6968 */
7069 public F getInstance(final String pattern, TimeZone timeZone, Locale locale) {
71 Validate.notNull(pattern, "pattern must not be null");
70 Validate.notNull(pattern, "pattern");
7271 if (timeZone == null) {
7372 timeZone = TimeZone.getDefault();
7473 }
75 if (locale == null) {
76 locale = Locale.getDefault();
77 }
78 final MultipartKey key = new MultipartKey(pattern, timeZone, locale);
74 locale = LocaleUtils.toLocale(locale);
75 final ArrayKey key = new ArrayKey(pattern, timeZone, locale);
7976 F format = cInstanceCache.get(key);
8077 if (format == null) {
8178 format = createInstance(pattern, timeZone, locale);
82 final F previousValue= cInstanceCache.putIfAbsent(key, format);
79 final F previousValue = cInstanceCache.putIfAbsent(key, format);
8380 if (previousValue != null) {
8481 // another thread snuck in and did the same work
8582 // we should return the instance that is in ConcurrentMap
86 format= previousValue;
83 format = previousValue;
8784 }
8885 }
8986 return format;
9087 }
9188
9289 /**
93 * <p>Create a format instance using the specified pattern, time zone
94 * and locale.</p>
90 * Create a format instance using the specified pattern, time zone
91 * and locale.
9592 *
9693 * @param pattern {@link java.text.SimpleDateFormat} compatible pattern, this will not be null.
9794 * @param timeZone time zone, this will not be null.
103100 protected abstract F createInstance(String pattern, TimeZone timeZone, Locale locale);
104101
105102 /**
106 * <p>Gets a date/time formatter instance using the specified style,
107 * time zone and locale.</p>
103 * Gets a date/time formatter instance using the specified style,
104 * time zone and locale.
108105 *
109106 * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT, null indicates no date in format
110107 * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT, null indicates no time in format
117114 */
118115 // This must remain private, see LANG-884
119116 private F getDateTimeInstance(final Integer dateStyle, final Integer timeStyle, final TimeZone timeZone, Locale locale) {
120 if (locale == null) {
121 locale = Locale.getDefault();
122 }
117 locale = LocaleUtils.toLocale(locale);
123118 final String pattern = getPatternForStyle(dateStyle, timeStyle, locale);
124119 return getInstance(pattern, timeZone, locale);
125120 }
126121
127122 /**
128 * <p>Gets a date/time formatter instance using the specified style,
129 * time zone and locale.</p>
123 * Gets a date/time formatter instance using the specified style,
124 * time zone and locale.
130125 *
131126 * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT
132127 * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT
143138 }
144139
145140 /**
146 * <p>Gets a date formatter instance using the specified style,
147 * time zone and locale.</p>
141 * Gets a date formatter instance using the specified style,
142 * time zone and locale.
148143 *
149144 * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT
150145 * @param timeZone optional time zone, overrides time zone of
160155 }
161156
162157 /**
163 * <p>Gets a time formatter instance using the specified style,
164 * time zone and locale.</p>
158 * Gets a time formatter instance using the specified style,
159 * time zone and locale.
165160 *
166161 * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT
167162 * @param timeZone optional time zone, overrides time zone of
177172 }
178173
179174 /**
180 * <p>Gets a date/time format for the specified styles and locale.</p>
175 * Gets a date/time format for the specified styles and locale.
181176 *
182177 * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT, null indicates no date in format
183178 * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT, null indicates no time in format
187182 */
188183 // package protected, for access from test code; do not make public or protected
189184 static String getPatternForStyle(final Integer dateStyle, final Integer timeStyle, final Locale locale) {
190 final MultipartKey key = new MultipartKey(dateStyle, timeStyle, locale);
185 final Locale safeLocale = LocaleUtils.toLocale(locale);
186 final ArrayKey key = new ArrayKey(dateStyle, timeStyle, safeLocale);
191187
192188 String pattern = cDateTimeInstanceCache.get(key);
193189 if (pattern == null) {
194190 try {
195 DateFormat formatter;
191 final DateFormat formatter;
196192 if (dateStyle == null) {
197 formatter = DateFormat.getTimeInstance(timeStyle.intValue(), locale);
193 formatter = DateFormat.getTimeInstance(timeStyle.intValue(), safeLocale);
198194 } else if (timeStyle == null) {
199 formatter = DateFormat.getDateInstance(dateStyle.intValue(), locale);
195 formatter = DateFormat.getDateInstance(dateStyle.intValue(), safeLocale);
200196 } else {
201 formatter = DateFormat.getDateTimeInstance(dateStyle.intValue(), timeStyle.intValue(), locale);
197 formatter = DateFormat.getDateTimeInstance(dateStyle.intValue(), timeStyle.intValue(), safeLocale);
202198 }
203199 pattern = ((SimpleDateFormat) formatter).toPattern();
204200 final String previous = cDateTimeInstanceCache.putIfAbsent(key, pattern);
206202 // even though it doesn't matter if another thread put the pattern
207203 // it's still good practice to return the String instance that is
208204 // actually in the ConcurrentMap
209 pattern= previous;
205 pattern = previous;
210206 }
211207 } catch (final ClassCastException ex) {
212 throw new IllegalArgumentException("No date time pattern for locale: " + locale);
208 throw new IllegalArgumentException("No date time pattern for locale: " + safeLocale);
213209 }
214210 }
215211 return pattern;
216212 }
217213
218 // ----------------------------------------------------------------------
219 /**
220 * <p>Helper class to hold multi-part Map keys</p>
221 */
222 private static class MultipartKey {
214 /**
215 * Helper class to hold multi-part Map keys as arrays.
216 */
217 private static final class ArrayKey {
218
219 private static int computeHashCode(final Object[] keys) {
220 final int prime = 31;
221 int result = 1;
222 result = prime * result + Arrays.hashCode(keys);
223 return result;
224 }
225
223226 private final Object[] keys;
224 private int hashCode;
227 private final int hashCode;
225228
226229 /**
227230 * Constructs an instance of {@code MultipartKey} to hold the specified objects.
231 *
228232 * @param keys the set of objects that make up the key. Each key may be null.
229233 */
230 MultipartKey(final Object... keys) {
234 ArrayKey(final Object... keys) {
231235 this.keys = keys;
232 }
233
234 /**
235 * {@inheritDoc}
236 */
236 this.hashCode = computeHashCode(keys);
237 }
238
239 @Override
240 public int hashCode() {
241 return hashCode;
242 }
243
237244 @Override
238245 public boolean equals(final Object obj) {
239 // Eliminate the usual boilerplate because
240 // this inner static class is only used in a generic ConcurrentHashMap
241 // which will not compare against other Object types
242 return Arrays.equals(keys, ((MultipartKey) obj).keys);
243 }
244
245 /**
246 * {@inheritDoc}
247 */
248 @Override
249 public int hashCode() {
250 if (hashCode==0) {
251 int rc= 0;
252 for (final Object key : keys) {
253 if (key!=null) {
254 rc= rc*7 + key.hashCode();
255 }
256 }
257 hashCode= rc;
258 }
259 return hashCode;
260 }
246 if (this == obj) {
247 return true;
248 }
249 if (obj == null) {
250 return false;
251 }
252 if (getClass() != obj.getClass()) {
253 return false;
254 }
255 final ArrayKey other = (ArrayKey) obj;
256 return Arrays.deepEquals(keys, other.keys);
257 }
258
259
261260 }
262261
263262 }
1919 import java.util.TimeZone;
2020
2121 /**
22 * Custom timezone that contains offset from GMT.
22 * Custom time zone that contains offset from GMT.
2323 *
2424 * @since 3.7
2525 */
204204 private SplitState splitState = SplitState.UNSPLIT;
205205
206206 /**
207 * The start time.
208 */
209 private long startTime;
210
211 /**
212 * The start time in Millis - nanoTime is only for elapsed time so we
207 * The start time in nanoseconds.
208 */
209 private long startTimeNanos;
210
211 /**
212 * The start time in milliseconds - nanoTime is only for elapsed time so we
213213 * need to also store the currentTimeMillis to maintain the old
214214 * getStartTime API.
215215 */
216216 private long startTimeMillis;
217217
218218 /**
219 * The stop time.
220 */
221 private long stopTime;
219 * The end time in milliseconds - nanoTime is only for elapsed time so we
220 * need to also store the currentTimeMillis to maintain the old
221 * getStartTime API.
222 */
223 private long stopTimeMillis;
224
225 /**
226 * The stop time in nanoseconds.
227 */
228 private long stopTimeNanos;
222229
223230 /**
224231 * <p>
272279
273280 /**
274281 * <p>
275 * Gets the time on the stopwatch in nanoseconds.
282 * Gets the <em>elapsed</em> time in nanoseconds.
276283 * </p>
277284 *
278285 * <p>
280287 * start and stop.
281288 * </p>
282289 *
283 * @return the time in nanoseconds
290 * @return the <em>elapsed</em> time in nanoseconds.
291 * @see System#nanoTime()
284292 * @since 3.0
285293 */
286294 public long getNanoTime() {
287295 if (this.runningState == State.STOPPED || this.runningState == State.SUSPENDED) {
288 return this.stopTime - this.startTime;
296 return this.stopTimeNanos - this.startTimeNanos;
289297 } else if (this.runningState == State.UNSTARTED) {
290298 return 0;
291299 } else if (this.runningState == State.RUNNING) {
292 return System.nanoTime() - this.startTime;
293 }
294 throw new RuntimeException("Illegal running state has occurred.");
295 }
296
297 /**
298 * <p>
299 * Gets the split time on the stopwatch in nanoseconds.
300 return System.nanoTime() - this.startTimeNanos;
301 }
302 throw new IllegalStateException("Illegal running state has occurred.");
303 }
304
305 /**
306 * <p>
307 * Gets the split time in nanoseconds.
300308 * </p>
301309 *
302310 * <p>
311319 */
312320 public long getSplitNanoTime() {
313321 if (this.splitState != SplitState.SPLIT) {
314 throw new IllegalStateException("Stopwatch must be split to get the split time. ");
315 }
316 return this.stopTime - this.startTime;
322 throw new IllegalStateException("Stopwatch must be split to get the split time.");
323 }
324 return this.stopTimeNanos - this.startTimeNanos;
317325 }
318326
319327 /**
336344 }
337345
338346 /**
339 * Gets the time this stopwatch was started.
340 *
341 * @return the time this stopwatch was started
342 * @throws IllegalStateException
343 * if this StopWatch has not been started
347 * Gets the time this stopwatch was started in milliseconds, between the current time and midnight, January 1, 1970
348 * UTC.
349 *
350 * @return the time this stopwatch was started in milliseconds, between the current time and midnight, January 1,
351 * 1970 UTC.
352 * @throws IllegalStateException if this StopWatch has not been started
344353 * @since 2.4
345354 */
346355 public long getStartTime() {
352361 }
353362
354363 /**
364 * Gets the time this stopwatch was stopped in milliseconds, between the current time and midnight, January 1, 1970
365 * UTC.
366 *
367 * @return the time this stopwatch was started in milliseconds, between the current time and midnight, January 1,
368 * 1970 UTC.
369 * @throws IllegalStateException if this StopWatch has not been started
370 * @since 3.12.0
371 */
372 public long getStopTime() {
373 if (this.runningState == State.UNSTARTED) {
374 throw new IllegalStateException("Stopwatch has not been started");
375 }
376 // System.nanoTime is for elapsed time
377 return this.stopTimeMillis;
378 }
379
380 /**
355381 * <p>
356382 * Gets the time on the stopwatch.
357383 * </p>
369395
370396 /**
371397 * <p>
372 * Gets the time on the stopwatch in the specified TimeUnit.
398 * Gets the time in the specified TimeUnit.
373399 * </p>
374400 *
375401 * <p>
438464 this.runningState = State.UNSTARTED;
439465 this.splitState = SplitState.UNSPLIT;
440466 }
467
441468 /**
442469 * <p>
443470 * Resumes the stopwatch after a suspend.
455482 if (this.runningState != State.SUSPENDED) {
456483 throw new IllegalStateException("Stopwatch must be suspended to resume. ");
457484 }
458 this.startTime += System.nanoTime() - this.stopTime;
485 this.startTimeNanos += System.nanoTime() - this.stopTimeNanos;
459486 this.runningState = State.RUNNING;
460487 }
461488
476503 if (this.runningState != State.RUNNING) {
477504 throw new IllegalStateException("Stopwatch is not running. ");
478505 }
479 this.stopTime = System.nanoTime();
506 this.stopTimeNanos = System.nanoTime();
480507 this.splitState = SplitState.SPLIT;
481508 }
482509
499526 if (this.runningState != State.UNSTARTED) {
500527 throw new IllegalStateException("Stopwatch already started. ");
501528 }
502 this.startTime = System.nanoTime();
529 this.startTimeNanos = System.nanoTime();
503530 this.startTimeMillis = System.currentTimeMillis();
504531 this.runningState = State.RUNNING;
505532 }
521548 throw new IllegalStateException("Stopwatch is not running. ");
522549 }
523550 if (this.runningState == State.RUNNING) {
524 this.stopTime = System.nanoTime();
551 this.stopTimeNanos = System.nanoTime();
552 this.stopTimeMillis = System.currentTimeMillis();
525553 }
526554 this.runningState = State.STOPPED;
527555 }
543571 if (this.runningState != State.RUNNING) {
544572 throw new IllegalStateException("Stopwatch must be running to suspend. ");
545573 }
546 this.stopTime = System.nanoTime();
574 this.stopTimeNanos = System.nanoTime();
575 this.stopTimeMillis = System.currentTimeMillis();
547576 this.runningState = State.SUSPENDED;
548577 }
549578
166166 * @param right the right value, may be null
167167 */
168168 public ImmutablePair(final L left, final R right) {
169 super();
170169 this.left = left;
171170 this.right = right;
172171 }
114114 * @param right the right value, may be null
115115 */
116116 public ImmutableTriple(final L left, final M middle, final R right) {
117 super();
118117 this.left = left;
119118 this.middle = middle;
120119 this.right = right;
106106 * Create a new pair instance of two nulls.
107107 */
108108 public MutablePair() {
109 super();
110109 }
111110
112111 /**
116115 * @param right the right value, may be null
117116 */
118117 public MutablePair(final L left, final R right) {
119 super();
120118 this.left = left;
121119 this.right = right;
122120 }
8585 * Create a new triple instance of three nulls.
8686 */
8787 public MutableTriple() {
88 super();
8988 }
9089
9190 /**
9695 * @param right the right value, may be null
9796 */
9897 public MutableTriple(final L left, final M middle, final R right) {
99 super();
10098 this.left = left;
10199 this.middle = middle;
102100 this.right = right;
1414 See the License for the specific language governing permissions and
1515 limitations under the License.
1616 -->
17 <!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN" "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
17 <!DOCTYPE suppressions PUBLIC "-//Checkstyle//DTD SuppressionFilter Configuration 1.0//EN" "https://checkstyle.org/dtds/suppressions_1_0.dtd">
1818 <suppressions>
1919 <suppress checks="JavadocMethod" files=".*[/\\]test[/\\].*"/>
2020 <suppress checks="JavadocPackage" files=".*[/\\]test[/\\].*"/>
2121 <!-- exclude generated JMH classes from all checks -->
2222 <suppress checks="[a-zA-Z0-9]*" files=".*[/\\]generated-test-sources[/\\].*"/>
2323 <suppress checks="RedundantModifier" files="ConstructorUtilsTest" lines="0-99999"/>
24 <!-- Windows-only workaround -->
25 <suppress checks="NewlineAtEndOfFile" files="target[/\\]maven-archiver[/\\]pom.properties"/>
2426 </suppressions>
1616 -->
1717
1818 <!DOCTYPE module PUBLIC
19 "-//Puppy Crawl//DTD Check Configuration 1.1//EN"
20 "http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
19 "-//Checkstyle//DTD Checkstyle Configuration 1.2//EN"
20 "https://checkstyle.org/dtds/configuration_1_2.dtd">
2121
2222 <!-- Apache Commons Lang customization of default Checkstyle behavior -->
2323 <module name="Checker">
8686 <a href="userguide.html" title="Users guide">Users guide</a>
8787 </li>
8888 <li class="none">
89 <a href="release-history.html" title="Release History">Release History</a>
89 <a href="changes-report.html" title="Release History">Release History</a>
9090 </li>
9191 <li class="none">
9292 <a href="api-release/index.html" title="Javadoc (3.0 release)">Javadoc (3.0 release)</a>
2323
2424 <body>
2525 <menu name="Lang">
26 <item name="Overview" href="/index.html"/>
27 <item name="Download" href="/download_lang.cgi"/>
28 <item name="Users guide" href="/userguide.html"/>
29 <item name="Release History" href="/release-history.html"/>
30 <item name="Javadoc (Latest release)" href="javadocs/api-release/index.html"/>
26 <item name="Overview" href="/index.html" />
27 <item name="Download" href="/download_lang.cgi" />
28 <item name="Users guide" href="/userguide.html" />
29 <item name="Release History" href="/changes-report.html" />
30 <item name="Javadoc" href="/apidocs/index.html" />
31 <item name="Javadoc Archive" href="https://javadoc.io/doc/org.apache.commons/commons-lang3" />
3132 </menu>
3233
3334 <menu name="Development">
34 <item name="Building" href="/building.html"/>
35 <item name="Mailing Lists" href="/mail-lists.html"/>
36 <item name="Issue Tracking" href="/issue-tracking.html"/>
37 <item name="Proposal" href="/proposal.html"/>
38 <item name="Developer guide" href="/developerguide.html"/>
39 <item name="Source Repository" href="/scm.html"/>
40 <item name="Javadoc (GIT latest)" href="apidocs/index.html"/>
35 <item name="Building" href="/building.html" />
36 <item name="Mailing Lists" href="/mail-lists.html" />
37 <item name="Issue Tracking" href="/issue-tracking.html" />
38 <item name="Proposal" href="/proposal.html" />
39 <item name="Developer guide" href="/developerguide.html" />
40 <item name="Source Repository" href="/scm.html" />
4141 </menu>
4242
4343 </body>
112112 </p>
113113 </subsection>
114114 </section>
115 <section name="Apache Commons Lang 3.11 (Java 8+)">
115 <section name="Apache Commons Lang 3.12.0 (Java 8+)">
116116 <subsection name="Binaries">
117117 <table>
118118 <tr>
119 <td><a href="[preferred]/commons/lang/binaries/commons-lang3-3.11-bin.tar.gz">commons-lang3-3.11-bin.tar.gz</a></td>
120 <td><a href="https://www.apache.org/dist/commons/lang/binaries/commons-lang3-3.11-bin.tar.gz.sha512">sha512</a></td>
121 <td><a href="https://www.apache.org/dist/commons/lang/binaries/commons-lang3-3.11-bin.tar.gz.asc">pgp</a></td>
119 <td><a href="[preferred]/commons/lang/binaries/commons-lang3-3.12.0-bin.tar.gz">commons-lang3-3.12.0-bin.tar.gz</a></td>
120 <td><a href="https://www.apache.org/dist/commons/lang/binaries/commons-lang3-3.12.0-bin.tar.gz.sha512">sha512</a></td>
121 <td><a href="https://www.apache.org/dist/commons/lang/binaries/commons-lang3-3.12.0-bin.tar.gz.asc">pgp</a></td>
122122 </tr>
123123 <tr>
124 <td><a href="[preferred]/commons/lang/binaries/commons-lang3-3.11-bin.zip">commons-lang3-3.11-bin.zip</a></td>
125 <td><a href="https://www.apache.org/dist/commons/lang/binaries/commons-lang3-3.11-bin.zip.sha512">sha512</a></td>
126 <td><a href="https://www.apache.org/dist/commons/lang/binaries/commons-lang3-3.11-bin.zip.asc">pgp</a></td>
124 <td><a href="[preferred]/commons/lang/binaries/commons-lang3-3.12.0-bin.zip">commons-lang3-3.12.0-bin.zip</a></td>
125 <td><a href="https://www.apache.org/dist/commons/lang/binaries/commons-lang3-3.12.0-bin.zip.sha512">sha512</a></td>
126 <td><a href="https://www.apache.org/dist/commons/lang/binaries/commons-lang3-3.12.0-bin.zip.asc">pgp</a></td>
127127 </tr>
128128 </table>
129129 </subsection>
130130 <subsection name="Source">
131131 <table>
132132 <tr>
133 <td><a href="[preferred]/commons/lang/source/commons-lang3-3.11-src.tar.gz">commons-lang3-3.11-src.tar.gz</a></td>
134 <td><a href="https://www.apache.org/dist/commons/lang/source/commons-lang3-3.11-src.tar.gz.sha512">sha512</a></td>
135 <td><a href="https://www.apache.org/dist/commons/lang/source/commons-lang3-3.11-src.tar.gz.asc">pgp</a></td>
133 <td><a href="[preferred]/commons/lang/source/commons-lang3-3.12.0-src.tar.gz">commons-lang3-3.12.0-src.tar.gz</a></td>
134 <td><a href="https://www.apache.org/dist/commons/lang/source/commons-lang3-3.12.0-src.tar.gz.sha512">sha512</a></td>
135 <td><a href="https://www.apache.org/dist/commons/lang/source/commons-lang3-3.12.0-src.tar.gz.asc">pgp</a></td>
136136 </tr>
137137 <tr>
138 <td><a href="[preferred]/commons/lang/source/commons-lang3-3.11-src.zip">commons-lang3-3.11-src.zip</a></td>
139 <td><a href="https://www.apache.org/dist/commons/lang/source/commons-lang3-3.11-src.zip.sha512">sha512</a></td>
140 <td><a href="https://www.apache.org/dist/commons/lang/source/commons-lang3-3.11-src.zip.asc">pgp</a></td>
138 <td><a href="[preferred]/commons/lang/source/commons-lang3-3.12.0-src.zip">commons-lang3-3.12.0-src.zip</a></td>
139 <td><a href="https://www.apache.org/dist/commons/lang/source/commons-lang3-3.12.0-src.zip.sha512">sha512</a></td>
140 <td><a href="https://www.apache.org/dist/commons/lang/source/commons-lang3-3.12.0-src.zip.asc">pgp</a></td>
141141 </tr>
142142 </table>
143143 </subsection>
3030 </p>
3131
3232 <p>
33 Lang provides a host of helper utilities for the java.lang API, notably
33 Apache Commons Lang provides a host of helper utilities for the java.lang API, notably
3434 String manipulation methods, basic numerical methods, object reflection, concurrency, creation and serialization
3535 and System properties. Additionally it contains basic enhancements to java.util.Date and a series of utilities dedicated to help with
3636 building methods, such as hashCode, toString and equals.
3737 </p>
3838 <p>
39 Note that Lang 3.0 (and subsequent versions) use a different package (<em>org.apache.commons.lang3</em>) than the previous versions (<em>org.apache.commons.lang</em>), allowing it to be used at the same time as an earlier version.
39 Note that Commons Lang 3.0 (and subsequent versions) use a different package (<em>org.apache.commons.lang3</em>) than the previous versions (<em>org.apache.commons.lang</em>),
40 allowing Commons Lang 3 to be used at the same time as Commons Lang 2.
4041 </p>
4142 </section>
4243 <!-- ================================================== -->
4950 The Javadoc API documents are available online:
5051 </p>
5152 <ul>
52 <li>The <a href="javadocs/api-3.11/index.html">current stable release 3.11</a> [Java 8 and up]</li>
53 <li>The <a href="javadocs/api-release/index.html">current release</a> [Java 8 and up]</li>
5354 <li>The <a href="javadocs/api-2.6/index.html">legacy release 2.6</a> [Java 1.2 and up]</li>
54 <li>Older releases - see the <a href="release-history.html">Release History</a> page</li>
55 <li>Older releases - see the <a href="changes-report.html">Release History</a> page</li>
5556 </ul>
5657 <p>
5758 The <a href="scm.html">git repository</a> can be
6061 </section>
6162 <!-- ================================================== -->
6263 <section name="Release Information">
63 <p>The latest stable release of Lang is 3.10. You may: </p>
64 <p>The latest stable release of Lang is 3.12.0: </p>
6465 <ul>
65 <li>Download <a href="https://commons.apache.org/lang/download_lang.cgi">3.10</a></li>
66 <li>Read the <a href="release-notes/RELEASE-NOTES-3.10.txt">3.10 release notes</a></li>
67 <li>Examine the <a href="article3_0.html">2.x to 3.0 upgrade notes</a></li>
68 <li>Compare major versions via the <a href="lang2-lang3-clirr-report.html">Lang2 to Lang3 Clirr report</a></li>
66 <li>Pull it using a build tool like Maven using a <a href="dependency-info.html">dependency management reference</a>.</li>
67 <li>Download the latest release from a <a href="https://commons.apache.org/lang/download_lang.cgi">mirror</a>.</li>
68 <li>Read the <a href="release-notes/RELEASE-NOTES-3.12.txt">release notes</a>.</li>
69 <li>Examine the <a href="article3_0.html">2.x to 3.0 upgrade notes</a>.</li>
70 <li>Compare major versions via the <a href="lang2-lang3-clirr-report.html">Lang2 to Lang3 Clirr report</a>.</li>
6971 </ul>
70 <p>
71 Alternatively you can pull it from the central Maven repositories:
72 <pre>
73 &lt;dependency&gt;
74 &lt;groupId&gt;org.apache.commons&lt;/groupId&gt;
75 &lt;artifactId&gt;commons-lang3&lt;/artifactId&gt;
76 &lt;version&gt;3.10&lt;/version&gt;
77 &lt;/dependency&gt;
78 </pre>
79 </p>
8072
8173 <p>
82 For information on previous releases see the <a href="release-history.html">Release History</a>, and to download previous releases see the <a href="https://archive.apache.org/dist/commons/lang/">Commons Lang Archive</a>.
74 For information on previous releases see the <a href="changes-report.html">Release History</a>, and to download previous releases see the <a href="https://archive.apache.org/dist/commons/lang/">Commons Lang Archive</a>.
8375 </p>
8476 </section>
8577 <!-- ================================================== -->
+0
-131
src/site/xdoc/release-history.xml less more
0 <?xml version="1.0"?>
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one or more
3 contributor license agreements. See the NOTICE file distributed with
4 this work for additional information regarding copyright ownership.
5 The ASF licenses this file to You under the Apache License, Version 2.0
6 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 -->
17 <document>
18 <properties>
19 <title>Release History</title>
20 <author email="dev@commons.apache.org">Commons Documentation Team</author>
21 </properties>
22 <body>
23 <!-- ================================================== -->
24 <section name="Release History">
25
26 This page contains information about all Apache Commons Lang releases.
27
28 <subsection name="org.apache.commons:commons-lang3:3.x">
29 <table>
30 <tr>
31 <th>Version</th><th>Release date</th><th>Required Java Version</th><th>Javadoc</th><th>Release notes</th>
32 </tr>
33 <tr>
34 <td>3.10</td><td>2020-03-22</td><td>8</td><td><a href="javadocs/api-3.10/">api-3.10</a></td><td><a href="release-notes/RELEASE-NOTES-3.10.txt">release notes for 3.10</a></td>
35 </tr>
36 <tr>
37 <td>3.9</td><td>2019-04-09</td><td>8</td><td><a href="javadocs/api-3.9/">api-3.9</a></td><td><a href="release-notes/RELEASE-NOTES-3.9.txt">release notes for 3.9</a></td>
38 </tr>
39 <tr>
40 <td>3.8.1</td><td>2018-09-19</td><td>7</td><td><a href="javadocs/api-3.8.1/">api-3.8.1</a></td><td><a href="release-notes/RELEASE-NOTES-3.8.1.txt">release notes for 3.8.1</a></td>
41 </tr>
42 <tr>
43 <td>3.8</td><td>2018-08-15</td><td>7</td><td><a href="javadocs/api-3.8/">api-3.8</a></td><td><a href="release-notes/RELEASE-NOTES-3.8.txt">release notes for 3.8</a></td>
44 </tr>
45 <tr>
46 <td>3.7</td><td>2017-10-04</td><td>7</td><td><a href="javadocs/api-3.7/">api-3.7</a></td><td><a href="release-notes/RELEASE-NOTES-3.7.txt">release notes for 3.7</a></td>
47 </tr>
48 <tr>
49 <td>3.6</td><td>2016-04-17</td><td>7</td><td><a href="javadocs/api-3.6/">api-3.6</a></td><td><a href="release-notes/RELEASE-NOTES-3.6.txt">release notes for 3.6</a></td>
50 </tr>
51 <tr>
52 <td>3.5</td><td>2016-10-02</td><td>6</td><td><a href="javadocs/api-3.5/">api-3.5</a></td><td><a href="release-notes/RELEASE-NOTES-3.5.txt">release notes for 3.5</a></td>
53 </tr>
54 <tr>
55 <td>3.4</td><td>2014-04-06</td><td>6</td><td><a href="javadocs/api-3.4/">api-3.4</a></td><td><a href="release-notes/RELEASE-NOTES-3.4.txt">release notes for 3.4</a></td>
56 </tr>
57 <tr>
58 <td>3.3.2</td><td>2014-04-09</td><td>6</td><td><a href="javadocs/api-3.3.2/">api-3.3.2</a></td><td><a href="release-notes/RELEASE-NOTES-3.3.2.txt">release notes for 3.3.2</a></td>
59 </tr>
60 <tr>
61 <td>3.3.1</td><td>2014-03-18</td><td>6</td><td><a href="javadocs/api-3.3.1/">api-3.3.1</a></td><td><a href="release-notes/RELEASE-NOTES-3.3.1.txt">release notes for 3.3.1</a></td>
62 </tr>
63 <tr>
64 <td>3.3</td><td>2014-03-04</td><td>6</td><td><a href="javadocs/api-3.3/">api-3.3</a></td><td><a href="release-notes/RELEASE-NOTES-3.3.txt">release notes for 3.3</a></td>
65 </tr>
66 <tr>
67 <td>3.2.1</td><td>2014-01-05</td><td>6</td><td><a href="javadocs/api-3.2.1/">api-3.2.1</a></td><td><a href="release-notes/RELEASE-NOTES-3.2.1.txt">release notes for 3.2.1</a></td>
68 </tr>
69 <tr>
70 <td>3.2</td><td>2014-01-01</td><td>6</td><td><a href="javadocs/api-3.2/">api-3.2</a></td><td><a href="release-notes/RELEASE-NOTES-3.2.txt">release notes for 3.2</a></td>
71 </tr>
72 <tr>
73 <td>3.1</td><td>2011-11-14</td><td>5.0</td><td><a href="javadocs/api-3.1/">api-3.1</a></td><td><a href="release-notes/RELEASE-NOTES-3.1.txt">release notes for 3.1</a></td>
74 </tr>
75 <tr>
76 <td>3.0.1</td><td>2011-08-09</td><td>5.0</td><td><a href="javadocs/api-3.0.1/">api-3.0.1</a></td><td><a href="release-notes/RELEASE-NOTES-3.0.1.txt">release notes for 3.0.1</a></td>
77 </tr>
78 <tr>
79 <td>3.0</td><td>2011-07-18</td><td>5.0</td><td><a href="javadocs/api-3.0/">api-3.0</a></td><td><a href="release-notes/RELEASE-NOTES-3.0.txt">release notes for 3.0</a></td>
80 </tr>
81 </table>
82 </subsection>
83
84 <subsection name="commons-lang:commons-lang:2.x">
85 <table>
86 <tr>
87 <th>Version</th><th>Release date</th><th>Required Java Version</th><th>Javadoc</th><th>Release notes</th>
88 </tr>
89 <tr>
90 <td>2.6</td><td>2011-01-16</td><td>1.3</td><td><a href="javadocs/api-2.6/">api-2.6</a></td><td><a href="release-notes/RELEASE-NOTES-2.6.txt">release notes for 2.6</a></td>
91 </tr>
92 <tr>
93 <td>2.5</td><td>2010-02-23</td><td>1.3</td><td><a href="javadocs/api-2.5/">api-2.5</a></td><td><a href="release-notes/RELEASE-NOTES-2.5.txt">release notes for 2.5</a></td>
94 </tr>
95 <tr>
96 <td>2.4</td><td>2008-03-18</td><td>1.2</td><td><a href="javadocs/api-2.4/">api-2.4</a></td><td><a href="release-notes/RELEASE-NOTES-2.4.txt">release notes for 2.4</a></td>
97 </tr>
98 <tr>
99 <td>2.3</td><td>2007-02-13</td><td>1.1</td><td><a href="javadocs/api-2.3/">api-2.3</a></td><td><a href="release-notes/RELEASE-NOTES-2.3.txt">release notes for 2.3</a></td>
100 </tr>
101 <tr>
102 <td>2.2</td><td>2006-10-04</td><td>1.1</td><td><a href="javadocs/api-2.2/">api-2.2</a></td><td><a href="release-notes/RELEASE-NOTES-2.2.txt">release notes for 2.2</a></td>
103 </tr>
104 <tr>
105 <td>2.1</td><td>2006-06-13</td><td>1.1</td><td><a href="javadocs/api-2.1/">api-2.1</a></td><td><a href="release-notes/RELEASE-NOTES-2.1.txt">release notes for 2.1</a></td>
106 </tr>
107 <tr>
108 <td>2.0</td><td>2003-09-02</td><td>1.1</td><td><a href="javadocs/api-2.0/">api-2.0</a></td><td><a href="release-notes/RELEASE-NOTES-2.0.txt">release notes for 2.0</a></td>
109 </tr>
110 </table>
111 </subsection>
112
113 <subsection name="commons-lang:commons-lang:1.x">
114 <table>
115 <tr>
116 <th>Version</th><th>Release date</th><th>Required Java Version</th><th>Javadoc</th><th>Release notes</th>
117 </tr>
118 <tr>
119 <td>1.0.1</td><td>2002-11-25</td><td>1.1</td><td><a href="javadocs/api-1.0.1/">api-1.0.1</a></td><td><a href="release-notes/RELEASE-NOTES-1.0.1.txt">release notes for 1.0.1</a></td>
120 </tr>
121 <tr>
122 <td>1.0</td><td>2002-10-04</td><td>1.1</td><td><a href="javadocs/api-1.0/">api-1.0</a></td><td><a href="release-notes/RELEASE-NOTES-1.0.txt">release notes for 1.0</a></td>
123 </tr>
124 </table>
125 </subsection>
126
127 </section>
128 <!-- ================================================== -->
129 </body>
130 </document>
2525 <body>
2626
2727 <section name='User guide for Commons "Lang"'>
28 Looking for the User Guide? It has been moved to the package <a href="javadocs/api-release/index.html">Javadoc</a>
28 Looking for the User Guide? It has been moved to the package <a href="javadocs/api-release/index.html">Javadoc</a>.
2929 </section>
3030
3131 </body>
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.commons.lang3;
18
19 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
20
21 import java.util.Arrays;
22
23 import org.junit.jupiter.api.Test;
24
25 public class ArraySorterTest {
26
27 @Test
28 public void testSortByteArray() {
29 final byte[] array1 = {2, 1};
30 final byte[] array2 = array1.clone();
31 Arrays.sort(array1);
32 assertArrayEquals(array1, ArraySorter.sort(array2));
33 }
34
35 @Test
36 public void testSortCharArray() {
37 final char[] array1 = {2, 1};
38 final char[] array2 = array1.clone();
39 Arrays.sort(array1);
40 assertArrayEquals(array1, ArraySorter.sort(array2));
41 }
42
43 @Test
44 public void testSortComparable() {
45 final String[] array1 = ArrayUtils.toArray("foo", "bar");
46 final String[] array2 = array1.clone();
47 Arrays.sort(array1);
48 assertArrayEquals(array1, ArraySorter.sort(array2, String::compareTo));
49 }
50
51 @Test
52 public void testSortDoubleArray() {
53 final double[] array1 = {2, 1};
54 final double[] array2 = array1.clone();
55 Arrays.sort(array1);
56 assertArrayEquals(array1, ArraySorter.sort(array2));
57 }
58
59 @Test
60 public void testSortFloatArray() {
61 final float[] array1 = {2, 1};
62 final float[] array2 = array1.clone();
63 Arrays.sort(array1);
64 assertArrayEquals(array1, ArraySorter.sort(array2));
65 }
66
67 @Test
68 public void testSortIntArray() {
69 final int[] array1 = {2, 1};
70 final int[] array2 = array1.clone();
71 Arrays.sort(array1);
72 assertArrayEquals(array1, ArraySorter.sort(array2));
73 }
74
75 @Test
76 public void testSortLongArray() {
77 final long[] array1 = {2, 1};
78 final long[] array2 = array1.clone();
79 Arrays.sort(array1);
80 assertArrayEquals(array1, ArraySorter.sort(array2));
81 }
82
83 @Test
84 public void testSortObjects() {
85 final String[] array1 = ArrayUtils.toArray("foo", "bar");
86 final String[] array2 = array1.clone();
87 Arrays.sort(array1);
88 assertArrayEquals(array1, ArraySorter.sort(array2));
89 }
90
91 @Test
92 public void testSortShortArray() {
93 final short[] array1 = {2, 1};
94 final short[] array2 = array1.clone();
95 Arrays.sort(array1);
96 assertArrayEquals(array1, ArraySorter.sort(array2));
97 }
98
99 }
7777 assertEquals("foo", array[0]);
7878 assertEquals("bar", array[1]);
7979 }
80
8180 /**
8281 * Tests generic array creation with parameters of common base type.
8382 */
276275 assertFalse(ArrayUtils.contains(array, (double) 99));
277276 }
278277
278 @Test
279 public void testContainsDoubleNaN() {
280 final double[] a = new double[] { Double.NEGATIVE_INFINITY, Double.NaN, Double.POSITIVE_INFINITY };
281 assertTrue(ArrayUtils.contains(a, Double.POSITIVE_INFINITY));
282 assertTrue(ArrayUtils.contains(a, Double.NEGATIVE_INFINITY));
283 assertTrue(ArrayUtils.contains(a, Double.NaN));
284 }
285
279286 @SuppressWarnings("cast")
280287 @Test
281288 public void testContainsDoubleTolerance() {
302309 }
303310
304311 @Test
312 public void testContainsFloatNaN() {
313 final float[] array = new float[] { Float.NEGATIVE_INFINITY, Float.NaN, Float.POSITIVE_INFINITY };
314 assertTrue(ArrayUtils.contains(array, Float.POSITIVE_INFINITY));
315 assertTrue(ArrayUtils.contains(array, Float.NEGATIVE_INFINITY));
316 assertTrue(ArrayUtils.contains(array, Float.NaN));
317 }
318
319 @Test
305320 public void testContainsInt() {
306321 int[] array = null;
307322 assertFalse(ArrayUtils.contains(array, 1));
340355 @Test
341356 public void testCreatePrimitiveArray() {
342357 assertNull(ArrayUtils.toPrimitive((Object[]) null));
358 assertArrayEquals(new boolean[]{true}, ArrayUtils.toPrimitive(new Boolean[]{true}));
359 assertArrayEquals(new char[]{'a'}, ArrayUtils.toPrimitive(new Character[]{'a'}));
360 assertArrayEquals(new byte[]{1}, ArrayUtils.toPrimitive(new Byte[]{1}));
343361 assertArrayEquals(new int[]{}, ArrayUtils.toPrimitive(new Integer[]{}));
344362 assertArrayEquals(new short[]{2}, ArrayUtils.toPrimitive(new Short[]{2}));
345363 assertArrayEquals(new long[]{2, 3}, ArrayUtils.toPrimitive(new Long[]{2L, 3L}));
346364 assertArrayEquals(new float[]{3.14f}, ArrayUtils.toPrimitive(new Float[]{3.14f}), 0.1f);
347365 assertArrayEquals(new double[]{2.718}, ArrayUtils.toPrimitive(new Double[]{2.718}), 0.1);
366 }
367
368 @Test
369 public void testCreatePrimitiveArrayViaObjectArray() {
370 assertNull(ArrayUtils.toPrimitive((Object) null));
371 assertArrayEquals(new boolean[]{true}, (boolean[]) ArrayUtils.toPrimitive((Object) new Boolean[]{true}));
372 assertArrayEquals(new char[]{'a'}, (char[]) ArrayUtils.toPrimitive((Object) new Character[]{'a'}));
373 assertArrayEquals(new byte[]{1}, (byte[]) ArrayUtils.toPrimitive((Object) new Byte[]{1}));
374 assertArrayEquals(new int[]{}, (int[]) ArrayUtils.toPrimitive((Object) new Integer[]{}));
375 assertArrayEquals(new short[]{2}, (short[]) ArrayUtils.toPrimitive((Object) new Short[]{2}));
376 assertArrayEquals(new long[]{2, 3}, (long[]) ArrayUtils.toPrimitive((Object) new Long[]{2L, 3L}));
377 assertArrayEquals(new float[]{3.14f}, (float[]) ArrayUtils.toPrimitive((Object) new Float[]{3.14f}), 0.1f);
378 assertArrayEquals(new double[]{2.718}, (double[]) ArrayUtils.toPrimitive((Object) new Double[]{2.718}), 0.1);
348379 }
349380
350381 /**
10281059 assertEquals(-1, ArrayUtils.indexOf(array, (double) 99));
10291060 }
10301061
1062 @Test
1063 public void testIndexOfDoubleNaN() {
1064 final double[] array = new double[] { Double.NEGATIVE_INFINITY, Double.NaN, Double.POSITIVE_INFINITY, Double.NaN };
1065 assertEquals(0, ArrayUtils.indexOf(array, Double.NEGATIVE_INFINITY));
1066 assertEquals(1, ArrayUtils.indexOf(array, Double.NaN));
1067 assertEquals(2, ArrayUtils.indexOf(array, Double.POSITIVE_INFINITY));
1068
1069 }
1070
10311071 @SuppressWarnings("cast")
10321072 @Test
10331073 public void testIndexOfDoubleTolerance() {
10911131 assertEquals(-1, ArrayUtils.indexOf(array, (float) 99));
10921132 }
10931133
1134 @Test
1135 public void testIndexOfFloatNaN() {
1136 final float[] array = new float[] { Float.NEGATIVE_INFINITY, Float.NaN, Float.POSITIVE_INFINITY, Float.NaN };
1137 assertEquals(0, ArrayUtils.indexOf(array, Float.NEGATIVE_INFINITY));
1138 assertEquals(1, ArrayUtils.indexOf(array, Float.NaN));
1139 assertEquals(2, ArrayUtils.indexOf(array, Float.POSITIVE_INFINITY));
1140 }
1141
10941142 @SuppressWarnings("cast")
10951143 @Test
10961144 public void testIndexOfFloatWithStartIndex() {
12451293 @Test
12461294 public void testIsEmptyObject() {
12471295 final Object[] emptyArray = new Object[]{};
1248 final Object[] notEmptyArray = new Object[]{new String("Value")};
1296 final Object[] notEmptyArray = new Object[]{"Value"};
12491297 assertTrue(ArrayUtils.isEmpty((Object[]) null));
12501298 assertTrue(ArrayUtils.isEmpty(emptyArray));
12511299 assertFalse(ArrayUtils.isEmpty(notEmptyArray));
13691417 @Test
13701418 public void testIsNotEmptyObject() {
13711419 final Object[] emptyArray = new Object[]{};
1372 final Object[] notEmptyArray = new Object[]{new String("Value")};
1420 final Object[] notEmptyArray = new Object[]{"Value"};
13731421 assertFalse(ArrayUtils.isNotEmpty((Object[]) null));
13741422 assertFalse(ArrayUtils.isNotEmpty(emptyArray));
13751423 assertTrue(ArrayUtils.isNotEmpty(notEmptyArray));
45124560 assertEquals(2, array[3]);
45134561 }
45144562
4515
45164563 @Test
45174564 public void testShiftFloat() {
45184565 final float[] array = new float[]{1, 2, 3, 4};
45374584 assertEquals(1, array[2]);
45384585 assertEquals(2, array[3]);
45394586 }
4587
45404588
45414589 @Test
45424590 public void testShiftInt() {
1515 */
1616 package org.apache.commons.lang3;
1717
18 import static org.apache.commons.lang3.ArraySorter.sort;
19 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
1820 import static org.junit.jupiter.api.Assertions.assertEquals;
1921 import static org.junit.jupiter.api.Assertions.assertFalse;
2022 import static org.junit.jupiter.api.Assertions.assertNotNull;
3335 */
3436 public class BooleanUtilsTest {
3537
36 //-----------------------------------------------------------------------
37 @Test
38 public void testConstructor() {
39 assertNotNull(new BooleanUtils());
40 final Constructor<?>[] cons = BooleanUtils.class.getDeclaredConstructors();
41 assertEquals(1, cons.length);
42 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
43 assertTrue(Modifier.isPublic(BooleanUtils.class.getModifiers()));
44 assertFalse(Modifier.isFinal(BooleanUtils.class.getModifiers()));
45 }
46
47 //-----------------------------------------------------------------------
38 @Test
39 public void test_booleanValues() {
40 final Boolean[] expected = new Boolean[] {false, true};
41 assertArrayEquals(sort(expected), BooleanUtils.booleanValues());
42 }
43
44 @Test
45 public void test_isFalse_Boolean() {
46 assertFalse(BooleanUtils.isFalse(Boolean.TRUE));
47 assertTrue(BooleanUtils.isFalse(Boolean.FALSE));
48 assertFalse(BooleanUtils.isFalse(null));
49 }
50
51 @Test
52 public void test_isNotFalse_Boolean() {
53 assertTrue(BooleanUtils.isNotFalse(Boolean.TRUE));
54 assertFalse(BooleanUtils.isNotFalse(Boolean.FALSE));
55 assertTrue(BooleanUtils.isNotFalse(null));
56 }
57
58 @Test
59 public void test_isNotTrue_Boolean() {
60 assertFalse(BooleanUtils.isNotTrue(Boolean.TRUE));
61 assertTrue(BooleanUtils.isNotTrue(Boolean.FALSE));
62 assertTrue(BooleanUtils.isNotTrue(null));
63 }
64
65 @Test
66 public void test_isTrue_Boolean() {
67 assertTrue(BooleanUtils.isTrue(Boolean.TRUE));
68 assertFalse(BooleanUtils.isTrue(Boolean.FALSE));
69 assertFalse(BooleanUtils.isTrue(null));
70 }
71
4872 @Test
4973 public void test_negate_Boolean() {
5074 assertSame(null, BooleanUtils.negate(null));
5276 assertSame(Boolean.FALSE, BooleanUtils.negate(Boolean.TRUE));
5377 }
5478
55 //-----------------------------------------------------------------------
56 @Test
57 public void test_isTrue_Boolean() {
58 assertTrue(BooleanUtils.isTrue(Boolean.TRUE));
59 assertFalse(BooleanUtils.isTrue(Boolean.FALSE));
60 assertFalse(BooleanUtils.isTrue(null));
61 }
62
63 @Test
64 public void test_isNotTrue_Boolean() {
65 assertFalse(BooleanUtils.isNotTrue(Boolean.TRUE));
66 assertTrue(BooleanUtils.isNotTrue(Boolean.FALSE));
67 assertTrue(BooleanUtils.isNotTrue(null));
68 }
69
70 //-----------------------------------------------------------------------
71 @Test
72 public void test_isFalse_Boolean() {
73 assertFalse(BooleanUtils.isFalse(Boolean.TRUE));
74 assertTrue(BooleanUtils.isFalse(Boolean.FALSE));
75 assertFalse(BooleanUtils.isFalse(null));
76 }
77
78 @Test
79 public void test_isNotFalse_Boolean() {
80 assertTrue(BooleanUtils.isNotFalse(Boolean.TRUE));
81 assertFalse(BooleanUtils.isNotFalse(Boolean.FALSE));
82 assertTrue(BooleanUtils.isNotFalse(null));
83 }
84
85 //-----------------------------------------------------------------------
79 @Test
80 public void test_primitiveValues() {
81 assertArrayEquals(new boolean[] {false, true}, BooleanUtils.primitiveValues());
82 }
83
8684 @Test
8785 public void test_toBoolean_Boolean() {
8886 assertTrue(BooleanUtils.toBoolean(Boolean.TRUE));
9189 }
9290
9391 @Test
94 public void test_toBooleanDefaultIfNull_Boolean_boolean() {
95 assertTrue(BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, true));
96 assertTrue(BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, false));
97 assertFalse(BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, true));
98 assertFalse(BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, false));
99 assertTrue(BooleanUtils.toBooleanDefaultIfNull(null, true));
100 assertFalse(BooleanUtils.toBooleanDefaultIfNull(null, false));
101 }
102
103 //-----------------------------------------------------------------------
104 //-----------------------------------------------------------------------
105 @Test
10692 public void test_toBoolean_int() {
10793 assertTrue(BooleanUtils.toBoolean(1));
10894 assertTrue(BooleanUtils.toBoolean(-1));
11096 }
11197
11298 @Test
113 public void test_toBooleanObject_int() {
114 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(1));
115 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(-1));
116 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject(0));
117 }
118
119 @Test
120 public void test_toBooleanObject_Integer() {
121 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(Integer.valueOf(1)));
122 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(Integer.valueOf(-1)));
123 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject(Integer.valueOf(0)));
124 assertNull(BooleanUtils.toBooleanObject((Integer) null));
125 }
126
127 //-----------------------------------------------------------------------
128 @Test
12999 public void test_toBoolean_int_int_int() {
130100 assertTrue(BooleanUtils.toBoolean(6, 6, 7));
131101 assertFalse(BooleanUtils.toBoolean(7, 6, 7));
149119 }
150120
151121 @Test
122 public void test_toBoolean_Integer_Integer_Integer_noMatch() {
123 assertThrows(IllegalArgumentException.class,
124 () -> BooleanUtils.toBoolean(Integer.valueOf(8), Integer.valueOf(6), Integer.valueOf(7)));
125 }
126
127 @Test
152128 public void test_toBoolean_Integer_Integer_Integer_nullValue() {
153129 assertThrows(IllegalArgumentException.class,
154130 () -> BooleanUtils.toBoolean(null, Integer.valueOf(6), Integer.valueOf(7)));
155131 }
156132
157 @Test
158 public void test_toBoolean_Integer_Integer_Integer_noMatch() {
159 assertThrows(IllegalArgumentException.class,
160 () -> BooleanUtils.toBoolean(Integer.valueOf(8), Integer.valueOf(6), Integer.valueOf(7)));
161 }
162
163 //-----------------------------------------------------------------------
164 @Test
165 public void test_toBooleanObject_int_int_int() {
166 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(6, 6, 7, 8));
167 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject(7, 6, 7, 8));
168 assertNull(BooleanUtils.toBooleanObject(8, 6, 7, 8));
169 }
170
171 @Test
172 public void test_toBooleanObject_int_int_int_noMatch() {
173 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.toBooleanObject(9, 6, 7, 8));
174 }
175
176 @Test
177 public void test_toBooleanObject_Integer_Integer_Integer_Integer() {
178 final Integer six = Integer.valueOf(6);
179 final Integer seven = Integer.valueOf(7);
180 final Integer eight = Integer.valueOf(8);
181
182 assertSame(Boolean.TRUE, BooleanUtils.toBooleanObject(null, null, seven, eight));
183 assertSame(Boolean.FALSE, BooleanUtils.toBooleanObject(null, six, null, eight));
184 assertSame(null, BooleanUtils.toBooleanObject(null, six, seven, null));
185
186 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(Integer.valueOf(6), six, seven, eight));
187 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject(Integer.valueOf(7), six, seven, eight));
188 assertNull(BooleanUtils.toBooleanObject(Integer.valueOf(8), six, seven, eight));
189 }
190
191 @Test
192 public void test_toBooleanObject_Integer_Integer_Integer_Integer_nullValue() {
193 assertThrows(IllegalArgumentException.class,
194 () -> BooleanUtils.toBooleanObject(null, Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8)));
195 }
196
197 @Test
198 public void test_toBooleanObject_Integer_Integer_Integer_Integer_noMatch() {
199 assertThrows(IllegalArgumentException.class,
200 () -> BooleanUtils.toBooleanObject(Integer.valueOf(9), Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8)));
201 }
202
203 //-----------------------------------------------------------------------
204 @Test
205 public void test_toInteger_boolean() {
206 assertEquals(1, BooleanUtils.toInteger(true));
207 assertEquals(0, BooleanUtils.toInteger(false));
208 }
209
210 @Test
211 public void test_toIntegerObject_boolean() {
212 assertEquals(Integer.valueOf(1), BooleanUtils.toIntegerObject(true));
213 assertEquals(Integer.valueOf(0), BooleanUtils.toIntegerObject(false));
214 }
215
216 @Test
217 public void test_toIntegerObject_Boolean() {
218 assertEquals(Integer.valueOf(1), BooleanUtils.toIntegerObject(Boolean.TRUE));
219 assertEquals(Integer.valueOf(0), BooleanUtils.toIntegerObject(Boolean.FALSE));
220 assertNull(BooleanUtils.toIntegerObject(null));
221 }
222
223 //-----------------------------------------------------------------------
224 @Test
225 public void test_toInteger_boolean_int_int() {
226 assertEquals(6, BooleanUtils.toInteger(true, 6, 7));
227 assertEquals(7, BooleanUtils.toInteger(false, 6, 7));
228 }
229
230 @Test
231 public void test_toInteger_Boolean_int_int_int() {
232 assertEquals(6, BooleanUtils.toInteger(Boolean.TRUE, 6, 7, 8));
233 assertEquals(7, BooleanUtils.toInteger(Boolean.FALSE, 6, 7, 8));
234 assertEquals(8, BooleanUtils.toInteger(null, 6, 7, 8));
235 }
236
237 @Test
238 public void test_toIntegerObject_boolean_Integer_Integer() {
239 final Integer six = Integer.valueOf(6);
240 final Integer seven = Integer.valueOf(7);
241 assertEquals(six, BooleanUtils.toIntegerObject(true, six, seven));
242 assertEquals(seven, BooleanUtils.toIntegerObject(false, six, seven));
243 }
244
245 @Test
246 public void test_toIntegerObject_Boolean_Integer_Integer_Integer() {
247 final Integer six = Integer.valueOf(6);
248 final Integer seven = Integer.valueOf(7);
249 final Integer eight = Integer.valueOf(8);
250 assertEquals(six, BooleanUtils.toIntegerObject(Boolean.TRUE, six, seven, eight));
251 assertEquals(seven, BooleanUtils.toIntegerObject(Boolean.FALSE, six, seven, eight));
252 assertEquals(eight, BooleanUtils.toIntegerObject(null, six, seven, eight));
253 assertNull(BooleanUtils.toIntegerObject(null, six, seven, null));
254 }
255
256 //-----------------------------------------------------------------------
257 //-----------------------------------------------------------------------
258 @Test
259 public void test_toBooleanObject_String() {
260 assertNull(BooleanUtils.toBooleanObject((String) null));
261 assertNull(BooleanUtils.toBooleanObject(""));
262 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("false"));
263 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("no"));
264 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("off"));
265 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("FALSE"));
266 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("NO"));
267 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("OFF"));
268 assertNull(BooleanUtils.toBooleanObject("oof"));
269 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("true"));
270 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("yes"));
271 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("on"));
272 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("TRUE"));
273 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("ON"));
274 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("YES"));
275 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("TruE"));
276 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("TruE"));
277
278 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("y")); // yes
279 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("Y"));
280 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("t")); // true
281 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("T"));
282 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("1"));
283 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("f")); // false
284 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("F"));
285 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("n")); // No
286 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("N"));
287 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("0"));
288 assertNull(BooleanUtils.toBooleanObject("z"));
289
290 assertNull(BooleanUtils.toBooleanObject("ab"));
291 assertNull(BooleanUtils.toBooleanObject("yoo"));
292 assertNull(BooleanUtils.toBooleanObject("true "));
293 assertNull(BooleanUtils.toBooleanObject("ono"));
294 }
295
296 @Test
297 public void test_toBooleanObject_String_String_String_String() {
298 assertSame(Boolean.TRUE, BooleanUtils.toBooleanObject(null, null, "N", "U"));
299 assertSame(Boolean.FALSE, BooleanUtils.toBooleanObject(null, "Y", null, "U"));
300 assertSame(null, BooleanUtils.toBooleanObject(null, "Y", "N", null));
301
302 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("Y", "Y", "N", "U"));
303 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("N", "Y", "N", "U"));
304 assertNull(BooleanUtils.toBooleanObject("U", "Y", "N", "U"));
305 }
306
307 @Test
308 public void test_toBooleanObject_String_String_String_String_nullValue() {
309 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.toBooleanObject(null, "Y", "N", "U"));
310 }
311
312 @Test
313 public void test_toBooleanObject_String_String_String_String_noMatch() {
314 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.toBooleanObject("X", "Y", "N", "U"));
315 }
316
317 //-----------------------------------------------------------------------
318133 @Test
319134 public void test_toBoolean_String() {
320135 assertFalse(BooleanUtils.toBoolean((String) null));
369184 assertTrue(BooleanUtils.toBoolean(null, null, "N"));
370185 assertFalse(BooleanUtils.toBoolean(null, "Y", null));
371186 assertTrue(BooleanUtils.toBoolean("Y", "Y", "N"));
372 assertTrue(BooleanUtils.toBoolean("Y", new String("Y"), new String("N")));
187 assertTrue(BooleanUtils.toBoolean("Y", "Y", "N"));
373188 assertFalse(BooleanUtils.toBoolean("N", "Y", "N"));
374 assertFalse(BooleanUtils.toBoolean("N", new String("Y"), new String("N")));
189 assertFalse(BooleanUtils.toBoolean("N", "Y", "N"));
375190 assertTrue(BooleanUtils.toBoolean((String) null, null, null));
376191 assertTrue(BooleanUtils.toBoolean("Y", "Y", "Y"));
377 assertTrue(BooleanUtils.toBoolean("Y", new String("Y"), new String("Y")));
192 assertTrue(BooleanUtils.toBoolean("Y", "Y", "Y"));
193 }
194
195 @Test
196 public void test_toBoolean_String_String_String_noMatch() {
197 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.toBoolean("X", "Y", "N"));
378198 }
379199
380200 @Test
383203 }
384204
385205 @Test
386 public void test_toBoolean_String_String_String_noMatch() {
387 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.toBoolean("X", "Y", "N"));
388 }
389
390 //-----------------------------------------------------------------------
206 public void test_toBooleanDefaultIfNull_Boolean_boolean() {
207 assertTrue(BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, true));
208 assertTrue(BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, false));
209 assertFalse(BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, true));
210 assertFalse(BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, false));
211 assertTrue(BooleanUtils.toBooleanDefaultIfNull(null, true));
212 assertFalse(BooleanUtils.toBooleanDefaultIfNull(null, false));
213 }
214
215 @Test
216 public void test_toBooleanObject_int() {
217 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(1));
218 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(-1));
219 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject(0));
220 }
221
222 @Test
223 public void test_toBooleanObject_int_int_int() {
224 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(6, 6, 7, 8));
225 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject(7, 6, 7, 8));
226 assertNull(BooleanUtils.toBooleanObject(8, 6, 7, 8));
227 }
228
229 @Test
230 public void test_toBooleanObject_int_int_int_noMatch() {
231 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.toBooleanObject(9, 6, 7, 8));
232 }
233
234 @Test
235 public void test_toBooleanObject_Integer() {
236 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(Integer.valueOf(1)));
237 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(Integer.valueOf(-1)));
238 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject(Integer.valueOf(0)));
239 assertNull(BooleanUtils.toBooleanObject((Integer) null));
240 }
241
242 @Test
243 public void test_toBooleanObject_Integer_Integer_Integer_Integer() {
244 final Integer six = Integer.valueOf(6);
245 final Integer seven = Integer.valueOf(7);
246 final Integer eight = Integer.valueOf(8);
247
248 assertSame(Boolean.TRUE, BooleanUtils.toBooleanObject(null, null, seven, eight));
249 assertSame(Boolean.FALSE, BooleanUtils.toBooleanObject(null, six, null, eight));
250 assertSame(null, BooleanUtils.toBooleanObject(null, six, seven, null));
251
252 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject(Integer.valueOf(6), six, seven, eight));
253 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject(Integer.valueOf(7), six, seven, eight));
254 assertNull(BooleanUtils.toBooleanObject(Integer.valueOf(8), six, seven, eight));
255 }
256
257 @Test
258 public void test_toBooleanObject_Integer_Integer_Integer_Integer_noMatch() {
259 assertThrows(IllegalArgumentException.class,
260 () -> BooleanUtils.toBooleanObject(Integer.valueOf(9), Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8)));
261 }
262
263 @Test
264 public void test_toBooleanObject_Integer_Integer_Integer_Integer_nullValue() {
265 assertThrows(IllegalArgumentException.class,
266 () -> BooleanUtils.toBooleanObject(null, Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8)));
267 }
268
269 @Test
270 public void test_toBooleanObject_String() {
271 assertNull(BooleanUtils.toBooleanObject((String) null));
272 assertNull(BooleanUtils.toBooleanObject(""));
273 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("false"));
274 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("no"));
275 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("off"));
276 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("FALSE"));
277 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("NO"));
278 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("OFF"));
279 assertNull(BooleanUtils.toBooleanObject("oof"));
280 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("true"));
281 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("yes"));
282 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("on"));
283 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("TRUE"));
284 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("ON"));
285 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("YES"));
286 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("TruE"));
287 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("TruE"));
288
289 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("y")); // yes
290 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("Y"));
291 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("t")); // true
292 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("T"));
293 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("1"));
294 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("f")); // false
295 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("F"));
296 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("n")); // No
297 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("N"));
298 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("0"));
299 assertNull(BooleanUtils.toBooleanObject("z"));
300
301 assertNull(BooleanUtils.toBooleanObject("ab"));
302 assertNull(BooleanUtils.toBooleanObject("yoo"));
303 assertNull(BooleanUtils.toBooleanObject("true "));
304 assertNull(BooleanUtils.toBooleanObject("ono"));
305 }
306
307 @Test
308 public void test_toBooleanObject_String_String_String_String() {
309 assertSame(Boolean.TRUE, BooleanUtils.toBooleanObject(null, null, "N", "U"));
310 assertSame(Boolean.FALSE, BooleanUtils.toBooleanObject(null, "Y", null, "U"));
311 assertSame(null, BooleanUtils.toBooleanObject(null, "Y", "N", null));
312
313 assertEquals(Boolean.TRUE, BooleanUtils.toBooleanObject("Y", "Y", "N", "U"));
314 assertEquals(Boolean.FALSE, BooleanUtils.toBooleanObject("N", "Y", "N", "U"));
315 assertNull(BooleanUtils.toBooleanObject("U", "Y", "N", "U"));
316 }
317
318 @Test
319 public void test_toBooleanObject_String_String_String_String_noMatch() {
320 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.toBooleanObject("X", "Y", "N", "U"));
321 }
322
323 @Test
324 public void test_toBooleanObject_String_String_String_String_nullValue() {
325 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.toBooleanObject(null, "Y", "N", "U"));
326 }
327
328 @Test
329 public void test_toInteger_boolean() {
330 assertEquals(1, BooleanUtils.toInteger(true));
331 assertEquals(0, BooleanUtils.toInteger(false));
332 }
333
334 @Test
335 public void test_toInteger_boolean_int_int() {
336 assertEquals(6, BooleanUtils.toInteger(true, 6, 7));
337 assertEquals(7, BooleanUtils.toInteger(false, 6, 7));
338 }
339
340 @Test
341 public void test_toInteger_Boolean_int_int_int() {
342 assertEquals(6, BooleanUtils.toInteger(Boolean.TRUE, 6, 7, 8));
343 assertEquals(7, BooleanUtils.toInteger(Boolean.FALSE, 6, 7, 8));
344 assertEquals(8, BooleanUtils.toInteger(null, 6, 7, 8));
345 }
346
347 @Test
348 public void test_toIntegerObject_boolean() {
349 assertEquals(Integer.valueOf(1), BooleanUtils.toIntegerObject(true));
350 assertEquals(Integer.valueOf(0), BooleanUtils.toIntegerObject(false));
351 }
352
353 @Test
354 public void test_toIntegerObject_Boolean() {
355 assertEquals(Integer.valueOf(1), BooleanUtils.toIntegerObject(Boolean.TRUE));
356 assertEquals(Integer.valueOf(0), BooleanUtils.toIntegerObject(Boolean.FALSE));
357 assertNull(BooleanUtils.toIntegerObject(null));
358 }
359
360 @Test
361 public void test_toIntegerObject_boolean_Integer_Integer() {
362 final Integer six = Integer.valueOf(6);
363 final Integer seven = Integer.valueOf(7);
364 assertEquals(six, BooleanUtils.toIntegerObject(true, six, seven));
365 assertEquals(seven, BooleanUtils.toIntegerObject(false, six, seven));
366 }
367
368 @Test
369 public void test_toIntegerObject_Boolean_Integer_Integer_Integer() {
370 final Integer six = Integer.valueOf(6);
371 final Integer seven = Integer.valueOf(7);
372 final Integer eight = Integer.valueOf(8);
373 assertEquals(six, BooleanUtils.toIntegerObject(Boolean.TRUE, six, seven, eight));
374 assertEquals(seven, BooleanUtils.toIntegerObject(Boolean.FALSE, six, seven, eight));
375 assertEquals(eight, BooleanUtils.toIntegerObject(null, six, seven, eight));
376 assertNull(BooleanUtils.toIntegerObject(null, six, seven, null));
377 }
378
379 @Test
380 public void test_toString_boolean_String_String_String() {
381 assertEquals("Y", BooleanUtils.toString(true, "Y", "N"));
382 assertEquals("N", BooleanUtils.toString(false, "Y", "N"));
383 }
384
385 @Test
386 public void test_toString_Boolean_String_String_String() {
387 assertEquals("U", BooleanUtils.toString(null, "Y", "N", "U"));
388 assertEquals("Y", BooleanUtils.toString(Boolean.TRUE, "Y", "N", "U"));
389 assertEquals("N", BooleanUtils.toString(Boolean.FALSE, "Y", "N", "U"));
390 }
391
392 @Test
393 public void test_toStringOnOff_boolean() {
394 assertEquals("on", BooleanUtils.toStringOnOff(true));
395 assertEquals("off", BooleanUtils.toStringOnOff(false));
396 }
397
398 @Test
399 public void test_toStringOnOff_Boolean() {
400 assertNull(BooleanUtils.toStringOnOff(null));
401 assertEquals("on", BooleanUtils.toStringOnOff(Boolean.TRUE));
402 assertEquals("off", BooleanUtils.toStringOnOff(Boolean.FALSE));
403 }
404
405 @Test
406 public void test_toStringTrueFalse_boolean() {
407 assertEquals("true", BooleanUtils.toStringTrueFalse(true));
408 assertEquals("false", BooleanUtils.toStringTrueFalse(false));
409 }
410
391411 @Test
392412 public void test_toStringTrueFalse_Boolean() {
393413 assertNull(BooleanUtils.toStringTrueFalse(null));
396416 }
397417
398418 @Test
399 public void test_toStringOnOff_Boolean() {
400 assertNull(BooleanUtils.toStringOnOff(null));
401 assertEquals("on", BooleanUtils.toStringOnOff(Boolean.TRUE));
402 assertEquals("off", BooleanUtils.toStringOnOff(Boolean.FALSE));
419 public void test_toStringYesNo_boolean() {
420 assertEquals("yes", BooleanUtils.toStringYesNo(true));
421 assertEquals("no", BooleanUtils.toStringYesNo(false));
403422 }
404423
405424 @Test
410429 }
411430
412431 @Test
413 public void test_toString_Boolean_String_String_String() {
414 assertEquals("U", BooleanUtils.toString(null, "Y", "N", "U"));
415 assertEquals("Y", BooleanUtils.toString(Boolean.TRUE, "Y", "N", "U"));
416 assertEquals("N", BooleanUtils.toString(Boolean.FALSE, "Y", "N", "U"));
417 }
418
419 //-----------------------------------------------------------------------
420 @Test
421 public void test_toStringTrueFalse_boolean() {
422 assertEquals("true", BooleanUtils.toStringTrueFalse(true));
423 assertEquals("false", BooleanUtils.toStringTrueFalse(false));
424 }
425
426 @Test
427 public void test_toStringOnOff_boolean() {
428 assertEquals("on", BooleanUtils.toStringOnOff(true));
429 assertEquals("off", BooleanUtils.toStringOnOff(false));
430 }
431
432 @Test
433 public void test_toStringYesNo_boolean() {
434 assertEquals("yes", BooleanUtils.toStringYesNo(true));
435 assertEquals("no", BooleanUtils.toStringYesNo(false));
436 }
437
438 @Test
439 public void test_toString_boolean_String_String_String() {
440 assertEquals("Y", BooleanUtils.toString(true, "Y", "N"));
441 assertEquals("N", BooleanUtils.toString(false, "Y", "N"));
442 }
443
444 // testXor
445 // -----------------------------------------------------------------------
446 @Test
447 public void testXor_primitive_nullInput() {
448 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.xor((boolean[]) null));
449 }
450
451 @Test
452 public void testXor_primitive_emptyInput() {
453 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.xor(new boolean[] {}));
454 }
455
456 @Test
457 public void testXor_primitive_validInput_2items() {
458 assertEquals(
459 true ^ true,
460 BooleanUtils.xor(new boolean[] { true, true }),
461 "true ^ true");
462
463 assertEquals(
464 false ^ false,
465 BooleanUtils.xor(new boolean[] { false, false }),
466 "false ^ false");
467
468 assertEquals(
469 true ^ false,
470 BooleanUtils.xor(new boolean[] { true, false }),
471 "true ^ false");
472
473 assertEquals(
474 false ^ true,
475 BooleanUtils.xor(new boolean[] { false, true }),
476 "false ^ true");
477 }
478
479 @Test
480 public void testXor_primitive_validInput_3items() {
481 assertEquals(
482 false ^ false ^ false,
483 BooleanUtils.xor(new boolean[] { false, false, false }),
484 "false ^ false ^ false");
485
486 assertEquals(
487 false ^ false ^ true,
488 BooleanUtils.xor(new boolean[] { false, false, true }),
489 "false ^ false ^ true");
490
491 assertEquals(
492 false ^ true ^ false,
493 BooleanUtils.xor(new boolean[] { false, true, false }),
494 "false ^ true ^ false");
495
496 assertEquals(
497 false ^ true ^ true,
498 BooleanUtils.xor(new boolean[] { false, true, true }),
499 "false ^ true ^ true");
500
501 assertEquals(
502 true ^ false ^ false,
503 BooleanUtils.xor(new boolean[] { true, false, false }),
504 "true ^ false ^ false");
505
506 assertEquals(
507 true ^ false ^ true,
508 BooleanUtils.xor(new boolean[] { true, false, true }),
509 "true ^ false ^ true");
510
511 assertEquals(
512 true ^ true ^ false,
513 BooleanUtils.xor(new boolean[] { true, true, false }),
514 "true ^ true ^ false");
515
516 assertEquals(
517 true ^ true ^ true,
518 BooleanUtils.xor(new boolean[] { true, true, true }),
519 "true ^ true ^ true");
520 }
521
522 @Test
523 public void testXor_object_nullInput() {
524 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.xor((Boolean[]) null));
432 public void testAnd_object_emptyInput() {
433 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.and(new Boolean[] {}));
434 }
435
436 @Test
437 public void testAnd_object_nullElementInput() {
438 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.and(new Boolean[] {null}));
439 }
440
441 @Test
442 public void testAnd_object_nullInput() {
443 assertThrows(NullPointerException.class, () -> BooleanUtils.and((Boolean[]) null));
444 }
445
446 @Test
447 public void testAnd_object_validInput_2items() {
448 assertTrue(
449 BooleanUtils
450 .and(new Boolean[] { Boolean.TRUE, Boolean.TRUE })
451 .booleanValue(),
452 "False result for (true, true)");
453
454 assertTrue(
455 ! BooleanUtils
456 .and(new Boolean[] { Boolean.FALSE, Boolean.FALSE })
457 .booleanValue(),
458 "True result for (false, false)");
459
460 assertTrue(
461 ! BooleanUtils
462 .and(new Boolean[] { Boolean.TRUE, Boolean.FALSE })
463 .booleanValue(),
464 "True result for (true, false)");
465
466 assertTrue(
467 ! BooleanUtils
468 .and(new Boolean[] { Boolean.FALSE, Boolean.TRUE })
469 .booleanValue(),
470 "True result for (false, true)");
471 }
472
473 @Test
474 public void testAnd_object_validInput_3items() {
475 assertTrue(
476 ! BooleanUtils
477 .and(
478 new Boolean[] {
479 Boolean.FALSE,
480 Boolean.FALSE,
481 Boolean.TRUE })
482 .booleanValue(),
483 "True result for (false, false, true)");
484
485 assertTrue(
486 ! BooleanUtils
487 .and(
488 new Boolean[] {
489 Boolean.FALSE,
490 Boolean.TRUE,
491 Boolean.FALSE })
492 .booleanValue(),
493 "True result for (false, true, false)");
494
495 assertTrue(
496 ! BooleanUtils
497 .and(
498 new Boolean[] {
499 Boolean.TRUE,
500 Boolean.FALSE,
501 Boolean.FALSE })
502 .booleanValue(),
503 "True result for (true, false, false)");
504
505 assertTrue(
506 BooleanUtils
507 .and(new Boolean[] { Boolean.TRUE, Boolean.TRUE, Boolean.TRUE })
508 .booleanValue(),
509 "False result for (true, true, true)");
510
511 assertTrue(
512 ! BooleanUtils.and(
513 new Boolean[] {
514 Boolean.FALSE,
515 Boolean.FALSE,
516 Boolean.FALSE })
517 .booleanValue(),
518 "True result for (false, false)");
519
520 assertTrue(
521 ! BooleanUtils.and(
522 new Boolean[] {
523 Boolean.TRUE,
524 Boolean.TRUE,
525 Boolean.FALSE })
526 .booleanValue(),
527 "True result for (true, true, false)");
528
529 assertTrue(
530 ! BooleanUtils.and(
531 new Boolean[] {
532 Boolean.TRUE,
533 Boolean.FALSE,
534 Boolean.TRUE })
535 .booleanValue(),
536 "True result for (true, false, true)");
537
538 assertTrue(
539 ! BooleanUtils.and(
540 new Boolean[] {
541 Boolean.FALSE,
542 Boolean.TRUE,
543 Boolean.TRUE })
544 .booleanValue(),
545 "True result for (false, true, true)");
546 }
547
548 @Test
549 public void testAnd_primitive_emptyInput() {
550 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.and(new boolean[] {}));
551 }
552
553 @Test
554 public void testAnd_primitive_nullInput() {
555 assertThrows(NullPointerException.class, () -> BooleanUtils.and((boolean[]) null));
556 }
557
558 @Test
559 public void testAnd_primitive_validInput_2items() {
560 assertTrue(
561 BooleanUtils.and(new boolean[] { true, true }),
562 "False result for (true, true)");
563
564 assertTrue(
565 ! BooleanUtils.and(new boolean[] { false, false }),
566 "True result for (false, false)");
567
568 assertTrue(
569 ! BooleanUtils.and(new boolean[] { true, false }),
570 "True result for (true, false)");
571
572 assertTrue(
573 ! BooleanUtils.and(new boolean[] { false, true }),
574 "True result for (false, true)");
575 }
576
577 @Test
578 public void testAnd_primitive_validInput_3items() {
579 assertTrue(
580 ! BooleanUtils.and(new boolean[] { false, false, true }),
581 "True result for (false, false, true)");
582
583 assertTrue(
584 ! BooleanUtils.and(new boolean[] { false, true, false }),
585 "True result for (false, true, false)");
586
587 assertTrue(
588 ! BooleanUtils.and(new boolean[] { true, false, false }),
589 "True result for (true, false, false)");
590
591 assertTrue(
592 BooleanUtils.and(new boolean[] { true, true, true }),
593 "False result for (true, true, true)");
594
595 assertTrue(
596 ! BooleanUtils.and(new boolean[] { false, false, false }),
597 "True result for (false, false)");
598
599 assertTrue(
600 ! BooleanUtils.and(new boolean[] { true, true, false }),
601 "True result for (true, true, false)");
602
603 assertTrue(
604 ! BooleanUtils.and(new boolean[] { true, false, true }),
605 "True result for (true, false, true)");
606
607 assertTrue(
608 ! BooleanUtils.and(new boolean[] { false, true, true }),
609 "True result for (false, true, true)");
610 }
611
612 @Test
613 public void testCompare() {
614 assertTrue(BooleanUtils.compare(true, false) > 0);
615 assertEquals(0, BooleanUtils.compare(true, true));
616 assertEquals(0, BooleanUtils.compare(false, false));
617 assertTrue(BooleanUtils.compare(false, true) < 0);
618 }
619
620 @Test
621 public void testConstructor() {
622 assertNotNull(new BooleanUtils());
623 final Constructor<?>[] cons = BooleanUtils.class.getDeclaredConstructors();
624 assertEquals(1, cons.length);
625 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
626 assertTrue(Modifier.isPublic(BooleanUtils.class.getModifiers()));
627 assertFalse(Modifier.isFinal(BooleanUtils.class.getModifiers()));
628 }
629
630 @Test
631 public void testOr_object_emptyInput() {
632 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.or(new Boolean[] {}));
633 }
634
635 @Test
636 public void testOr_object_nullElementInput() {
637 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.or(new Boolean[] {null}));
638 }
639
640 @Test
641 public void testOr_object_nullInput() {
642 assertThrows(NullPointerException.class, () -> BooleanUtils.or((Boolean[]) null));
643 }
644
645 @Test
646 public void testOr_object_validInput_2items() {
647 assertTrue(
648 BooleanUtils
649 .or(new Boolean[] { Boolean.TRUE, Boolean.TRUE })
650 .booleanValue(),
651 "False result for (true, true)");
652
653 assertTrue(
654 ! BooleanUtils
655 .or(new Boolean[] { Boolean.FALSE, Boolean.FALSE })
656 .booleanValue(),
657 "True result for (false, false)");
658
659 assertTrue(
660 BooleanUtils
661 .or(new Boolean[] { Boolean.TRUE, Boolean.FALSE })
662 .booleanValue(),
663 "False result for (true, false)");
664
665 assertTrue(
666 BooleanUtils
667 .or(new Boolean[] { Boolean.FALSE, Boolean.TRUE })
668 .booleanValue(),
669 "False result for (false, true)");
670 }
671
672 @Test
673 public void testOr_object_validInput_3items() {
674 assertTrue(
675 BooleanUtils
676 .or(
677 new Boolean[] {
678 Boolean.FALSE,
679 Boolean.FALSE,
680 Boolean.TRUE })
681 .booleanValue(),
682 "False result for (false, false, true)");
683
684 assertTrue(
685 BooleanUtils
686 .or(
687 new Boolean[] {
688 Boolean.FALSE,
689 Boolean.TRUE,
690 Boolean.FALSE })
691 .booleanValue(),
692 "False result for (false, true, false)");
693
694 assertTrue(
695 BooleanUtils
696 .or(
697 new Boolean[] {
698 Boolean.TRUE,
699 Boolean.FALSE,
700 Boolean.FALSE })
701 .booleanValue(),
702 "False result for (true, false, false)");
703
704 assertTrue(
705 BooleanUtils
706 .or(new Boolean[] { Boolean.TRUE, Boolean.TRUE, Boolean.TRUE })
707 .booleanValue(),
708 "False result for (true, true, true)");
709
710 assertTrue(
711 ! BooleanUtils.or(
712 new Boolean[] {
713 Boolean.FALSE,
714 Boolean.FALSE,
715 Boolean.FALSE })
716 .booleanValue(),
717 "True result for (false, false)");
718
719 assertTrue(
720 BooleanUtils.or(
721 new Boolean[] {
722 Boolean.TRUE,
723 Boolean.TRUE,
724 Boolean.FALSE })
725 .booleanValue(),
726 "False result for (true, true, false)");
727
728 assertTrue(
729 BooleanUtils.or(
730 new Boolean[] {
731 Boolean.TRUE,
732 Boolean.FALSE,
733 Boolean.TRUE })
734 .booleanValue(),
735 "False result for (true, false, true)");
736
737 assertTrue(
738 BooleanUtils.or(
739 new Boolean[] {
740 Boolean.FALSE,
741 Boolean.TRUE,
742 Boolean.TRUE })
743 .booleanValue(),
744 "False result for (false, true, true)");
745 }
746
747 @Test
748 public void testOr_primitive_emptyInput() {
749 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.or(new boolean[] {}));
750 }
751
752 @Test
753 public void testOr_primitive_nullInput() {
754 assertThrows(NullPointerException.class, () -> BooleanUtils.or((boolean[]) null));
755 }
756
757 @Test
758 public void testOr_primitive_validInput_2items() {
759 assertTrue(
760 BooleanUtils.or(new boolean[] { true, true }),
761 "False result for (true, true)");
762
763 assertTrue(
764 ! BooleanUtils.or(new boolean[] { false, false }),
765 "True result for (false, false)");
766
767 assertTrue(
768 BooleanUtils.or(new boolean[] { true, false }),
769 "False result for (true, false)");
770
771 assertTrue(
772 BooleanUtils.or(new boolean[] { false, true }),
773 "False result for (false, true)");
774 }
775
776 @Test
777 public void testOr_primitive_validInput_3items() {
778 assertTrue(
779 BooleanUtils.or(new boolean[] { false, false, true }),
780 "False result for (false, false, true)");
781
782 assertTrue(
783 BooleanUtils.or(new boolean[] { false, true, false }),
784 "False result for (false, true, false)");
785
786 assertTrue(
787 BooleanUtils.or(new boolean[] { true, false, false }),
788 "False result for (true, false, false)");
789
790 assertTrue(
791 BooleanUtils.or(new boolean[] { true, true, true }),
792 "False result for (true, true, true)");
793
794 assertTrue(
795 ! BooleanUtils.or(new boolean[] { false, false, false }),
796 "True result for (false, false)");
797
798 assertTrue(
799 BooleanUtils.or(new boolean[] { true, true, false }),
800 "False result for (true, true, false)");
801
802 assertTrue(
803 BooleanUtils.or(new boolean[] { true, false, true }),
804 "False result for (true, false, true)");
805
806 assertTrue(
807 BooleanUtils.or(new boolean[] { false, true, true }),
808 "False result for (false, true, true)");
809
525810 }
526811
527812 @Test
534819 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.xor(new Boolean[] {null}));
535820 }
536821
822 @Test
823 public void testXor_object_nullInput() {
824 assertThrows(NullPointerException.class, () -> BooleanUtils.xor((Boolean[]) null));
825 }
537826 @Test
538827 public void testXor_object_validInput_2items() {
539828 assertEquals(
643932 "true ^ true ^ true");
644933 }
645934
646 // testAnd
647 // -----------------------------------------------------------------------
648 @Test
649 public void testAnd_primitive_nullInput() {
650 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.and((boolean[]) null));
651 }
652
653 @Test
654 public void testAnd_primitive_emptyInput() {
655 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.and(new boolean[] {}));
656 }
657
658 @Test
659 public void testAnd_primitive_validInput_2items() {
660 assertTrue(
661 BooleanUtils.and(new boolean[] { true, true }),
662 "False result for (true, true)");
663
664 assertTrue(
665 ! BooleanUtils.and(new boolean[] { false, false }),
666 "True result for (false, false)");
667
668 assertTrue(
669 ! BooleanUtils.and(new boolean[] { true, false }),
670 "True result for (true, false)");
671
672 assertTrue(
673 ! BooleanUtils.and(new boolean[] { false, true }),
674 "True result for (false, true)");
675 }
676
677 @Test
678 public void testAnd_primitive_validInput_3items() {
679 assertTrue(
680 ! BooleanUtils.and(new boolean[] { false, false, true }),
681 "True result for (false, false, true)");
682
683 assertTrue(
684 ! BooleanUtils.and(new boolean[] { false, true, false }),
685 "True result for (false, true, false)");
686
687 assertTrue(
688 ! BooleanUtils.and(new boolean[] { true, false, false }),
689 "True result for (true, false, false)");
690
691 assertTrue(
692 BooleanUtils.and(new boolean[] { true, true, true }),
693 "False result for (true, true, true)");
694
695 assertTrue(
696 ! BooleanUtils.and(new boolean[] { false, false, false }),
697 "True result for (false, false)");
698
699 assertTrue(
700 ! BooleanUtils.and(new boolean[] { true, true, false }),
701 "True result for (true, true, false)");
702
703 assertTrue(
704 ! BooleanUtils.and(new boolean[] { true, false, true }),
705 "True result for (true, false, true)");
706
707 assertTrue(
708 ! BooleanUtils.and(new boolean[] { false, true, true }),
709 "True result for (false, true, true)");
710 }
711
712 @Test
713 public void testAnd_object_nullInput() {
714 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.and((Boolean[]) null));
715 }
716
717 @Test
718 public void testAnd_object_emptyInput() {
719 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.and(new Boolean[] {}));
720 }
721
722 @Test
723 public void testAnd_object_nullElementInput() {
724 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.and(new Boolean[] {null}));
725 }
726
727 @Test
728 public void testAnd_object_validInput_2items() {
729 assertTrue(
730 BooleanUtils
731 .and(new Boolean[] { Boolean.TRUE, Boolean.TRUE })
732 .booleanValue(),
733 "False result for (true, true)");
734
735 assertTrue(
736 ! BooleanUtils
737 .and(new Boolean[] { Boolean.FALSE, Boolean.FALSE })
738 .booleanValue(),
739 "True result for (false, false)");
740
741 assertTrue(
742 ! BooleanUtils
743 .and(new Boolean[] { Boolean.TRUE, Boolean.FALSE })
744 .booleanValue(),
745 "True result for (true, false)");
746
747 assertTrue(
748 ! BooleanUtils
749 .and(new Boolean[] { Boolean.FALSE, Boolean.TRUE })
750 .booleanValue(),
751 "True result for (false, true)");
752 }
753
754 @Test
755 public void testAnd_object_validInput_3items() {
756 assertTrue(
757 ! BooleanUtils
758 .and(
759 new Boolean[] {
760 Boolean.FALSE,
761 Boolean.FALSE,
762 Boolean.TRUE })
763 .booleanValue(),
764 "True result for (false, false, true)");
765
766 assertTrue(
767 ! BooleanUtils
768 .and(
769 new Boolean[] {
770 Boolean.FALSE,
771 Boolean.TRUE,
772 Boolean.FALSE })
773 .booleanValue(),
774 "True result for (false, true, false)");
775
776 assertTrue(
777 ! BooleanUtils
778 .and(
779 new Boolean[] {
780 Boolean.TRUE,
781 Boolean.FALSE,
782 Boolean.FALSE })
783 .booleanValue(),
784 "True result for (true, false, false)");
785
786 assertTrue(
787 BooleanUtils
788 .and(new Boolean[] { Boolean.TRUE, Boolean.TRUE, Boolean.TRUE })
789 .booleanValue(),
790 "False result for (true, true, true)");
791
792 assertTrue(
793 ! BooleanUtils.and(
794 new Boolean[] {
795 Boolean.FALSE,
796 Boolean.FALSE,
797 Boolean.FALSE })
798 .booleanValue(),
799 "True result for (false, false)");
800
801 assertTrue(
802 ! BooleanUtils.and(
803 new Boolean[] {
804 Boolean.TRUE,
805 Boolean.TRUE,
806 Boolean.FALSE })
807 .booleanValue(),
808 "True result for (true, true, false)");
809
810 assertTrue(
811 ! BooleanUtils.and(
812 new Boolean[] {
813 Boolean.TRUE,
814 Boolean.FALSE,
815 Boolean.TRUE })
816 .booleanValue(),
817 "True result for (true, false, true)");
818
819 assertTrue(
820 ! BooleanUtils.and(
821 new Boolean[] {
822 Boolean.FALSE,
823 Boolean.TRUE,
824 Boolean.TRUE })
825 .booleanValue(),
826 "True result for (false, true, true)");
827 }
828
829 // testOr
830 // -----------------------------------------------------------------------
831 @Test
832 public void testOr_primitive_nullInput() {
833 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.or((boolean[]) null));
834 }
835
836 @Test
837 public void testOr_primitive_emptyInput() {
838 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.or(new boolean[] {}));
839 }
840
841 @Test
842 public void testOr_primitive_validInput_2items() {
843 assertTrue(
844 BooleanUtils.or(new boolean[] { true, true }),
845 "False result for (true, true)");
846
847 assertTrue(
848 ! BooleanUtils.or(new boolean[] { false, false }),
849 "True result for (false, false)");
850
851 assertTrue(
852 BooleanUtils.or(new boolean[] { true, false }),
853 "False result for (true, false)");
854
855 assertTrue(
856 BooleanUtils.or(new boolean[] { false, true }),
857 "False result for (false, true)");
858 }
859
860 @Test
861 public void testOr_primitive_validInput_3items() {
862 assertTrue(
863 BooleanUtils.or(new boolean[] { false, false, true }),
864 "False result for (false, false, true)");
865
866 assertTrue(
867 BooleanUtils.or(new boolean[] { false, true, false }),
868 "False result for (false, true, false)");
869
870 assertTrue(
871 BooleanUtils.or(new boolean[] { true, false, false }),
872 "False result for (true, false, false)");
873
874 assertTrue(
875 BooleanUtils.or(new boolean[] { true, true, true }),
876 "False result for (true, true, true)");
877
878 assertTrue(
879 ! BooleanUtils.or(new boolean[] { false, false, false }),
880 "True result for (false, false)");
881
882 assertTrue(
883 BooleanUtils.or(new boolean[] { true, true, false }),
884 "False result for (true, true, false)");
885
886 assertTrue(
887 BooleanUtils.or(new boolean[] { true, false, true }),
888 "False result for (true, false, true)");
889
890 assertTrue(
891 BooleanUtils.or(new boolean[] { false, true, true }),
892 "False result for (false, true, true)");
893
894 }
895 @Test
896 public void testOr_object_nullInput() {
897 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.or((Boolean[]) null));
898 }
899
900 @Test
901 public void testOr_object_emptyInput() {
902 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.or(new Boolean[] {}));
903 }
904
905 @Test
906 public void testOr_object_nullElementInput() {
907 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.or(new Boolean[] {null}));
908 }
909
910 @Test
911 public void testOr_object_validInput_2items() {
912 assertTrue(
913 BooleanUtils
914 .or(new Boolean[] { Boolean.TRUE, Boolean.TRUE })
915 .booleanValue(),
916 "False result for (true, true)");
917
918 assertTrue(
919 ! BooleanUtils
920 .or(new Boolean[] { Boolean.FALSE, Boolean.FALSE })
921 .booleanValue(),
922 "True result for (false, false)");
923
924 assertTrue(
925 BooleanUtils
926 .or(new Boolean[] { Boolean.TRUE, Boolean.FALSE })
927 .booleanValue(),
928 "False result for (true, false)");
929
930 assertTrue(
931 BooleanUtils
932 .or(new Boolean[] { Boolean.FALSE, Boolean.TRUE })
933 .booleanValue(),
934 "False result for (false, true)");
935 }
936
937 @Test
938 public void testOr_object_validInput_3items() {
939 assertTrue(
940 BooleanUtils
941 .or(
942 new Boolean[] {
943 Boolean.FALSE,
944 Boolean.FALSE,
945 Boolean.TRUE })
946 .booleanValue(),
947 "False result for (false, false, true)");
948
949 assertTrue(
950 BooleanUtils
951 .or(
952 new Boolean[] {
953 Boolean.FALSE,
954 Boolean.TRUE,
955 Boolean.FALSE })
956 .booleanValue(),
957 "False result for (false, true, false)");
958
959 assertTrue(
960 BooleanUtils
961 .or(
962 new Boolean[] {
963 Boolean.TRUE,
964 Boolean.FALSE,
965 Boolean.FALSE })
966 .booleanValue(),
967 "False result for (true, false, false)");
968
969 assertTrue(
970 BooleanUtils
971 .or(new Boolean[] { Boolean.TRUE, Boolean.TRUE, Boolean.TRUE })
972 .booleanValue(),
973 "False result for (true, true, true)");
974
975 assertTrue(
976 ! BooleanUtils.or(
977 new Boolean[] {
978 Boolean.FALSE,
979 Boolean.FALSE,
980 Boolean.FALSE })
981 .booleanValue(),
982 "True result for (false, false)");
983
984 assertTrue(
985 BooleanUtils.or(
986 new Boolean[] {
987 Boolean.TRUE,
988 Boolean.TRUE,
989 Boolean.FALSE })
990 .booleanValue(),
991 "False result for (true, true, false)");
992
993 assertTrue(
994 BooleanUtils.or(
995 new Boolean[] {
996 Boolean.TRUE,
997 Boolean.FALSE,
998 Boolean.TRUE })
999 .booleanValue(),
1000 "False result for (true, false, true)");
1001
1002 assertTrue(
1003 BooleanUtils.or(
1004 new Boolean[] {
1005 Boolean.FALSE,
1006 Boolean.TRUE,
1007 Boolean.TRUE })
1008 .booleanValue(),
1009 "False result for (false, true, true)");
1010 }
1011
1012 @Test
1013 public void testCompare() {
1014 assertTrue(BooleanUtils.compare(true, false) > 0);
1015 assertEquals(0, BooleanUtils.compare(true, true));
1016 assertEquals(0, BooleanUtils.compare(false, false));
1017 assertTrue(BooleanUtils.compare(false, true) < 0);
935 @Test
936 public void testXor_primitive_emptyInput() {
937 assertThrows(IllegalArgumentException.class, () -> BooleanUtils.xor(new boolean[] {}));
938 }
939
940 @Test
941 public void testXor_primitive_nullInput() {
942 assertThrows(NullPointerException.class, () -> BooleanUtils.xor((boolean[]) null));
943 }
944
945 @Test
946 public void testXor_primitive_validInput_2items() {
947 assertEquals(
948 true ^ true,
949 BooleanUtils.xor(new boolean[] { true, true }),
950 "true ^ true");
951
952 assertEquals(
953 false ^ false,
954 BooleanUtils.xor(new boolean[] { false, false }),
955 "false ^ false");
956
957 assertEquals(
958 true ^ false,
959 BooleanUtils.xor(new boolean[] { true, false }),
960 "true ^ false");
961
962 assertEquals(
963 false ^ true,
964 BooleanUtils.xor(new boolean[] { false, true }),
965 "false ^ true");
966 }
967
968 @Test
969 public void testXor_primitive_validInput_3items() {
970 assertEquals(
971 false ^ false ^ false,
972 BooleanUtils.xor(new boolean[] { false, false, false }),
973 "false ^ false ^ false");
974
975 assertEquals(
976 false ^ false ^ true,
977 BooleanUtils.xor(new boolean[] { false, false, true }),
978 "false ^ false ^ true");
979
980 assertEquals(
981 false ^ true ^ false,
982 BooleanUtils.xor(new boolean[] { false, true, false }),
983 "false ^ true ^ false");
984
985 assertEquals(
986 false ^ true ^ true,
987 BooleanUtils.xor(new boolean[] { false, true, true }),
988 "false ^ true ^ true");
989
990 assertEquals(
991 true ^ false ^ false,
992 BooleanUtils.xor(new boolean[] { true, false, false }),
993 "true ^ false ^ false");
994
995 assertEquals(
996 true ^ false ^ true,
997 BooleanUtils.xor(new boolean[] { true, false, true }),
998 "true ^ false ^ true");
999
1000 assertEquals(
1001 true ^ true ^ false,
1002 BooleanUtils.xor(new boolean[] { true, true, false }),
1003 "true ^ true ^ false");
1004
1005 assertEquals(
1006 true ^ true ^ true,
1007 BooleanUtils.xor(new boolean[] { true, true, true }),
1008 "true ^ true ^ true");
10181009 }
10191010
10201011 }
311311 public void testContainsNullArg() {
312312 final CharRange range = CharRange.is('a');
313313 final NullPointerException e = assertThrows(NullPointerException.class, () -> range.contains(null));
314 assertEquals("The Range must not be null", e.getMessage());
314 assertEquals("range", e.getMessage());
315315 }
316316
317317 @Test
2222 import static org.junit.jupiter.api.Assertions.assertNull;
2323 import static org.junit.jupiter.api.Assertions.assertThrows;
2424 import static org.junit.jupiter.api.Assertions.assertTrue;
25 import static org.junit.jupiter.params.provider.Arguments.arguments;
2526
2627 import java.lang.reflect.Constructor;
2728 import java.lang.reflect.Modifier;
2829 import java.util.Random;
2930 import java.util.stream.IntStream;
31 import java.util.stream.Stream;
3032
3133 import org.junit.jupiter.api.Test;
34 import org.junit.jupiter.params.ParameterizedTest;
35 import org.junit.jupiter.params.provider.Arguments;
36 import org.junit.jupiter.params.provider.MethodSource;
3237
3338 /**
3439 * Tests CharSequenceUtils
260265 }
261266 }
262267
268 @ParameterizedTest
269 @MethodSource("lastIndexWithStandardCharSequence")
270 public void testLastIndexOfWithDifferentCharSequences(final CharSequence cs, final CharSequence search, final int start,
271 final int expected) {
272 assertEquals(expected, CharSequenceUtils.lastIndexOf(cs, search, start));
273 }
274
275 static Stream<Arguments> lastIndexWithStandardCharSequence() {
276 return Stream.of(
277 arguments("abc", "b", 2, 1),
278 arguments(new StringBuilder("abc"), "b", 2, 1),
279 arguments(new StringBuffer("abc"), "b", 2, 1),
280 arguments("abc", new StringBuilder("b"), 2, 1),
281 arguments(new StringBuilder("abc"), new StringBuilder("b"), 2, 1),
282 arguments(new StringBuffer("abc"), new StringBuffer("b"), 2, 1),
283 arguments(new StringBuilder("abc"), new StringBuffer("b"), 2, 1)
284 );
285 }
286
263287 private void testNewLastIndexOfSingle(final CharSequence a, final CharSequence b) {
264288 final int maxa = Math.max(a.length(), b.length());
265289 for (int i = -maxa - 10; i <= maxa + 10; i++) {
293293 @Test
294294 public void testConstructor_String_oddCombinations() {
295295 CharSet set;
296 CharRange[] array = null;
296 CharRange[] array;
297297
298298 set = CharSet.getInstance("a-^c");
299299 array = set.getCharRanges();
9898
9999 private void run() {
100100 this.printSysInfo();
101 long start;
102 start = System.currentTimeMillis();
103 this.printlnTotal("Do nothing", start);
101 long startMillis;
102 startMillis = System.currentTimeMillis();
103 this.printlnTotal("Do nothing", startMillis);
104104 run_CharUtils_isAsciiNumeric(WARM_UP);
105 start = System.currentTimeMillis();
105 startMillis = System.currentTimeMillis();
106106 run_CharUtils_isAsciiNumeric(COUNT);
107 this.printlnTotal("run_CharUtils_isAsciiNumeric", start);
107 this.printlnTotal("run_CharUtils_isAsciiNumeric", startMillis);
108108 run_inlined_CharUtils_isAsciiNumeric(WARM_UP);
109 start = System.currentTimeMillis();
109 startMillis = System.currentTimeMillis();
110110 run_inlined_CharUtils_isAsciiNumeric(COUNT);
111 this.printlnTotal("run_inlined_CharUtils_isAsciiNumeric", start);
111 this.printlnTotal("run_inlined_CharUtils_isAsciiNumeric", startMillis);
112112 run_CharSet(WARM_UP);
113 start = System.currentTimeMillis();
113 startMillis = System.currentTimeMillis();
114114 run_CharSet(COUNT);
115 this.printlnTotal("run_CharSet", start);
115 this.printlnTotal("run_CharSet", startMillis);
116116 }
117117
118118 private int run_CharSet(final int loopCount) {
148148 return t;
149149 }
150150
151 private void printlnTotal(final String prefix, final long start) {
152 final long total = System.currentTimeMillis() - start;
153 System.out.println(prefix + ": " + NumberFormat.getInstance().format(total) + " milliseconds.");
151 private void printlnTotal(final String prefix, final long startMillis) {
152 final long totalMillis = System.currentTimeMillis() - startMillis;
153 System.out.println(prefix + ": " + NumberFormat.getInstance().format(totalMillis) + " milliseconds.");
154154 }
155155 }
2525 import static org.apache.commons.lang3.JavaVersion.JAVA_14;
2626 import static org.apache.commons.lang3.JavaVersion.JAVA_15;
2727 import static org.apache.commons.lang3.JavaVersion.JAVA_16;
28 import static org.apache.commons.lang3.JavaVersion.JAVA_17;
2829 import static org.apache.commons.lang3.JavaVersion.JAVA_1_1;
2930 import static org.apache.commons.lang3.JavaVersion.JAVA_1_2;
3031 import static org.apache.commons.lang3.JavaVersion.JAVA_1_3;
6768 assertEquals(JAVA_14, get("14"), "14 failed");
6869 assertEquals(JAVA_15, get("15"), "15 failed");
6970 assertEquals(JAVA_16, get("16"), "16 failed");
71 assertEquals(JAVA_17, get("17"), "17 failed");
7072 assertEquals(JAVA_RECENT, get("1.10"), "1.10 failed");
7173 // assertNull("2.10 unexpectedly worked", get("2.10"));
7274 assertEquals(get("1.5"), getJavaVersion("1.5"), "Wrapper method failed");
73 assertEquals(JAVA_RECENT, get("17"), "Unhandled"); // LANG-1384
75 assertEquals(JAVA_RECENT, get("18"), "Unhandled"); // LANG-1384
7476 }
7577
7678 @Test
122122 }
123123
124124 /**
125 * Test toLocale() method.
125 * Test toLocale(Locale) method.
126 */
127 @Test
128 public void testToLocale_Locale_defaults() {
129 assertNull(LocaleUtils.toLocale((String) null));
130 assertEquals(Locale.getDefault(), LocaleUtils.toLocale((Locale) null));
131 assertEquals(Locale.getDefault(), LocaleUtils.toLocale(Locale.getDefault()));
132 }
133
134 /**
135 * Test toLocale(Locale) method.
136 */
137 @ParameterizedTest
138 @MethodSource("java.util.Locale#getAvailableLocales")
139 public void testToLocales(final Locale actualLocale) {
140 assertEquals(actualLocale, LocaleUtils.toLocale(actualLocale));
141 }
142
143 /**
144 * Test toLocale(String) method.
126145 */
127146 @Test
128147 public void testToLocale_1Part() {
129 assertNull(LocaleUtils.toLocale(null));
148 assertNull(LocaleUtils.toLocale((String) null));
130149
131150 assertValidToLocale("us");
132151 assertValidToLocale("fr");
523542
524543 @ParameterizedTest
525544 @MethodSource("java.util.Locale#getAvailableLocales")
526 public void testParseAllLocales(final Locale l) {
545 public void testParseAllLocales(final Locale actualLocale) {
527546 // Check if it's possible to recreate the Locale using just the standard constructor
528 final Locale locale = new Locale(l.getLanguage(), l.getCountry(), l.getVariant());
529 if (l.equals(locale)) { // it is possible for LocaleUtils.toLocale to handle these Locales
530 final String str = l.toString();
547 final Locale locale = new Locale(actualLocale.getLanguage(), actualLocale.getCountry(), actualLocale.getVariant());
548 if (actualLocale.equals(locale)) { // it is possible for LocaleUtils.toLocale to handle these Locales
549 final String str = actualLocale.toString();
531550 // Look for the script/extension suffix
532551 int suff = str.indexOf("_#");
533552 if (suff == - 1) {
540559 localeStr = str.substring(0, suff);
541560 }
542561 final Locale loc = LocaleUtils.toLocale(localeStr);
543 assertEquals(l, loc);
562 assertEquals(actualLocale, loc);
544563 }
545564 }
546565 }
2929 import java.io.IOException;
3030 import java.lang.reflect.Constructor;
3131 import java.lang.reflect.Modifier;
32 import java.time.Duration;
3233 import java.util.ArrayList;
3334 import java.util.Arrays;
3435 import java.util.Calendar;
5354 */
5455 @SuppressWarnings("deprecation") // deliberate use of deprecated code
5556 public class ObjectUtilsTest {
57 static final class CharSequenceComparator implements Comparator<CharSequence> {
58
59 @Override
60 public int compare(final CharSequence o1, final CharSequence o2) {
61 return o1.toString().compareTo(o2.toString());
62 }
63
64 }
65 /**
66 * String that is cloneable.
67 */
68 static final class CloneableString extends MutableObject<String> implements Cloneable {
69 private static final long serialVersionUID = 1L;
70 CloneableString(final String s) {
71 super(s);
72 }
73
74 @Override
75 public CloneableString clone() throws CloneNotSupportedException {
76 return (CloneableString) super.clone();
77 }
78 }
79 static final class NonComparableCharSequence implements CharSequence {
80 final String value;
81
82 /**
83 * Create a new NonComparableCharSequence instance.
84 *
85 * @param value the CharSequence value
86 */
87 NonComparableCharSequence(final String value) {
88 Validate.notNull(value);
89 this.value = value;
90 }
91
92 @Override
93 public char charAt(final int arg0) {
94 return value.charAt(arg0);
95 }
96
97 @Override
98 public int length() {
99 return value.length();
100 }
101
102 @Override
103 public CharSequence subSequence(final int arg0, final int arg1) {
104 return value.subSequence(arg0, arg1);
105 }
106
107 @Override
108 public String toString() {
109 return value;
110 }
111 }
112 /**
113 * String that is not cloneable.
114 */
115 static final class UncloneableString extends MutableObject<String> implements Cloneable {
116 private static final long serialVersionUID = 1L;
117 UncloneableString(final String s) {
118 super(s);
119 }
120 }
56121 private static final String FOO = "foo";
57122 private static final String BAR = "bar";
58123 private static final String[] NON_EMPTY_ARRAY = new String[] { FOO, BAR, };
124
59125 private static final List<String> NON_EMPTY_LIST = Arrays.asList(NON_EMPTY_ARRAY);
126
60127 private static final Set<String> NON_EMPTY_SET = new HashSet<>(NON_EMPTY_LIST);
128
61129 private static final Map<String, String> NON_EMPTY_MAP = new HashMap<>();
130
62131 static {
63132 NON_EMPTY_MAP.put(FOO, BAR);
64 }
65
66 //-----------------------------------------------------------------------
67 @Test
68 public void testConstructor() {
69 assertNotNull(new ObjectUtils());
70 final Constructor<?>[] cons = ObjectUtils.class.getDeclaredConstructors();
71 assertEquals(1, cons.length);
72 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
73 assertTrue(Modifier.isPublic(ObjectUtils.class.getModifiers()));
74 assertFalse(Modifier.isFinal(ObjectUtils.class.getModifiers()));
75 }
76
77 //-----------------------------------------------------------------------
78 @Test
79 public void testIsEmpty() {
80 assertTrue(ObjectUtils.isEmpty(null));
81 assertTrue(ObjectUtils.isEmpty(""));
82 assertTrue(ObjectUtils.isEmpty(new int[] {}));
83 assertTrue(ObjectUtils.isEmpty(Collections.emptyList()));
84 assertTrue(ObjectUtils.isEmpty(Collections.emptySet()));
85 assertTrue(ObjectUtils.isEmpty(Collections.emptyMap()));
86
87 assertFalse(ObjectUtils.isEmpty(" "));
88 assertFalse(ObjectUtils.isEmpty("ab"));
89 assertFalse(ObjectUtils.isEmpty(NON_EMPTY_ARRAY));
90 assertFalse(ObjectUtils.isEmpty(NON_EMPTY_LIST));
91 assertFalse(ObjectUtils.isEmpty(NON_EMPTY_SET));
92 assertFalse(ObjectUtils.isEmpty(NON_EMPTY_MAP));
93 }
94
95 @Test
96 public void testIsNotEmpty() {
97 assertFalse(ObjectUtils.isNotEmpty(null));
98 assertFalse(ObjectUtils.isNotEmpty(""));
99 assertFalse(ObjectUtils.isNotEmpty(new int[] {}));
100 assertFalse(ObjectUtils.isNotEmpty(Collections.emptyList()));
101 assertFalse(ObjectUtils.isNotEmpty(Collections.emptySet()));
102 assertFalse(ObjectUtils.isNotEmpty(Collections.emptyMap()));
103
104 assertTrue(ObjectUtils.isNotEmpty(" "));
105 assertTrue(ObjectUtils.isNotEmpty("ab"));
106 assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_ARRAY));
107 assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_LIST));
108 assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_SET));
109 assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_MAP));
110 }
111
112 //-----------------------------------------------------------------------
113 @Test
114 public void testDefaultIfNull() {
115 final Object o = FOO;
116 final Object dflt = BAR;
117 assertSame(dflt, ObjectUtils.defaultIfNull(null, dflt), "dflt was not returned when o was null");
118 assertSame(o, ObjectUtils.defaultIfNull(o, dflt), "dflt was returned when o was not null");
119 assertSame(dflt, ObjectUtils.getIfNull(null, () -> dflt), "dflt was not returned when o was null");
120 assertSame(o, ObjectUtils.getIfNull(o, () -> dflt), "dflt was returned when o was not null");
121 assertSame(o, ObjectUtils.getIfNull(FOO, () -> dflt), "dflt was returned when o was not null");
122 assertSame(o, ObjectUtils.getIfNull("foo", () -> dflt), "dflt was returned when o was not null");
123 final MutableInt callsCounter = new MutableInt(0);
124 final Supplier<Object> countingDefaultSupplier = () -> {
125 callsCounter.increment();
126 return dflt;
127 };
128 ObjectUtils.getIfNull(o, countingDefaultSupplier);
129 assertEquals(0, callsCounter.getValue());
130 ObjectUtils.getIfNull(null, countingDefaultSupplier);
131 assertEquals(1, callsCounter.getValue());
132 }
133
134 @Test
135 public void testFirstNonNull() {
136 assertEquals("", ObjectUtils.firstNonNull(null, ""));
137 final String firstNonNullGenerics = ObjectUtils.firstNonNull(null, null, "123", "456");
138 assertEquals("123", firstNonNullGenerics);
139 assertEquals("123", ObjectUtils.firstNonNull("123", null, "456", null));
140 assertSame(Boolean.TRUE, ObjectUtils.firstNonNull(Boolean.TRUE));
141
142 // Explicitly pass in an empty array of Object type to ensure compiler doesn't complain of unchecked generic array creation
143 assertNull(ObjectUtils.firstNonNull());
144
145 // Cast to Object in line below ensures compiler doesn't complain of unchecked generic array creation
146 assertNull(ObjectUtils.firstNonNull(null, null));
147
148 assertNull(ObjectUtils.firstNonNull((Object) null));
149 assertNull(ObjectUtils.firstNonNull((Object[]) null));
150 }
151
152 @Test
153 public void testGetFirstNonNull() {
154 // first non null
155 assertEquals("", ObjectUtils.getFirstNonNull(() -> null, () -> ""));
156 // first encountered value is used
157 assertEquals("1", ObjectUtils.getFirstNonNull(() -> null, () -> "1", () -> "2", () -> null));
158 assertEquals("123", ObjectUtils.getFirstNonNull(() -> "123", () -> null, () -> "456"));
159 // don't evaluate suppliers after first value is found
160 assertEquals("123", ObjectUtils.getFirstNonNull(() -> null, () -> "123", () -> fail("Supplier after first non-null value should not be evaluated")));
161 // supplier returning null and null supplier both result in null
162 assertNull(ObjectUtils.getFirstNonNull(null, () -> null));
163 // Explicitly pass in an empty array of Object type to ensure compiler doesn't complain of unchecked generic array creation
164 assertNull(ObjectUtils.getFirstNonNull());
165 // supplier is null
166 assertNull(ObjectUtils.getFirstNonNull((Supplier<Object>) null));
167 // varargs array itself is null
168 assertNull(ObjectUtils.getFirstNonNull((Supplier<Object>[]) null));
169 // test different types
170 assertEquals(1, ObjectUtils.getFirstNonNull(() -> null, () -> 1));
171 assertEquals(Boolean.TRUE, ObjectUtils.getFirstNonNull(() -> null, () -> Boolean.TRUE));
172 }
173
174 /**
175 * Tests {@link ObjectUtils#anyNull(Object...)}.
176 */
177 @Test
178 public void testAnyNull() {
179 assertTrue(ObjectUtils.anyNull((Object) null));
180 assertTrue(ObjectUtils.anyNull(null, null, null));
181 assertTrue(ObjectUtils.anyNull(null, FOO, BAR));
182 assertTrue(ObjectUtils.anyNull(FOO, BAR, null));
183 assertTrue(ObjectUtils.anyNull(FOO, BAR, null, FOO, BAR));
184
185 assertFalse(ObjectUtils.anyNull());
186 assertFalse(ObjectUtils.anyNull(FOO));
187 assertFalse(ObjectUtils.anyNull(FOO, BAR, 1, Boolean.TRUE, new Object(), new Object[]{}));
188 }
189
190 /**
191 * Tests {@link ObjectUtils#anyNotNull(Object...)}.
192 */
193 @Test
194 public void testAnyNotNull() {
195 assertFalse(ObjectUtils.anyNotNull());
196 assertFalse(ObjectUtils.anyNotNull((Object) null));
197 assertFalse(ObjectUtils.anyNotNull((Object[]) null));
198 assertFalse(ObjectUtils.anyNotNull(null, null, null));
199
200 assertTrue(ObjectUtils.anyNotNull(FOO));
201 assertTrue(ObjectUtils.anyNotNull(null, FOO, null));
202 assertTrue(ObjectUtils.anyNotNull(null, null, null, null, FOO, BAR));
203 }
204
205 /**
206 * Tests {@link ObjectUtils#allNull(Object...)}.
207 */
208 @Test
209 public void testAllNull() {
210 assertTrue(ObjectUtils.allNull());
211 assertTrue(ObjectUtils.allNull((Object) null));
212 assertTrue(ObjectUtils.allNull((Object[]) null));
213 assertTrue(ObjectUtils.allNull(null, null, null));
214
215 assertFalse(ObjectUtils.allNull(FOO));
216 assertFalse(ObjectUtils.allNull(null, FOO, null));
217 assertFalse(ObjectUtils.allNull(null, null, null, null, FOO, BAR));
218133 }
219134
220135 /**
234149 assertTrue(ObjectUtils.allNotNull(FOO, BAR, 1, Boolean.TRUE, new Object(), new Object[]{}));
235150 }
236151
237 //-----------------------------------------------------------------------
238 @Test
239 public void testEquals() {
240 assertTrue(ObjectUtils.equals(null, null), "ObjectUtils.equals(null, null) returned false");
241 assertTrue(!ObjectUtils.equals(FOO, null), "ObjectUtils.equals(\"foo\", null) returned true");
242 assertTrue(!ObjectUtils.equals(null, BAR), "ObjectUtils.equals(null, \"bar\") returned true");
243 assertTrue(!ObjectUtils.equals(FOO, BAR), "ObjectUtils.equals(\"foo\", \"bar\") returned true");
244 assertTrue(ObjectUtils.equals(FOO, FOO), "ObjectUtils.equals(\"foo\", \"foo\") returned false");
245 }
246
247 @Test
248 public void testNotEqual() {
249 assertFalse(ObjectUtils.notEqual(null, null), "ObjectUtils.notEqual(null, null) returned false");
250 assertTrue(ObjectUtils.notEqual(FOO, null), "ObjectUtils.notEqual(\"foo\", null) returned true");
251 assertTrue(ObjectUtils.notEqual(null, BAR), "ObjectUtils.notEqual(null, \"bar\") returned true");
252 assertTrue(ObjectUtils.notEqual(FOO, BAR), "ObjectUtils.notEqual(\"foo\", \"bar\") returned true");
253 assertFalse(ObjectUtils.notEqual(FOO, FOO), "ObjectUtils.notEqual(\"foo\", \"foo\") returned false");
254 }
255
256 @Test
257 public void testHashCode() {
258 assertEquals(0, ObjectUtils.hashCode(null));
259 assertEquals("a".hashCode(), ObjectUtils.hashCode("a"));
260 }
261
262 @Test
263 public void testHashCodeMulti_multiple_emptyArray() {
264 final Object[] array = new Object[0];
265 assertEquals(1, ObjectUtils.hashCodeMulti(array));
266 }
267
268 @Test
269 public void testHashCodeMulti_multiple_nullArray() {
270 final Object[] array = null;
271 assertEquals(1, ObjectUtils.hashCodeMulti(array));
272 }
273
274 @Test
275 public void testHashCodeMulti_multiple_likeList() {
276 final List<Object> list0 = new ArrayList<>(Collections.emptyList());
277 assertEquals(list0.hashCode(), ObjectUtils.hashCodeMulti());
278
279 final List<Object> list1 = new ArrayList<>(Collections.singletonList("a"));
280 assertEquals(list1.hashCode(), ObjectUtils.hashCodeMulti("a"));
281
282 final List<Object> list2 = new ArrayList<>(Arrays.asList("a", "b"));
283 assertEquals(list2.hashCode(), ObjectUtils.hashCodeMulti("a", "b"));
284
285 final List<Object> list3 = new ArrayList<>(Arrays.asList("a", "b", "c"));
286 assertEquals(list3.hashCode(), ObjectUtils.hashCodeMulti("a", "b", "c"));
287 }
288
289 @Test
290 public void testIdentityToStringStringBuffer() {
291 final Integer i = Integer.valueOf(45);
292 final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
293
294 final StringBuffer buffer = new StringBuffer();
295 ObjectUtils.identityToString(buffer, i);
296 assertEquals(expected, buffer.toString());
297
298 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((StringBuffer) null, "tmp"));
299 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString(new StringBuffer(), null));
300 }
301
302 @Test
303 public void testIdentityToStringObjectNull() {
304 assertNull(ObjectUtils.identityToString(null));
305 }
306
307 @Test
308 public void testIdentityToStringInteger() {
309 final Integer i = Integer.valueOf(90);
310 final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
311
312 assertEquals(expected, ObjectUtils.identityToString(i));
313 }
314
315 @Test
316 public void testIdentityToStringString() {
317 assertEquals(
318 "java.lang.String@" + Integer.toHexString(System.identityHashCode(FOO)),
319 ObjectUtils.identityToString(FOO));
320 }
321
322 @Test
323 public void testIdentityToStringStringBuilder() {
324 final Integer i = Integer.valueOf(90);
325 final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
326
327 final StringBuilder builder = new StringBuilder();
328 ObjectUtils.identityToString(builder, i);
329 assertEquals(expected, builder.toString());
330 }
331
332 @Test
333 public void testIdentityToStringStringBuilderInUse() {
334 final Integer i = Integer.valueOf(90);
335 final String expected = "ABC = java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
336
337 final StringBuilder builder = new StringBuilder("ABC = ");
338 ObjectUtils.identityToString(builder, i);
339 assertEquals(expected, builder.toString());
340 }
341
342 @Test
343 public void testIdentityToStringStringBuilderNullValue() {
344 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString(new StringBuilder(), null));
345 }
346
347 @Test
348 public void testIdentityToStringStringBuilderNullStringBuilder() {
349 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((StringBuilder) null, "tmp"));
350 }
351
352 @Test
353 public void testIdentityToStringStrBuilder() {
354 final Integer i = Integer.valueOf(102);
355 final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
356
357 final StrBuilder builder = new StrBuilder();
358 ObjectUtils.identityToString(builder, i);
359 assertEquals(expected, builder.toString());
360
361 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((StrBuilder) null, "tmp"));
362
363 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString(new StrBuilder(), null));
364 }
365
366 @Test
367 public void testIdentityToStringAppendable() throws IOException {
368 final Integer i = Integer.valueOf(121);
369 final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
370
371 final Appendable appendable = new StringBuilder();
372 ObjectUtils.identityToString(appendable, i);
373 assertEquals(expected, appendable.toString());
374
375 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((Appendable) null, "tmp"));
376
377 assertThrows(
378 NullPointerException.class,
379 () -> ObjectUtils.identityToString((Appendable) (new StringBuilder()), null));
380 }
381
382 @Test
383 public void testToString_Object() {
384 assertEquals("", ObjectUtils.toString(null) );
385 assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE) );
386 }
387
388 @Test
389 public void testToString_ObjectString() {
390 assertEquals(BAR, ObjectUtils.toString(null, BAR) );
391 assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE, BAR) );
392 }
393
394 @Test
395 public void testToString_SupplierString() {
396 assertEquals(null, ObjectUtils.toString(null, (Supplier<String>) null));
397 assertEquals(null, ObjectUtils.toString(null, () -> null));
398 // Pretend computing BAR is expensive.
399 assertEquals(BAR, ObjectUtils.toString(null, () -> BAR));
400 assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE, () -> BAR));
401 }
402
403 @SuppressWarnings("cast") // 1 OK, because we are checking for code change
404 @Test
405 public void testNull() {
406 assertNotNull(ObjectUtils.NULL);
407 // 1 Check that NULL really is a Null i.e. the definition has not been changed
408 assertTrue(ObjectUtils.NULL instanceof ObjectUtils.Null);
409 assertSame(ObjectUtils.NULL, SerializationUtils.clone(ObjectUtils.NULL));
410 }
411
412 @Test
413 public void testMax() {
414 final Calendar calendar = Calendar.getInstance();
415 final Date nonNullComparable1 = calendar.getTime();
416 final Date nonNullComparable2 = calendar.getTime();
417 final String[] nullArray = null;
418
419 calendar.set( Calendar.YEAR, calendar.get( Calendar.YEAR ) -1 );
420 final Date minComparable = calendar.getTime();
421
422 assertNotSame( nonNullComparable1, nonNullComparable2 );
423
424 assertNull(ObjectUtils.max( (String) null ) );
425 assertNull(ObjectUtils.max( nullArray ) );
426 assertSame( nonNullComparable1, ObjectUtils.max( null, nonNullComparable1 ) );
427 assertSame( nonNullComparable1, ObjectUtils.max( nonNullComparable1, null ) );
428 assertSame( nonNullComparable1, ObjectUtils.max( null, nonNullComparable1, null ) );
429 assertSame( nonNullComparable1, ObjectUtils.max( nonNullComparable1, nonNullComparable2 ) );
430 assertSame( nonNullComparable2, ObjectUtils.max( nonNullComparable2, nonNullComparable1 ) );
431 assertSame( nonNullComparable1, ObjectUtils.max( nonNullComparable1, minComparable ) );
432 assertSame( nonNullComparable1, ObjectUtils.max( minComparable, nonNullComparable1 ) );
433 assertSame( nonNullComparable1, ObjectUtils.max( null, minComparable, null, nonNullComparable1 ) );
434
435 assertNull( ObjectUtils.max(null, null) );
436 }
437
438 @Test
439 public void testMin() {
440 final Calendar calendar = Calendar.getInstance();
441 final Date nonNullComparable1 = calendar.getTime();
442 final Date nonNullComparable2 = calendar.getTime();
443 final String[] nullArray = null;
444
445 calendar.set( Calendar.YEAR, calendar.get( Calendar.YEAR ) -1 );
446 final Date minComparable = calendar.getTime();
447
448 assertNotSame( nonNullComparable1, nonNullComparable2 );
449
450 assertNull(ObjectUtils.min( (String) null ) );
451 assertNull(ObjectUtils.min( nullArray ) );
452 assertSame( nonNullComparable1, ObjectUtils.min( null, nonNullComparable1 ) );
453 assertSame( nonNullComparable1, ObjectUtils.min( nonNullComparable1, null ) );
454 assertSame( nonNullComparable1, ObjectUtils.min( null, nonNullComparable1, null ) );
455 assertSame( nonNullComparable1, ObjectUtils.min( nonNullComparable1, nonNullComparable2 ) );
456 assertSame( nonNullComparable2, ObjectUtils.min( nonNullComparable2, nonNullComparable1 ) );
457 assertSame( minComparable, ObjectUtils.min( nonNullComparable1, minComparable ) );
458 assertSame( minComparable, ObjectUtils.min( minComparable, nonNullComparable1 ) );
459 assertSame( minComparable, ObjectUtils.min( null, nonNullComparable1, null, minComparable ) );
460
461 assertNull( ObjectUtils.min(null, null) );
462 }
463
464 /**
465 * Tests {@link ObjectUtils#compare(Comparable, Comparable, boolean)}.
466 */
467 @Test
468 public void testCompare() {
469 final Integer one = Integer.valueOf(1);
470 final Integer two = Integer.valueOf(2);
471 final Integer nullValue = null;
472
473 assertEquals(0, ObjectUtils.compare(nullValue, nullValue), "Null Null false");
474 assertEquals(0, ObjectUtils.compare(nullValue, nullValue, true), "Null Null true");
475
476 assertEquals(-1, ObjectUtils.compare(nullValue, one), "Null one false");
477 assertEquals(1, ObjectUtils.compare(nullValue, one, true), "Null one true");
478
479 assertEquals(1, ObjectUtils.compare(one, nullValue), "one Null false");
480 assertEquals(-1, ObjectUtils.compare(one, nullValue, true), "one Null true");
481
482 assertEquals(-1, ObjectUtils.compare(one, two), "one two false");
483 assertEquals(-1, ObjectUtils.compare(one, two, true), "one two true");
484 }
485
486 @Test
487 public void testMedian() {
488 assertEquals("foo", ObjectUtils.median("foo"));
489 assertEquals("bar", ObjectUtils.median("foo", "bar"));
490 assertEquals("baz", ObjectUtils.median("foo", "bar", "baz"));
491 assertEquals("baz", ObjectUtils.median("foo", "bar", "baz", "blah"));
492 assertEquals("blah", ObjectUtils.median("foo", "bar", "baz", "blah", "wah"));
493 assertEquals(Integer.valueOf(5),
494 ObjectUtils.median(Integer.valueOf(1), Integer.valueOf(5), Integer.valueOf(10)));
495 assertEquals(
496 Integer.valueOf(7),
497 ObjectUtils.median(Integer.valueOf(5), Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8),
498 Integer.valueOf(9)));
499 assertEquals(Integer.valueOf(6),
500 ObjectUtils.median(Integer.valueOf(5), Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8)));
501 }
502
503 @Test
504 public void testMedian_nullItems() {
505 assertThrows(NullPointerException.class, () -> ObjectUtils.median((String[]) null));
506 }
507
508 @Test
509 public void testMedian_emptyItems() {
510 assertThrows(IllegalArgumentException.class, ObjectUtils::<String>median);
152 /**
153 * Tests {@link ObjectUtils#allNull(Object...)}.
154 */
155 @Test
156 public void testAllNull() {
157 assertTrue(ObjectUtils.allNull());
158 assertTrue(ObjectUtils.allNull((Object) null));
159 assertTrue(ObjectUtils.allNull((Object[]) null));
160 assertTrue(ObjectUtils.allNull(null, null, null));
161
162 assertFalse(ObjectUtils.allNull(FOO));
163 assertFalse(ObjectUtils.allNull(null, FOO, null));
164 assertFalse(ObjectUtils.allNull(null, null, null, null, FOO, BAR));
165 }
166
167 /**
168 * Tests {@link ObjectUtils#anyNotNull(Object...)}.
169 */
170 @Test
171 public void testAnyNotNull() {
172 assertFalse(ObjectUtils.anyNotNull());
173 assertFalse(ObjectUtils.anyNotNull((Object) null));
174 assertFalse(ObjectUtils.anyNotNull((Object[]) null));
175 assertFalse(ObjectUtils.anyNotNull(null, null, null));
176
177 assertTrue(ObjectUtils.anyNotNull(FOO));
178 assertTrue(ObjectUtils.anyNotNull(null, FOO, null));
179 assertTrue(ObjectUtils.anyNotNull(null, null, null, null, FOO, BAR));
180 }
181
182 /**
183 * Tests {@link ObjectUtils#anyNull(Object...)}.
184 */
185 @Test
186 public void testAnyNull() {
187 assertTrue(ObjectUtils.anyNull((Object) null));
188 assertTrue(ObjectUtils.anyNull(null, null, null));
189 assertTrue(ObjectUtils.anyNull(null, FOO, BAR));
190 assertTrue(ObjectUtils.anyNull(FOO, BAR, null));
191 assertTrue(ObjectUtils.anyNull(FOO, BAR, null, FOO, BAR));
192
193 assertFalse(ObjectUtils.anyNull());
194 assertFalse(ObjectUtils.anyNull(FOO));
195 assertFalse(ObjectUtils.anyNull(FOO, BAR, 1, Boolean.TRUE, new Object(), new Object[]{}));
196 }
197
198 /**
199 * Tests {@link ObjectUtils#clone(Object)} with a cloneable object.
200 */
201 @Test
202 public void testCloneOfCloneable() {
203 final CloneableString string = new CloneableString("apache");
204 final CloneableString stringClone = ObjectUtils.clone(string);
205 assertEquals("apache", stringClone.getValue());
206 }
207
208 /**
209 * Tests {@link ObjectUtils#clone(Object)} with a not cloneable object.
210 */
211 @Test
212 public void testCloneOfNotCloneable() {
213 final String string = "apache";
214 assertNull(ObjectUtils.clone(string));
215 }
216
217 /**
218 * Tests {@link ObjectUtils#clone(Object)} with an array of primitives.
219 */
220 @Test
221 public void testCloneOfPrimitiveArray() {
222 assertArrayEquals(new int[]{1}, ObjectUtils.clone(new int[]{1}));
223 }
224
225 /**
226 * Tests {@link ObjectUtils#clone(Object)} with an object array.
227 */
228 @Test
229 public void testCloneOfStringArray() {
230 assertTrue(Arrays.deepEquals(
231 new String[]{"string"}, ObjectUtils.clone(new String[]{"string"})));
232 }
233
234 /**
235 * Tests {@link ObjectUtils#clone(Object)} with an uncloneable object.
236 */
237 @Test
238 public void testCloneOfUncloneable() {
239 final UncloneableString string = new UncloneableString("apache");
240 final CloneFailedException e = assertThrows(CloneFailedException.class, () -> ObjectUtils.clone(string));
241 assertEquals(NoSuchMethodException.class, e.getCause().getClass());
511242 }
512243
513244 @Test
526257 }
527258
528259 @Test
260 public void testComparatorMedian_emptyItems() {
261 assertThrows(IllegalArgumentException.class, () -> ObjectUtils.median(new CharSequenceComparator()));
262 }
263
264 @Test
529265 public void testComparatorMedian_nullComparator() {
530266 assertThrows(NullPointerException.class,
531267 () -> ObjectUtils.median((Comparator<CharSequence>) null, new NonComparableCharSequence("foo")));
537273 () -> ObjectUtils.median(new CharSequenceComparator(), (CharSequence[]) null));
538274 }
539275
540 @Test
541 public void testComparatorMedian_emptyItems() {
542 assertThrows(IllegalArgumentException.class, () -> ObjectUtils.median(new CharSequenceComparator()));
543 }
544
545 @Test
546 public void testMode() {
547 assertNull(ObjectUtils.mode((Object[]) null));
548 assertNull(ObjectUtils.mode());
549 assertNull(ObjectUtils.mode("foo", "bar", "baz"));
550 assertNull(ObjectUtils.mode("foo", "bar", "baz", "foo", "bar"));
551 assertEquals("foo", ObjectUtils.mode("foo", "bar", "baz", "foo"));
552 assertEquals(Integer.valueOf(9),
553 ObjectUtils.mode("foo", "bar", "baz", Integer.valueOf(9), Integer.valueOf(10), Integer.valueOf(9)));
554 }
555
556 /**
557 * Tests {@link ObjectUtils#clone(Object)} with a cloneable object.
558 */
559 @Test
560 public void testCloneOfCloneable() {
561 final CloneableString string = new CloneableString("apache");
562 final CloneableString stringClone = ObjectUtils.clone(string);
563 assertEquals("apache", stringClone.getValue());
564 }
565
566 /**
567 * Tests {@link ObjectUtils#clone(Object)} with a not cloneable object.
568 */
569 @Test
570 public void testCloneOfNotCloneable() {
571 final String string = new String("apache");
572 assertNull(ObjectUtils.clone(string));
573 }
574
575 /**
576 * Tests {@link ObjectUtils#clone(Object)} with an uncloneable object.
577 */
578 @Test
579 public void testCloneOfUncloneable() {
580 final UncloneableString string = new UncloneableString("apache");
581 final CloneFailedException e = assertThrows(CloneFailedException.class, () -> ObjectUtils.clone(string));
582 assertEquals(NoSuchMethodException.class, e.getCause().getClass());
583 }
584
585 /**
586 * Tests {@link ObjectUtils#clone(Object)} with an object array.
587 */
588 @Test
589 public void testCloneOfStringArray() {
590 assertTrue(Arrays.deepEquals(
591 new String[]{"string"}, ObjectUtils.clone(new String[]{"string"})));
592 }
593
594 /**
595 * Tests {@link ObjectUtils#clone(Object)} with an array of primitives.
596 */
597 @Test
598 public void testCloneOfPrimitiveArray() {
599 assertArrayEquals(new int[]{1}, ObjectUtils.clone(new int[]{1}));
600 }
601
602 /**
603 * Tests {@link ObjectUtils#cloneIfPossible(Object)} with a cloneable object.
604 */
605 @Test
606 public void testPossibleCloneOfCloneable() {
607 final CloneableString string = new CloneableString("apache");
608 final CloneableString stringClone = ObjectUtils.cloneIfPossible(string);
609 assertEquals("apache", stringClone.getValue());
610 }
611
612 /**
613 * Tests {@link ObjectUtils#cloneIfPossible(Object)} with a not cloneable object.
614 */
615 @Test
616 public void testPossibleCloneOfNotCloneable() {
617 final String string = new String("apache");
618 assertSame(string, ObjectUtils.cloneIfPossible(string));
619 }
620
621 /**
622 * Tests {@link ObjectUtils#cloneIfPossible(Object)} with an uncloneable object.
623 */
624 @Test
625 public void testPossibleCloneOfUncloneable() {
626 final UncloneableString string = new UncloneableString("apache");
627 final CloneFailedException e = assertThrows(CloneFailedException.class, () -> ObjectUtils.cloneIfPossible(string));
628 assertEquals(NoSuchMethodException.class, e.getCause().getClass());
276 /**
277 * Tests {@link ObjectUtils#compare(Comparable, Comparable, boolean)}.
278 */
279 @Test
280 public void testCompare() {
281 final Integer one = Integer.valueOf(1);
282 final Integer two = Integer.valueOf(2);
283 final Integer nullValue = null;
284
285 assertEquals(0, ObjectUtils.compare(nullValue, nullValue), "Null Null false");
286 assertEquals(0, ObjectUtils.compare(nullValue, nullValue, true), "Null Null true");
287
288 assertEquals(-1, ObjectUtils.compare(nullValue, one), "Null one false");
289 assertEquals(1, ObjectUtils.compare(nullValue, one, true), "Null one true");
290
291 assertEquals(1, ObjectUtils.compare(one, nullValue), "one Null false");
292 assertEquals(-1, ObjectUtils.compare(one, nullValue, true), "one Null true");
293
294 assertEquals(-1, ObjectUtils.compare(one, two), "one two false");
295 assertEquals(-1, ObjectUtils.compare(one, two, true), "one two true");
629296 }
630297
631298 @Test
695362 "CONST_SHORT(32768): IllegalArgumentException should have been thrown.");
696363 }
697364
698 /**
699 * String that is cloneable.
700 */
701 static final class CloneableString extends MutableObject<String> implements Cloneable {
702 private static final long serialVersionUID = 1L;
703 CloneableString(final String s) {
704 super(s);
705 }
706
707 @Override
708 public CloneableString clone() throws CloneNotSupportedException {
709 return (CloneableString) super.clone();
710 }
711 }
712
713 /**
714 * String that is not cloneable.
715 */
716 static final class UncloneableString extends MutableObject<String> implements Cloneable {
717 private static final long serialVersionUID = 1L;
718 UncloneableString(final String s) {
719 super(s);
720 }
721 }
722
723 static final class NonComparableCharSequence implements CharSequence {
724 final String value;
725
726 /**
727 * Create a new NonComparableCharSequence instance.
728 *
729 * @param value
730 */
731 NonComparableCharSequence(final String value) {
732 super();
733 Validate.notNull(value);
734 this.value = value;
735 }
736
737 @Override
738 public char charAt(final int arg0) {
739 return value.charAt(arg0);
740 }
741
742 @Override
743 public int length() {
744 return value.length();
745 }
746
747 @Override
748 public CharSequence subSequence(final int arg0, final int arg1) {
749 return value.subSequence(arg0, arg1);
750 }
751
752 @Override
753 public String toString() {
754 return value;
755 }
756 }
757
758 static final class CharSequenceComparator implements Comparator<CharSequence> {
759
760 @Override
761 public int compare(final CharSequence o1, final CharSequence o2) {
762 return o1.toString().compareTo(o2.toString());
763 }
764
365 //-----------------------------------------------------------------------
366 @Test
367 public void testConstructor() {
368 assertNotNull(new ObjectUtils());
369 final Constructor<?>[] cons = ObjectUtils.class.getDeclaredConstructors();
370 assertEquals(1, cons.length);
371 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
372 assertTrue(Modifier.isPublic(ObjectUtils.class.getModifiers()));
373 assertFalse(Modifier.isFinal(ObjectUtils.class.getModifiers()));
374 }
375
376 //-----------------------------------------------------------------------
377 @Test
378 public void testDefaultIfNull() {
379 final Object o = FOO;
380 final Object dflt = BAR;
381 assertSame(dflt, ObjectUtils.defaultIfNull(null, dflt), "dflt was not returned when o was null");
382 assertSame(o, ObjectUtils.defaultIfNull(o, dflt), "dflt was returned when o was not null");
383 assertSame(dflt, ObjectUtils.getIfNull(null, () -> dflt), "dflt was not returned when o was null");
384 assertSame(o, ObjectUtils.getIfNull(o, () -> dflt), "dflt was returned when o was not null");
385 assertSame(o, ObjectUtils.getIfNull(FOO, () -> dflt), "dflt was returned when o was not null");
386 assertSame(o, ObjectUtils.getIfNull("foo", () -> dflt), "dflt was returned when o was not null");
387 final MutableInt callsCounter = new MutableInt(0);
388 final Supplier<Object> countingDefaultSupplier = () -> {
389 callsCounter.increment();
390 return dflt;
391 };
392 ObjectUtils.getIfNull(o, countingDefaultSupplier);
393 assertEquals(0, callsCounter.getValue());
394 ObjectUtils.getIfNull(null, countingDefaultSupplier);
395 assertEquals(1, callsCounter.getValue());
396 }
397
398 //-----------------------------------------------------------------------
399 @Test
400 public void testEquals() {
401 assertTrue(ObjectUtils.equals(null, null), "ObjectUtils.equals(null, null) returned false");
402 assertTrue(!ObjectUtils.equals(FOO, null), "ObjectUtils.equals(\"foo\", null) returned true");
403 assertTrue(!ObjectUtils.equals(null, BAR), "ObjectUtils.equals(null, \"bar\") returned true");
404 assertTrue(!ObjectUtils.equals(FOO, BAR), "ObjectUtils.equals(\"foo\", \"bar\") returned true");
405 assertTrue(ObjectUtils.equals(FOO, FOO), "ObjectUtils.equals(\"foo\", \"foo\") returned false");
406 }
407
408 @Test
409 public void testFirstNonNull() {
410 assertEquals("", ObjectUtils.firstNonNull(null, ""));
411 final String firstNonNullGenerics = ObjectUtils.firstNonNull(null, null, "123", "456");
412 assertEquals("123", firstNonNullGenerics);
413 assertEquals("123", ObjectUtils.firstNonNull("123", null, "456", null));
414 assertSame(Boolean.TRUE, ObjectUtils.firstNonNull(Boolean.TRUE));
415
416 // Explicitly pass in an empty array of Object type to ensure compiler doesn't complain of unchecked generic array creation
417 assertNull(ObjectUtils.firstNonNull());
418
419 // Cast to Object in line below ensures compiler doesn't complain of unchecked generic array creation
420 assertNull(ObjectUtils.firstNonNull(null, null));
421
422 assertNull(ObjectUtils.firstNonNull((Object) null));
423 assertNull(ObjectUtils.firstNonNull((Object[]) null));
424 }
425
426 @Test
427 public void testGetFirstNonNull() {
428 // first non null
429 assertEquals("", ObjectUtils.getFirstNonNull(() -> null, () -> ""));
430 // first encountered value is used
431 assertEquals("1", ObjectUtils.getFirstNonNull(() -> null, () -> "1", () -> "2", () -> null));
432 assertEquals("123", ObjectUtils.getFirstNonNull(() -> "123", () -> null, () -> "456"));
433 // don't evaluate suppliers after first value is found
434 assertEquals("123", ObjectUtils.getFirstNonNull(() -> null, () -> "123", () -> fail("Supplier after first non-null value should not be evaluated")));
435 // supplier returning null and null supplier both result in null
436 assertNull(ObjectUtils.getFirstNonNull(null, () -> null));
437 // Explicitly pass in an empty array of Object type to ensure compiler doesn't complain of unchecked generic array creation
438 assertNull(ObjectUtils.getFirstNonNull());
439 // supplier is null
440 assertNull(ObjectUtils.getFirstNonNull((Supplier<Object>) null));
441 // varargs array itself is null
442 assertNull(ObjectUtils.getFirstNonNull((Supplier<Object>[]) null));
443 // test different types
444 assertEquals(1, ObjectUtils.getFirstNonNull(() -> null, () -> 1));
445 assertEquals(Boolean.TRUE, ObjectUtils.getFirstNonNull(() -> null, () -> Boolean.TRUE));
446 }
447
448 @Test
449 public void testHashCode() {
450 assertEquals(0, ObjectUtils.hashCode(null));
451 assertEquals("a".hashCode(), ObjectUtils.hashCode("a"));
452 }
453
454 @Test
455 public void testHashCodeMulti_multiple_emptyArray() {
456 final Object[] array = new Object[0];
457 assertEquals(1, ObjectUtils.hashCodeMulti(array));
458 }
459
460 @Test
461 public void testHashCodeMulti_multiple_likeList() {
462 final List<Object> list0 = new ArrayList<>(Collections.emptyList());
463 assertEquals(list0.hashCode(), ObjectUtils.hashCodeMulti());
464
465 final List<Object> list1 = new ArrayList<>(Collections.singletonList("a"));
466 assertEquals(list1.hashCode(), ObjectUtils.hashCodeMulti("a"));
467
468 final List<Object> list2 = new ArrayList<>(Arrays.asList("a", "b"));
469 assertEquals(list2.hashCode(), ObjectUtils.hashCodeMulti("a", "b"));
470
471 final List<Object> list3 = new ArrayList<>(Arrays.asList("a", "b", "c"));
472 assertEquals(list3.hashCode(), ObjectUtils.hashCodeMulti("a", "b", "c"));
473 }
474
475 @Test
476 public void testHashCodeMulti_multiple_nullArray() {
477 final Object[] array = null;
478 assertEquals(1, ObjectUtils.hashCodeMulti(array));
479 }
480
481 @Test
482 public void testIdentityToStringAppendable() throws IOException {
483 final Integer i = Integer.valueOf(121);
484 final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
485
486 final Appendable appendable = new StringBuilder();
487 ObjectUtils.identityToString(appendable, i);
488 assertEquals(expected, appendable.toString());
489
490 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((Appendable) null, "tmp"));
491
492 assertThrows(
493 NullPointerException.class,
494 () -> ObjectUtils.identityToString((Appendable) (new StringBuilder()), null));
495 }
496
497 @Test
498 public void testIdentityToStringInteger() {
499 final Integer i = Integer.valueOf(90);
500 final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
501
502 assertEquals(expected, ObjectUtils.identityToString(i));
503 }
504
505 @Test
506 public void testIdentityToStringObjectNull() {
507 assertNull(ObjectUtils.identityToString(null));
508 }
509
510 @Test
511 public void testIdentityToStringStrBuilder() {
512 final Integer i = Integer.valueOf(102);
513 final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
514
515 final StrBuilder builder = new StrBuilder();
516 ObjectUtils.identityToString(builder, i);
517 assertEquals(expected, builder.toString());
518
519 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((StrBuilder) null, "tmp"));
520
521 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString(new StrBuilder(), null));
522 }
523
524 @Test
525 public void testIdentityToStringString() {
526 assertEquals(
527 "java.lang.String@" + Integer.toHexString(System.identityHashCode(FOO)),
528 ObjectUtils.identityToString(FOO));
529 }
530
531 @Test
532 public void testIdentityToStringStringBuffer() {
533 final Integer i = Integer.valueOf(45);
534 final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
535
536 final StringBuffer buffer = new StringBuffer();
537 ObjectUtils.identityToString(buffer, i);
538 assertEquals(expected, buffer.toString());
539
540 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((StringBuffer) null, "tmp"));
541 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString(new StringBuffer(), null));
542 }
543
544 @Test
545 public void testIdentityToStringStringBuilder() {
546 final Integer i = Integer.valueOf(90);
547 final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
548
549 final StringBuilder builder = new StringBuilder();
550 ObjectUtils.identityToString(builder, i);
551 assertEquals(expected, builder.toString());
552 }
553
554 @Test
555 public void testIdentityToStringStringBuilderInUse() {
556 final Integer i = Integer.valueOf(90);
557 final String expected = "ABC = java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
558
559 final StringBuilder builder = new StringBuilder("ABC = ");
560 ObjectUtils.identityToString(builder, i);
561 assertEquals(expected, builder.toString());
562 }
563
564 @Test
565 public void testIdentityToStringStringBuilderNullStringBuilder() {
566 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((StringBuilder) null, "tmp"));
567 }
568
569 @Test
570 public void testIdentityToStringStringBuilderNullValue() {
571 assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString(new StringBuilder(), null));
572 }
573
574 //-----------------------------------------------------------------------
575 @Test
576 public void testIsEmpty() {
577 assertTrue(ObjectUtils.isEmpty(null));
578 assertTrue(ObjectUtils.isEmpty(""));
579 assertTrue(ObjectUtils.isEmpty(new int[] {}));
580 assertTrue(ObjectUtils.isEmpty(Collections.emptyList()));
581 assertTrue(ObjectUtils.isEmpty(Collections.emptySet()));
582 assertTrue(ObjectUtils.isEmpty(Collections.emptyMap()));
583
584 assertFalse(ObjectUtils.isEmpty(" "));
585 assertFalse(ObjectUtils.isEmpty("ab"));
586 assertFalse(ObjectUtils.isEmpty(NON_EMPTY_ARRAY));
587 assertFalse(ObjectUtils.isEmpty(NON_EMPTY_LIST));
588 assertFalse(ObjectUtils.isEmpty(NON_EMPTY_SET));
589 assertFalse(ObjectUtils.isEmpty(NON_EMPTY_MAP));
590 }
591
592 @Test
593 public void testIsNotEmpty() {
594 assertFalse(ObjectUtils.isNotEmpty(null));
595 assertFalse(ObjectUtils.isNotEmpty(""));
596 assertFalse(ObjectUtils.isNotEmpty(new int[] {}));
597 assertFalse(ObjectUtils.isNotEmpty(Collections.emptyList()));
598 assertFalse(ObjectUtils.isNotEmpty(Collections.emptySet()));
599 assertFalse(ObjectUtils.isNotEmpty(Collections.emptyMap()));
600
601 assertTrue(ObjectUtils.isNotEmpty(" "));
602 assertTrue(ObjectUtils.isNotEmpty("ab"));
603 assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_ARRAY));
604 assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_LIST));
605 assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_SET));
606 assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_MAP));
607 }
608
609 @Test
610 public void testMax() {
611 final Calendar calendar = Calendar.getInstance();
612 final Date nonNullComparable1 = calendar.getTime();
613 final Date nonNullComparable2 = calendar.getTime();
614 final String[] nullArray = null;
615
616 calendar.set( Calendar.YEAR, calendar.get( Calendar.YEAR ) -1 );
617 final Date minComparable = calendar.getTime();
618
619 assertNotSame( nonNullComparable1, nonNullComparable2 );
620
621 assertNull(ObjectUtils.max( (String) null ) );
622 assertNull(ObjectUtils.max( nullArray ) );
623 assertSame( nonNullComparable1, ObjectUtils.max( null, nonNullComparable1 ) );
624 assertSame( nonNullComparable1, ObjectUtils.max( nonNullComparable1, null ) );
625 assertSame( nonNullComparable1, ObjectUtils.max( null, nonNullComparable1, null ) );
626 assertSame( nonNullComparable1, ObjectUtils.max( nonNullComparable1, nonNullComparable2 ) );
627 assertSame( nonNullComparable2, ObjectUtils.max( nonNullComparable2, nonNullComparable1 ) );
628 assertSame( nonNullComparable1, ObjectUtils.max( nonNullComparable1, minComparable ) );
629 assertSame( nonNullComparable1, ObjectUtils.max( minComparable, nonNullComparable1 ) );
630 assertSame( nonNullComparable1, ObjectUtils.max( null, minComparable, null, nonNullComparable1 ) );
631
632 assertNull( ObjectUtils.max(null, null) );
633 }
634
635 @Test
636 public void testMedian() {
637 assertEquals("foo", ObjectUtils.median("foo"));
638 assertEquals("bar", ObjectUtils.median("foo", "bar"));
639 assertEquals("baz", ObjectUtils.median("foo", "bar", "baz"));
640 assertEquals("baz", ObjectUtils.median("foo", "bar", "baz", "blah"));
641 assertEquals("blah", ObjectUtils.median("foo", "bar", "baz", "blah", "wah"));
642 assertEquals(Integer.valueOf(5),
643 ObjectUtils.median(Integer.valueOf(1), Integer.valueOf(5), Integer.valueOf(10)));
644 assertEquals(
645 Integer.valueOf(7),
646 ObjectUtils.median(Integer.valueOf(5), Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8),
647 Integer.valueOf(9)));
648 assertEquals(Integer.valueOf(6),
649 ObjectUtils.median(Integer.valueOf(5), Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8)));
650 }
651
652 @Test
653 public void testMedian_emptyItems() {
654 assertThrows(IllegalArgumentException.class, ObjectUtils::<String>median);
655 }
656
657 @Test
658 public void testMedian_nullItems() {
659 assertThrows(NullPointerException.class, () -> ObjectUtils.median((String[]) null));
660 }
661
662 @Test
663 public void testMin() {
664 final Calendar calendar = Calendar.getInstance();
665 final Date nonNullComparable1 = calendar.getTime();
666 final Date nonNullComparable2 = calendar.getTime();
667 final String[] nullArray = null;
668
669 calendar.set( Calendar.YEAR, calendar.get( Calendar.YEAR ) -1 );
670 final Date minComparable = calendar.getTime();
671
672 assertNotSame( nonNullComparable1, nonNullComparable2 );
673
674 assertNull(ObjectUtils.min( (String) null ) );
675 assertNull(ObjectUtils.min( nullArray ) );
676 assertSame( nonNullComparable1, ObjectUtils.min( null, nonNullComparable1 ) );
677 assertSame( nonNullComparable1, ObjectUtils.min( nonNullComparable1, null ) );
678 assertSame( nonNullComparable1, ObjectUtils.min( null, nonNullComparable1, null ) );
679 assertSame( nonNullComparable1, ObjectUtils.min( nonNullComparable1, nonNullComparable2 ) );
680 assertSame( nonNullComparable2, ObjectUtils.min( nonNullComparable2, nonNullComparable1 ) );
681 assertSame( minComparable, ObjectUtils.min( nonNullComparable1, minComparable ) );
682 assertSame( minComparable, ObjectUtils.min( minComparable, nonNullComparable1 ) );
683 assertSame( minComparable, ObjectUtils.min( null, nonNullComparable1, null, minComparable ) );
684
685 assertNull( ObjectUtils.min(null, null) );
686 }
687
688 @Test
689 public void testMode() {
690 assertNull(ObjectUtils.mode((Object[]) null));
691 assertNull(ObjectUtils.mode());
692 assertNull(ObjectUtils.mode("foo", "bar", "baz"));
693 assertNull(ObjectUtils.mode("foo", "bar", "baz", "foo", "bar"));
694 assertEquals("foo", ObjectUtils.mode("foo", "bar", "baz", "foo"));
695 assertEquals(Integer.valueOf(9),
696 ObjectUtils.mode("foo", "bar", "baz", Integer.valueOf(9), Integer.valueOf(10), Integer.valueOf(9)));
697 }
698
699 @Test
700 public void testNotEqual() {
701 assertFalse(ObjectUtils.notEqual(null, null), "ObjectUtils.notEqual(null, null) returned false");
702 assertTrue(ObjectUtils.notEqual(FOO, null), "ObjectUtils.notEqual(\"foo\", null) returned true");
703 assertTrue(ObjectUtils.notEqual(null, BAR), "ObjectUtils.notEqual(null, \"bar\") returned true");
704 assertTrue(ObjectUtils.notEqual(FOO, BAR), "ObjectUtils.notEqual(\"foo\", \"bar\") returned true");
705 assertFalse(ObjectUtils.notEqual(FOO, FOO), "ObjectUtils.notEqual(\"foo\", \"foo\") returned false");
706 }
707
708 @SuppressWarnings("cast") // 1 OK, because we are checking for code change
709 @Test
710 public void testNull() {
711 assertNotNull(ObjectUtils.NULL);
712 // 1 Check that NULL really is a Null i.e. the definition has not been changed
713 assertTrue(ObjectUtils.NULL instanceof ObjectUtils.Null);
714 assertSame(ObjectUtils.NULL, SerializationUtils.clone(ObjectUtils.NULL));
715 }
716
717 /**
718 * Tests {@link ObjectUtils#cloneIfPossible(Object)} with a cloneable object.
719 */
720 @Test
721 public void testPossibleCloneOfCloneable() {
722 final CloneableString string = new CloneableString("apache");
723 final CloneableString stringClone = ObjectUtils.cloneIfPossible(string);
724 assertEquals("apache", stringClone.getValue());
725 }
726
727 /**
728 * Tests {@link ObjectUtils#cloneIfPossible(Object)} with a not cloneable object.
729 */
730 @Test
731 public void testPossibleCloneOfNotCloneable() {
732 final String string = "apache";
733 assertSame(string, ObjectUtils.cloneIfPossible(string));
734 }
735
736 /**
737 * Tests {@link ObjectUtils#cloneIfPossible(Object)} with an uncloneable object.
738 */
739 @Test
740 public void testPossibleCloneOfUncloneable() {
741 final UncloneableString string = new UncloneableString("apache");
742 final CloneFailedException e = assertThrows(CloneFailedException.class,
743 () -> ObjectUtils.cloneIfPossible(string));
744 assertEquals(NoSuchMethodException.class, e.getCause().getClass());
745 }
746
747 @Test
748 public void testRequireNonEmpty() {
749 assertEquals("foo", ObjectUtils.requireNonEmpty("foo"));
750 assertEquals("foo", ObjectUtils.requireNonEmpty("foo", "foo"));
751 //
752 assertThrows(NullPointerException.class, () -> ObjectUtils.requireNonEmpty(null));
753 assertThrows(NullPointerException.class, () -> ObjectUtils.requireNonEmpty(null, "foo"));
754 //
755 assertThrows(IllegalArgumentException.class, () -> ObjectUtils.requireNonEmpty(""));
756 assertThrows(IllegalArgumentException.class, () -> ObjectUtils.requireNonEmpty("", "foo"));
757 }
758
759 @Test
760 public void testToString_Object() {
761 assertEquals("", ObjectUtils.toString(null) );
762 assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE) );
763 }
764
765 @Test
766 public void testToString_ObjectString() {
767 assertEquals(BAR, ObjectUtils.toString(null, BAR) );
768 assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE, BAR) );
769 }
770
771 @Test
772 public void testToString_SupplierString() {
773 assertEquals(null, ObjectUtils.toString(null, (Supplier<String>) null));
774 assertEquals(null, ObjectUtils.toString(null, () -> null));
775 // Pretend computing BAR is expensive.
776 assertEquals(BAR, ObjectUtils.toString(null, () -> BAR));
777 assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE, () -> BAR));
778 }
779
780 @Test
781 public void testWaitDuration() {
782 assertThrows(IllegalMonitorStateException.class, () -> ObjectUtils.wait(new Object(), Duration.ZERO));
765783 }
766784
767785 }
141141 assertEquals(50, r2.length(), "random(50) length");
142142 assertTrue(!r1.equals(r2), "!r1.equals(r2)");
143143
144 final long seed = System.currentTimeMillis();
145 r1 = RandomStringUtils.random(50, 0, 0, true, true, null, new Random(seed));
146 r2 = RandomStringUtils.random(50, 0, 0, true, true, null, new Random(seed));
144 final long seedMillis = System.currentTimeMillis();
145 r1 = RandomStringUtils.random(50, 0, 0, true, true, null, new Random(seedMillis));
146 r2 = RandomStringUtils.random(50, 0, 0, true, true, null, new Random(seedMillis));
147147 assertEquals(r1, r2, "r1.equals(r2)");
148148
149149 r1 = RandomStringUtils.random(0);
152152
153153 @Test
154154 public void testLANG805() {
155 final long seed = System.currentTimeMillis();
156 assertEquals("aaa", RandomStringUtils.random(3, 0, 0, false, false, new char[]{'a'}, new Random(seed)));
155 final long seedMillis = System.currentTimeMillis();
156 assertEquals("aaa", RandomStringUtils.random(3, 0, 0, false, false, new char[]{'a'}, new Random(seedMillis)));
157157 }
158158
159159 @Test
1818 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
1919 import static org.junit.jupiter.api.Assertions.assertEquals;
2020 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertNotEquals;
2122 import static org.junit.jupiter.api.Assertions.assertNotNull;
2223 import static org.junit.jupiter.api.Assertions.assertThrows;
2324 import static org.junit.jupiter.api.Assertions.assertTrue;
261262 final double result = RandomUtils.nextDouble(0, Double.MAX_VALUE);
262263 assertTrue(result >= 0 && result <= Double.MAX_VALUE);
263264 }
265
266 /**
267 * Test a large value for long. A previous implementation using
268 * {@link RandomUtils#nextDouble(double, double)} could generate a value equal
269 * to the upper limit.
270 *
271 * <pre>
272 * return (long) nextDouble(startInclusive, endExclusive);
273 * </pre>
274 *
275 * <p>See LANG-1592.</p>
276 */
277 @Test
278 public void testLargeValueRangeLong() {
279 final long startInclusive = 12900000000001L;
280 final long endExclusive = 12900000000016L;
281 // Note: The method using 'return (long) nextDouble(startInclusive, endExclusive)'
282 // takes thousands of calls to generate an error. This size loop fails most
283 // of the time with the previous method.
284 final int n = (int) (endExclusive - startInclusive) * 1000;
285 for (int i = 0; i < n; i++) {
286 assertNotEquals(endExclusive, RandomUtils.nextLong(startInclusive, endExclusive));
287 }
288 }
264289 }
9090 }
9191
9292 // -----------------------------------------------------------------------
93 @SuppressWarnings({ "rawtypes", "unchecked" })
93 @SuppressWarnings({"rawtypes", "unchecked"})
9494 @Test
9595 public void testComparableConstructors() {
9696 final Comparable c = other -> 1;
144144
145145 protected <T extends Throwable> FailablePredicate<Integer, T> asIntPredicate(final T pThrowable) {
146146 return i -> {
147 if (i.intValue() == 5) {
148 if (pThrowable != null) {
149 throw pThrowable;
150 }
147 if (i.intValue() == 5 && pThrowable != null) {
148 throw pThrowable;
151149 }
152150 return i%2==0;
153151 };
172172 assertTrue(StringUtils.containsAny("zzabyycdxx", "by"));
173173 assertTrue(StringUtils.containsAny("zzabyycdxx", "zy"));
174174 assertFalse(StringUtils.containsAny("ab", "z"));
175 }
176
177 /**
178 * See http://www.oracle.com/technetwork/articles/javase/supplementary-142654.html
179 */
180 @Test
181 public void testContainsAny_StringWithBadSupplementaryChars() {
182 // Test edge case: 1/2 of a (broken) supplementary char
183 assertFalse(StringUtils.containsAny(CharUSuppCharHigh, CharU20001));
184 assertEquals(-1, CharUSuppCharLow.indexOf(CharU20001));
185 assertFalse(StringUtils.containsAny(CharUSuppCharLow, CharU20001));
186 assertFalse(StringUtils.containsAny(CharU20001, CharUSuppCharHigh));
187 assertEquals(0, CharU20001.indexOf(CharUSuppCharLow));
188 assertTrue(StringUtils.containsAny(CharU20001, CharUSuppCharLow));
189 }
190
191 /**
192 * See http://www.oracle.com/technetwork/articles/javase/supplementary-142654.html
193 */
194 @Test
195 public void testContainsAny_StringWithSupplementaryChars() {
196 assertTrue(StringUtils.containsAny(CharU20000 + CharU20001, CharU20000));
197 assertTrue(StringUtils.containsAny(CharU20000 + CharU20001, CharU20001));
198 assertTrue(StringUtils.containsAny(CharU20000, CharU20000));
199 // Sanity check:
200 assertEquals(-1, CharU20000.indexOf(CharU20001));
201 assertEquals(0, CharU20000.indexOf(CharU20001.charAt(0)));
202 assertEquals(-1, CharU20000.indexOf(CharU20001.charAt(1)));
203 // Test:
204 assertFalse(StringUtils.containsAny(CharU20000, CharU20001));
205 assertFalse(StringUtils.containsAny(CharU20001, CharU20000));
206175 }
207176
208177 @Test
224193 assertTrue(StringUtils.containsAny("abcd", "ab", null));
225194 assertTrue(StringUtils.containsAny("abcd", "ab", "cd"));
226195 assertTrue(StringUtils.containsAny("abc", "d", "abc"));
196 }
197
198 @Test
199 public void testContainsAnyIgnoreCase_StringStringArray() {
200 assertFalse(StringUtils.containsAnyIgnoreCase(null, (String[]) null));
201 assertFalse(StringUtils.containsAnyIgnoreCase(null, new String[0]));
202 assertFalse(StringUtils.containsAnyIgnoreCase(null, new String[] { "hello" }));
203 assertFalse(StringUtils.containsAnyIgnoreCase("", (String[]) null));
204 assertFalse(StringUtils.containsAnyIgnoreCase("", new String[0]));
205 assertFalse(StringUtils.containsAnyIgnoreCase("", new String[] { "hello" }));
206 assertFalse(StringUtils.containsAnyIgnoreCase("hello, goodbye", (String[]) null));
207 assertFalse(StringUtils.containsAnyIgnoreCase("hello, goodbye", new String[0]));
208 assertTrue(StringUtils.containsAnyIgnoreCase("hello, goodbye", new String[]{"hello", "goodbye"}));
209 assertTrue(StringUtils.containsAnyIgnoreCase("hello, goodbye", new String[]{"hello", "Goodbye"}));
210 assertTrue(StringUtils.containsAnyIgnoreCase("hello, goodbye", new String[]{"Hello", "Goodbye"}));
211 assertTrue(StringUtils.containsAnyIgnoreCase("hello, goodbye", new String[]{"Hello", null}));
212 assertTrue(StringUtils.containsAnyIgnoreCase("hello, null", new String[] { "Hello", null }));
213 // Javadoc examples:
214 assertTrue(StringUtils.containsAnyIgnoreCase("abcd", "ab", null));
215 assertTrue(StringUtils.containsAnyIgnoreCase("abcd", "ab", "cd"));
216 assertTrue(StringUtils.containsAnyIgnoreCase("abc", "d", "abc"));
217 }
218
219 /**
220 * See http://www.oracle.com/technetwork/articles/javase/supplementary-142654.html
221 */
222 @Test
223 public void testContainsAny_StringWithBadSupplementaryChars() {
224 // Test edge case: 1/2 of a (broken) supplementary char
225 assertFalse(StringUtils.containsAny(CharUSuppCharHigh, CharU20001));
226 assertEquals(-1, CharUSuppCharLow.indexOf(CharU20001));
227 assertFalse(StringUtils.containsAny(CharUSuppCharLow, CharU20001));
228 assertFalse(StringUtils.containsAny(CharU20001, CharUSuppCharHigh));
229 assertEquals(0, CharU20001.indexOf(CharUSuppCharLow));
230 assertTrue(StringUtils.containsAny(CharU20001, CharUSuppCharLow));
231 }
232
233 /**
234 * See http://www.oracle.com/technetwork/articles/javase/supplementary-142654.html
235 */
236 @Test
237 public void testContainsAny_StringWithSupplementaryChars() {
238 assertTrue(StringUtils.containsAny(CharU20000 + CharU20001, CharU20000));
239 assertTrue(StringUtils.containsAny(CharU20000 + CharU20001, CharU20001));
240 assertTrue(StringUtils.containsAny(CharU20000, CharU20000));
241 // Sanity check:
242 assertEquals(-1, CharU20000.indexOf(CharU20001));
243 assertEquals(0, CharU20000.indexOf(CharU20001.charAt(0)));
244 assertEquals(-1, CharU20000.indexOf(CharU20001.charAt(1)));
245 // Test:
246 assertFalse(StringUtils.containsAny(CharU20000, CharU20001));
247 assertFalse(StringUtils.containsAny(CharU20001, CharU20000));
227248 }
228249
229250 @DefaultLocale(language = "de", country = "DE")
2020 import static org.junit.jupiter.api.Assertions.assertFalse;
2121 import static org.junit.jupiter.api.Assertions.assertTrue;
2222
23 import java.nio.CharBuffer;
2324 import java.util.Locale;
2425
2526 import org.hamcrest.core.IsNot;
274275 assertEquals(2, StringUtils.indexOf("aabaabaa", 'b'));
275276
276277 assertEquals(2, StringUtils.indexOf(new StringBuilder("aabaabaa"), 'b'));
278 assertEquals(StringUtils.INDEX_NOT_FOUND, StringUtils.indexOf(new StringBuilder("aabaabaa"), -1738));
277279 }
278280
279281 @Test
563565 assertEquals(1, StringUtils.lastIndexOf(builder, CODE_POINT, 1 ));
564566 assertEquals(-1, StringUtils.lastIndexOf(builder.toString(), CODE_POINT, 0));
565567 assertEquals(1, StringUtils.lastIndexOf(builder.toString(), CODE_POINT, 1));
568 assertEquals(StringUtils.INDEX_NOT_FOUND, StringUtils.lastIndexOf(CharBuffer.wrap("[%{.c.0rro"), -1738, 982));
566569 }
567570
568571 @Test
126126 assertEquals(FOO, StringUtils.mid(FOOBAR, -1, 3));
127127 }
128128
129 //-----------------------------------------------------------------------
129 @Test
130 public void testSubstringBefore_StringInt() {
131 assertEquals("foo", StringUtils.substringBefore("fooXXbarXXbaz", 'X'));
132
133 assertNull(StringUtils.substringBefore(null, 0));
134 assertNull(StringUtils.substringBefore(null, 'X'));
135 assertEquals("", StringUtils.substringBefore("", 0));
136 assertEquals("", StringUtils.substringBefore("", 'X'));
137
138 assertEquals("foo", StringUtils.substringBefore("foo", 0));
139 assertEquals("foo", StringUtils.substringBefore("foo", 'b'));
140 assertEquals("f", StringUtils.substringBefore("foot", 'o'));
141 assertEquals("", StringUtils.substringBefore("abc", 'a'));
142 assertEquals("a", StringUtils.substringBefore("abcba", 'b'));
143 assertEquals("ab", StringUtils.substringBefore("abc", 'c'));
144 assertEquals("abc", StringUtils.substringBefore("abc", 0));
145 }
146
130147 @Test
131148 public void testSubstringBefore_StringString() {
132149 assertEquals("foo", StringUtils.substringBefore("fooXXbarXXbaz", "XX"));
145162 assertEquals("a", StringUtils.substringBefore("abcba", "b"));
146163 assertEquals("ab", StringUtils.substringBefore("abc", "c"));
147164 assertEquals("", StringUtils.substringBefore("abc", ""));
165 assertEquals("abc", StringUtils.substringBefore("abc", "X"));
148166 }
149167
150168 @Test
348366 StringUtils.countMatches("one long someone sentence of one", "two"));
349367 assertEquals(4,
350368 StringUtils.countMatches("oooooooooooo", "ooo"));
369 assertEquals(0, StringUtils.countMatches(null, "?"));
370 assertEquals(0, StringUtils.countMatches("", "?"));
371 assertEquals(0, StringUtils.countMatches("abba", null));
372 assertEquals(0, StringUtils.countMatches("abba", ""));
373 assertEquals(2, StringUtils.countMatches("abba", "a"));
374 assertEquals(1, StringUtils.countMatches("abba", "ab"));
375 assertEquals(0, StringUtils.countMatches("abba", "xxx"));
376 assertEquals(1, StringUtils.countMatches("ababa", "aba"));
351377 }
352378
353379 @Test
4444 import org.apache.commons.lang3.mutable.MutableInt;
4545 import org.apache.commons.lang3.text.WordUtils;
4646 import org.junit.jupiter.api.Test;
47 import org.junit.jupiter.api.Disabled;
4748
4849 /**
4950 * Unit tests for methods of {@link org.apache.commons.lang3.StringUtils}
112113
113114 private static final String SEPARATOR = ",";
114115 private static final char SEPARATOR_CHAR = ';';
116 private static final char COMMA_SEPARATOR_CHAR = ',';
115117
116118 private static final String TEXT_LIST = "foo,bar,baz";
117119 private static final String TEXT_LIST_CHAR = "foo;bar;baz";
122124
123125 private static final String SENTENCE_UNCAP = "foo bar baz";
124126 private static final String SENTENCE_CAP = "Foo Bar Baz";
127
128 private static final boolean[] EMPTY = {};
129 private static final boolean[] ARRAY_FALSE_FALSE = {false, false};
130 private static final boolean[] ARRAY_FALSE_TRUE = {false, true};
131 private static final boolean[] ARRAY_FALSE_TRUE_FALSE = {false, true, false};
125132
126133 private void assertAbbreviateWithAbbrevMarkerAndOffset(final String expected, final String abbrevMarker, final int offset, final int maxWidth) {
127134 final String abcdefghijklmno = "abcdefghijklmno";
11531160 assertEquals(StringUtils.EMPTY, StringUtils.join(BYTE_PRIM_LIST, SEPARATOR_CHAR, 1, 0));
11541161 }
11551162
1163
1164 @Test
1165 public void testJoin_ArrayOfBooleans() {
1166 assertNull(StringUtils.join((boolean[]) null, COMMA_SEPARATOR_CHAR));
1167 assertEquals("false;false", StringUtils.join(ARRAY_FALSE_FALSE, SEPARATOR_CHAR));
1168 assertEquals("", StringUtils.join(EMPTY, SEPARATOR_CHAR));
1169 assertEquals("false,true,false", StringUtils.join(ARRAY_FALSE_TRUE_FALSE, COMMA_SEPARATOR_CHAR));
1170 assertEquals("true", StringUtils.join(ARRAY_FALSE_TRUE, SEPARATOR_CHAR, 1, 2));
1171 assertNull(StringUtils.join((boolean[]) null, SEPARATOR_CHAR, 0, 1));
1172 assertEquals(StringUtils.EMPTY, StringUtils.join(ARRAY_FALSE_FALSE, SEPARATOR_CHAR, 0, 0));
1173 assertEquals(StringUtils.EMPTY, StringUtils.join(ARRAY_FALSE_TRUE_FALSE, SEPARATOR_CHAR, 1, 0));
1174 }
1175
11561176 @Test
11571177 public void testJoin_ArrayOfChars() {
11581178 assertNull(StringUtils.join((char[]) null, ','));
13381358 assertEquals("a", StringUtils.join(null, "a", ""));
13391359 assertEquals("foo", StringUtils.join(MIXED_ARRAY_LIST));
13401360 assertEquals("foo2", StringUtils.join(MIXED_TYPE_LIST));
1361 }
1362
1363 @Disabled
1364 @Test
1365 public void testLang1593() {
1366 final int[] arr = new int[] {1, 2, 3, 4, 5, 6, 7};
1367 final String expected = StringUtils.join(arr, '-');
1368 final String actual = StringUtils.join(arr, "-");
1369 assertEquals(expected, actual);
13411370 }
13421371
13431372 //-----------------------------------------------------------------------
31633192 assertEquals("abc", StringUtils.unwrap("abc", null));
31643193 assertEquals("abc", StringUtils.unwrap("abc", ""));
31653194 assertEquals("a", StringUtils.unwrap("a", "a"));
3195 assertEquals("ababa", StringUtils.unwrap("ababa", "aba"));
31663196 assertEquals("", StringUtils.unwrap("aa", "a"));
31673197 assertEquals("abc", StringUtils.unwrap("\'abc\'", "\'"));
31683198 assertEquals("abc", StringUtils.unwrap("\"abc\"", "\""));
2828
2929 import java.lang.reflect.Constructor;
3030 import java.lang.reflect.Modifier;
31 import java.time.Duration;
3132 import java.util.Arrays;
3233 import java.util.List;
3334 import java.util.concurrent.CountDownLatch;
3940 */
4041 public class ThreadUtilsTest {
4142
42 @Test
43 public void testNullThreadName() {
44 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName(null));
45 }
46
47 @Test
48 public void testNullThreadGroupName() {
49 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadGroupsByName(null));
50 }
51
52 @Test
53 public void testNullThreadThreadGroupName1() {
54 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName(null, "tgname"));
55 }
56
57 @Test
58 public void testNullThreadThreadGroupName2() {
59 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName("tname", (String) null));
60 }
61
62 @Test
63 public void testNullThreadThreadGroupName3() {
64 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName(null, (String) null));
65 }
66
67 @Test
68 public void testNullThreadThreadGroup1() {
69 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName("tname", (ThreadGroup) null));
70 }
71
72 @Test
73 public void testNullThreadThreadGroup2() {
74 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadById(1L, (ThreadGroup) null));
75 }
76
77 @Test
78 public void testNullThreadThreadGroup3() {
79 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName(null, (ThreadGroup) null));
80 }
81
82 @Test
83 public void testInvalidThreadId() {
84 assertThrows(IllegalArgumentException.class, () -> ThreadUtils.findThreadById(-5L));
85 }
86
87 @Test
88 public void testThreadGroupsByIdFail() {
89 assertThrows(NullPointerException.class,
90 () -> ThreadUtils.findThreadById(Thread.currentThread().getId(), (String) null));
91 }
92
93 @Test
94 public void testThreadgroupsNullParent() {
95 assertThrows(NullPointerException.class,
96 () -> ThreadUtils.findThreadGroups(null, true, ThreadUtils.ALWAYS_TRUE_PREDICATE));
97 }
98
99 @Test
100 public void testThreadgroupsNullPredicate() {
101 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadGroups(null));
102 }
103
104 @Test
105 public void testThreadsNullPredicate() {
106 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreads(null));
107 }
108
109 @Test
110 public void testNoThread() {
111 assertEquals(0, ThreadUtils.findThreadsByName("some_thread_which_does_not_exist_18762ZucTT").size());
112 }
113
114 @Test
115 public void testNoThreadGroup() {
116 assertEquals(0, ThreadUtils.findThreadGroupsByName("some_thread_group_which_does_not_exist_18762ZucTTII").size());
117 }
118
119 @Test
120 public void testSystemThreadGroupExists() {
121 final ThreadGroup systemThreadGroup = ThreadUtils.getSystemThreadGroup();
122 assertNotNull(systemThreadGroup);
123 assertNull(systemThreadGroup.getParent());
124 assertEquals("system", systemThreadGroup.getName());
43 private static class TestThread extends Thread {
44 private final CountDownLatch latch = new CountDownLatch(1);
45
46 TestThread(final String name) {
47 super(name);
48 }
49
50 TestThread(final ThreadGroup group, final String name) {
51 super(group, name);
52 }
53
54 @Override
55 public void run() {
56 latch.countDown();
57 try {
58 synchronized(this) {
59 this.wait();
60 }
61 } catch (final InterruptedException e) {
62 Thread.currentThread().interrupt();
63 }
64 }
65
66 @Override
67 public synchronized void start() {
68 super.start();
69 try {
70 latch.await();
71 } catch (final InterruptedException e) {
72 Thread.currentThread().interrupt();
73 }
74 }
12575 }
12676
12777 @Test
12878 public void testAtLeastOneThreadExists() {
129 assertTrue(ThreadUtils.getAllThreads().size() > 0);
79 assertFalse(ThreadUtils.getAllThreads().isEmpty());
13080 }
13181
13282 @Test
13383 public void testAtLeastOneThreadGroupsExists() {
134 assertTrue(ThreadUtils.getAllThreadGroups().size() > 0);
135 }
136
137 @Test
138 public void testThreadsSameName() throws InterruptedException {
139 final Thread t1 = new TestThread("thread1_XXOOLL__");
140 final Thread alsot1 = new TestThread("thread1_XXOOLL__");
141
142 try {
143 t1.start();
144 alsot1.start();
145 assertEquals(2, ThreadUtils.findThreadsByName("thread1_XXOOLL__").size());
146 } finally {
147 t1.interrupt();
148 alsot1.interrupt();
149 t1.join();
150 alsot1.join();
151 }
152 }
153
154 @Test
155 public void testThreads() throws InterruptedException {
156 final Thread t1 = new TestThread("thread1_XXOOLL__");
157 final Thread t2 = new TestThread("thread2_XXOOLL__");
158
159 try {
160 t1.start();
161 t2.start();
162 assertEquals(1, ThreadUtils.findThreadsByName("thread2_XXOOLL__").size());
163 } finally {
164 t1.interrupt();
165 t2.interrupt();
166 t1.join();
167 t2.join();
168 }
169 }
170
171 @Test
172 public void testThreadsById() throws InterruptedException {
173 final Thread t1 = new TestThread("thread1_XXOOLL__");
174 final Thread t2 = new TestThread("thread2_XXOOLL__");
175
176 try {
177 t1.start();
178 t2.start();
179 assertSame(t1, ThreadUtils.findThreadById(t1.getId()));
180 assertSame(t2, ThreadUtils.findThreadById(t2.getId()));
181 } finally {
182 t1.interrupt();
183 t2.interrupt();
184 t1.join();
185 t2.join();
186 }
187 }
188
189 @Test
190 public void testThreadsByIdWrongGroup() throws InterruptedException {
191 final Thread t1 = new TestThread("thread1_XXOOLL__");
192 final ThreadGroup tg = new ThreadGroup("tg__HHEE22");
193
194 try {
195 t1.start();
196 assertNull(ThreadUtils.findThreadById(t1.getId(), tg));
197 } finally {
198 t1.interrupt();
199 t1.join();
200 tg.destroy();
201 }
202 }
203
204
205 @Test
206 public void testThreadGroups() throws InterruptedException {
207 final ThreadGroup threadGroup = new ThreadGroup("thread_group_DDZZ99__");
208 final Thread t1 = new TestThread(threadGroup, "thread1_XXOOPP__");
209 final Thread t2 = new TestThread(threadGroup, "thread2_XXOOPP__");
210
211 try {
212 t1.start();
213 t2.start();
214 assertEquals(1, ThreadUtils.findThreadsByName("thread1_XXOOPP__").size());
215 assertEquals(1, ThreadUtils.findThreadsByName("thread1_XXOOPP__", "thread_group_DDZZ99__").size());
216 assertEquals(1, ThreadUtils.findThreadsByName("thread2_XXOOPP__", "thread_group_DDZZ99__").size());
217 assertEquals(0, ThreadUtils.findThreadsByName("thread1_XXOOPP__", "non_existent_thread_group_JJHHZZ__").size());
218 assertEquals(0, ThreadUtils.findThreadsByName("non_existent_thread_BBDDWW__", "thread_group_DDZZ99__").size());
219 assertEquals(1, ThreadUtils.findThreadGroupsByName("thread_group_DDZZ99__").size());
220 assertEquals(0, ThreadUtils.findThreadGroupsByName("non_existent_thread_group_JJHHZZ__").size());
221 assertNotNull(ThreadUtils.findThreadById(t1.getId(), threadGroup));
222 } finally {
223 t1.interrupt();
224 t2.interrupt();
225 t1.join();
226 t2.join();
227 threadGroup.destroy();
228 }
229 }
230
231 @Test
232 public void testThreadGroupsRef() throws InterruptedException {
233 final ThreadGroup threadGroup = new ThreadGroup("thread_group_DDZZ99__");
234 final ThreadGroup deadThreadGroup = new ThreadGroup("dead_thread_group_MMQQSS__");
235 deadThreadGroup.destroy();
236 final Thread t1 = new TestThread(threadGroup, "thread1_XXOOPP__");
237 final Thread t2 = new TestThread(threadGroup, "thread2_XXOOPP__");
238
239 try {
240 t1.start();
241 t2.start();
242 assertEquals(1, ThreadUtils.findThreadsByName("thread1_XXOOPP__").size());
243 assertEquals(1, ThreadUtils.findThreadsByName("thread1_XXOOPP__", threadGroup).size());
244 assertEquals(1, ThreadUtils.findThreadsByName("thread2_XXOOPP__", threadGroup).size());
245 assertEquals(0, ThreadUtils.findThreadsByName("thread1_XXOOPP__", deadThreadGroup).size());
246 } finally {
247 t1.interrupt();
248 t2.interrupt();
249 t1.join();
250 t2.join();
251 threadGroup.destroy();
252 assertEquals(0, ThreadUtils.findThreadsByName("thread2_XXOOPP__", threadGroup).size());
253 }
254 }
255
256 @Test
257 public void testThreadGroupsById() throws InterruptedException {
258 final ThreadGroup threadGroup = new ThreadGroup("thread_group_DDZZ99__");
259 final Thread t1 = new TestThread(threadGroup, "thread1_XXOOPP__");
260 final Thread t2 = new TestThread(threadGroup, "thread2_XXOOPP__");
261 final long nonExistingId = t1.getId()+t2.getId();
262
263 try {
264 t1.start();
265 t2.start();
266 assertSame(t1, ThreadUtils.findThreadById(t1.getId(), "thread_group_DDZZ99__"));
267 assertSame(t2, ThreadUtils.findThreadById(t2.getId(), "thread_group_DDZZ99__"));
268 assertNull(ThreadUtils.findThreadById(nonExistingId, "non_existent_thread_group_JJHHZZ__"));
269 assertNull(ThreadUtils.findThreadById(nonExistingId, "thread_group_DDZZ99__"));
270 } finally {
271 t1.interrupt();
272 t2.interrupt();
273 t1.join();
274 t2.join();
275 threadGroup.destroy();
276 }
277 }
278
279 @Test
280 public void testConstructor() {
281 assertNotNull(new ThreadUtils());
282 final Constructor<?>[] cons = ThreadUtils.class.getDeclaredConstructors();
283 assertEquals(1, cons.length);
284 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
285 assertTrue(Modifier.isPublic(ThreadUtils.class.getModifiers()));
286 assertFalse(Modifier.isFinal(ThreadUtils.class.getModifiers()));
84 assertFalse(ThreadUtils.getAllThreadGroups().isEmpty());
28785 }
28886
28987 @Test
335133 }
336134 }
337135
338
339 private static class TestThread extends Thread {
340 private final CountDownLatch latch = new CountDownLatch(1);
341
342 TestThread(final String name) {
343 super(name);
344 }
345
346 TestThread(final ThreadGroup group, final String name) {
347 super(group, name);
348 }
349
350 @Override
351 public synchronized void start() {
352 super.start();
353 try {
354 latch.await();
355 } catch (final InterruptedException e) {
356 Thread.currentThread().interrupt();
357 }
358 }
359
360 @Override
361 public void run() {
362 latch.countDown();
363 try {
364 synchronized(this) {
365 this.wait();
366 }
367 } catch (final InterruptedException e) {
368 Thread.currentThread().interrupt();
369 }
136 @Test
137 public void testConstructor() {
138 assertNotNull(new ThreadUtils());
139 final Constructor<?>[] cons = ThreadUtils.class.getDeclaredConstructors();
140 assertEquals(1, cons.length);
141 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
142 assertTrue(Modifier.isPublic(ThreadUtils.class.getModifiers()));
143 assertFalse(Modifier.isFinal(ThreadUtils.class.getModifiers()));
144 }
145
146 @Test
147 public void testInvalidThreadId() {
148 assertThrows(IllegalArgumentException.class, () -> ThreadUtils.findThreadById(-5L));
149 }
150
151 @Test
152 public void testJoinDuration() throws InterruptedException {
153 ThreadUtils.join(new Thread(), Duration.ZERO);
154 ThreadUtils.join(new Thread(), Duration.ofMillis(1));
155 }
156
157 @Test
158 public void testNoThread() {
159 assertEquals(0, ThreadUtils.findThreadsByName("some_thread_which_does_not_exist_18762ZucTT").size());
160 }
161
162 @Test
163 public void testNoThreadGroup() {
164 assertEquals(0, ThreadUtils.findThreadGroupsByName("some_thread_group_which_does_not_exist_18762ZucTTII").size());
165 }
166
167 @Test
168 public void testNullThreadGroupName() {
169 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadGroupsByName(null));
170 }
171
172 @Test
173 public void testNullThreadName() {
174 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName(null));
175 }
176
177 @Test
178 public void testNullThreadThreadGroup1() {
179 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName("tname", (ThreadGroup) null));
180 }
181
182 @Test
183 public void testNullThreadThreadGroup2() {
184 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadById(1L, (ThreadGroup) null));
185 }
186
187 @Test
188 public void testNullThreadThreadGroup3() {
189 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName(null, (ThreadGroup) null));
190 }
191
192 @Test
193 public void testNullThreadThreadGroupName1() {
194 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName(null, "tgname"));
195 }
196
197 @Test
198 public void testNullThreadThreadGroupName2() {
199 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName("tname", (String) null));
200 }
201
202 @Test
203 public void testNullThreadThreadGroupName3() {
204 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadsByName(null, (String) null));
205 }
206
207 @Test
208 public void testSleepDuration() throws InterruptedException {
209 ThreadUtils.sleep(Duration.ZERO);
210 ThreadUtils.sleep(Duration.ofMillis(1));
211 }
212
213 @Test
214 public void testSystemThreadGroupExists() {
215 final ThreadGroup systemThreadGroup = ThreadUtils.getSystemThreadGroup();
216 assertNotNull(systemThreadGroup);
217 assertNull(systemThreadGroup.getParent());
218 assertEquals("system", systemThreadGroup.getName());
219 }
220
221 @Test
222 public void testThreadGroups() throws InterruptedException {
223 final ThreadGroup threadGroup = new ThreadGroup("thread_group_DDZZ99__");
224 final Thread t1 = new TestThread(threadGroup, "thread1_XXOOPP__");
225 final Thread t2 = new TestThread(threadGroup, "thread2_XXOOPP__");
226
227 try {
228 t1.start();
229 t2.start();
230 assertEquals(1, ThreadUtils.findThreadsByName("thread1_XXOOPP__").size());
231 assertEquals(1, ThreadUtils.findThreadsByName("thread1_XXOOPP__", "thread_group_DDZZ99__").size());
232 assertEquals(1, ThreadUtils.findThreadsByName("thread2_XXOOPP__", "thread_group_DDZZ99__").size());
233 assertEquals(0, ThreadUtils.findThreadsByName("thread1_XXOOPP__", "non_existent_thread_group_JJHHZZ__").size());
234 assertEquals(0, ThreadUtils.findThreadsByName("non_existent_thread_BBDDWW__", "thread_group_DDZZ99__").size());
235 assertEquals(1, ThreadUtils.findThreadGroupsByName("thread_group_DDZZ99__").size());
236 assertEquals(0, ThreadUtils.findThreadGroupsByName("non_existent_thread_group_JJHHZZ__").size());
237 assertNotNull(ThreadUtils.findThreadById(t1.getId(), threadGroup));
238 } finally {
239 t1.interrupt();
240 t2.interrupt();
241 t1.join();
242 t2.join();
243 threadGroup.destroy();
244 }
245 }
246
247 @Test
248 public void testThreadGroupsById() throws InterruptedException {
249 final ThreadGroup threadGroup = new ThreadGroup("thread_group_DDZZ99__");
250 final Thread t1 = new TestThread(threadGroup, "thread1_XXOOPP__");
251 final Thread t2 = new TestThread(threadGroup, "thread2_XXOOPP__");
252 final long nonExistingId = t1.getId()+t2.getId();
253
254 try {
255 t1.start();
256 t2.start();
257 assertSame(t1, ThreadUtils.findThreadById(t1.getId(), "thread_group_DDZZ99__"));
258 assertSame(t2, ThreadUtils.findThreadById(t2.getId(), "thread_group_DDZZ99__"));
259 assertNull(ThreadUtils.findThreadById(nonExistingId, "non_existent_thread_group_JJHHZZ__"));
260 assertNull(ThreadUtils.findThreadById(nonExistingId, "thread_group_DDZZ99__"));
261 } finally {
262 t1.interrupt();
263 t2.interrupt();
264 t1.join();
265 t2.join();
266 threadGroup.destroy();
267 }
268 }
269
270 @Test
271 public void testThreadGroupsByIdFail() {
272 assertThrows(NullPointerException.class,
273 () -> ThreadUtils.findThreadById(Thread.currentThread().getId(), (String) null));
274 }
275
276
277 @Test
278 public void testThreadgroupsNullParent() {
279 assertThrows(NullPointerException.class,
280 () -> ThreadUtils.findThreadGroups(null, true, ThreadUtils.ALWAYS_TRUE_PREDICATE));
281 }
282
283 @Test
284 public void testThreadgroupsNullPredicate() {
285 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreadGroups(null));
286 }
287
288 @Test
289 public void testThreadGroupsRef() throws InterruptedException {
290 final ThreadGroup threadGroup = new ThreadGroup("thread_group_DDZZ99__");
291 final ThreadGroup deadThreadGroup = new ThreadGroup("dead_thread_group_MMQQSS__");
292 deadThreadGroup.destroy();
293 final Thread t1 = new TestThread(threadGroup, "thread1_XXOOPP__");
294 final Thread t2 = new TestThread(threadGroup, "thread2_XXOOPP__");
295
296 try {
297 t1.start();
298 t2.start();
299 assertEquals(1, ThreadUtils.findThreadsByName("thread1_XXOOPP__").size());
300 assertEquals(1, ThreadUtils.findThreadsByName("thread1_XXOOPP__", threadGroup).size());
301 assertEquals(1, ThreadUtils.findThreadsByName("thread2_XXOOPP__", threadGroup).size());
302 assertEquals(0, ThreadUtils.findThreadsByName("thread1_XXOOPP__", deadThreadGroup).size());
303 } finally {
304 t1.interrupt();
305 t2.interrupt();
306 t1.join();
307 t2.join();
308 threadGroup.destroy();
309 assertEquals(0, ThreadUtils.findThreadsByName("thread2_XXOOPP__", threadGroup).size());
310 }
311 }
312
313 @Test
314 public void testThreads() throws InterruptedException {
315 final Thread t1 = new TestThread("thread1_XXOOLL__");
316 final Thread t2 = new TestThread("thread2_XXOOLL__");
317
318 try {
319 t1.start();
320 t2.start();
321 assertEquals(1, ThreadUtils.findThreadsByName("thread2_XXOOLL__").size());
322 } finally {
323 t1.interrupt();
324 t2.interrupt();
325 t1.join();
326 t2.join();
327 }
328 }
329
330 @Test
331 public void testThreadsById() throws InterruptedException {
332 final Thread t1 = new TestThread("thread1_XXOOLL__");
333 final Thread t2 = new TestThread("thread2_XXOOLL__");
334
335 try {
336 t1.start();
337 t2.start();
338 assertSame(t1, ThreadUtils.findThreadById(t1.getId()));
339 assertSame(t2, ThreadUtils.findThreadById(t2.getId()));
340 } finally {
341 t1.interrupt();
342 t2.interrupt();
343 t1.join();
344 t2.join();
345 }
346 }
347
348
349 @Test
350 public void testThreadsByIdWrongGroup() throws InterruptedException {
351 final Thread t1 = new TestThread("thread1_XXOOLL__");
352 final ThreadGroup tg = new ThreadGroup("tg__HHEE22");
353
354 try {
355 t1.start();
356 assertNull(ThreadUtils.findThreadById(t1.getId(), tg));
357 } finally {
358 t1.interrupt();
359 t1.join();
360 tg.destroy();
361 }
362 }
363
364 @Test
365 public void testThreadsNullPredicate() {
366 assertThrows(NullPointerException.class, () -> ThreadUtils.findThreads(null));
367 }
368
369 @Test
370 public void testThreadsSameName() throws InterruptedException {
371 final Thread t1 = new TestThread("thread1_XXOOLL__");
372 final Thread alsot1 = new TestThread("thread1_XXOOLL__");
373
374 try {
375 t1.start();
376 alsot1.start();
377 assertEquals(2, ThreadUtils.findThreadsByName("thread1_XXOOLL__").size());
378 } finally {
379 t1.interrupt();
380 alsot1.interrupt();
381 t1.join();
382 alsot1.join();
370383 }
371384 }
372385 }
8989
9090 static class TestTransientSubObject extends TestObject {
9191 @SuppressWarnings("unused")
92 private transient int t;
92 private final transient int t;
9393 TestTransientSubObject(final int a, final int t) {
9494 super(a);
9595 this.t = t;
1717
1818 import static org.junit.jupiter.api.Assertions.assertEquals;
1919
20 import java.util.ArrayList;
21 import java.util.HashMap;
20 import java.util.Arrays;
21 import java.util.Collections;
2222
2323 import org.apache.commons.lang3.builder.ToStringStyleTest.Person;
2424 import org.junit.jupiter.api.AfterEach;
7070 assertEquals(baseStr + "[a=3]", new ToStringBuilder(base).append("a", i3).toString());
7171 assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", i3).append("b", i4).toString());
7272 assertEquals(baseStr + "[a=<Integer>]", new ToStringBuilder(base).append("a", i3, false).toString());
73 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", new ArrayList<>(), false).toString());
74 assertEquals(baseStr + "[a=[]]", new ToStringBuilder(base).append("a", new ArrayList<>(), true).toString());
75 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", new HashMap<>(), false).toString());
76 assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", new HashMap<>(), true).toString());
77 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", (Object) new String[0], false).toString());
78 assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", (Object) new String[0], true).toString());
73 }
74
75 @Test
76 public void testCollection() {
77 final Integer i3 = Integer.valueOf(3);
78 final Integer i4 = Integer.valueOf(4);
79 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", Collections.emptyList(), false).toString());
80 assertEquals(baseStr + "[a=[]]", new ToStringBuilder(base).append("a", Collections.emptyList(), true).toString());
81 assertEquals(baseStr + "[a=<size=1>]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), false).toString());
82 assertEquals(baseStr + "[a=[3]]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), true).toString());
83 assertEquals(baseStr + "[a=<size=2>]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), false).toString());
84 assertEquals(baseStr + "[a=[3, 4]]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), true).toString());
85 }
86
87 @Test
88 public void testMap() {
89 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", Collections.emptyMap(), false).toString());
90 assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", Collections.emptyMap(), true).toString());
91 assertEquals(baseStr + "[a=<size=1>]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), false).toString());
92 assertEquals(baseStr + "[a={k=v}]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), true).toString());
93 }
94
95 @Test
96 public void testArray() {
97 final Integer i3 = Integer.valueOf(3);
98 final Integer i4 = Integer.valueOf(4);
99 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", (Object) new Integer[0], false).toString());
100 assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", (Object) new Integer[0], true).toString());
101 assertEquals(baseStr + "[a=<size=1>]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, false).toString());
102 assertEquals(baseStr + "[a={3}]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, true).toString());
103 assertEquals(baseStr + "[a=<size=2>]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, false).toString());
104 assertEquals(baseStr + "[a={3,4}]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, true).toString());
79105 }
80106
81107 @Test
124124
125125 static class TestTSubObject extends TestObject {
126126 @SuppressWarnings("unused")
127 private transient int t;
127 private final transient int t;
128128
129129 TestTSubObject(final int a, final int t) {
130130 super(a);
134134
135135 static class TestTTSubObject extends TestTSubObject {
136136 @SuppressWarnings("unused")
137 private transient int tt;
137 private final transient int tt;
138138
139139 TestTTSubObject(final int a, final int t, final int tt) {
140140 super(a, t);
598598 }
599599
600600 /**
601 * An object with nested object structures used to test {@link ToStringStyle.JsonToStringStyle}.
602 *
601 * An object with nested object structures used to test {@code ToStringStyle.JsonToStringStyle}.
603602 */
604603 static class NestingPerson {
605604 /**
683682 }
684683
685684 /**
686 * An object with a Map field used to test {@link ToStringStyle.JsonToStringStyle}.
687 *
685 * An object with a Map field used to test {@code ToStringStyle.JsonToStringStyle}.
688686 */
689687 static class InnerMapObject {
690688 /**
1717
1818 import static org.junit.jupiter.api.Assertions.assertEquals;
1919
20 import java.util.ArrayList;
21 import java.util.HashMap;
20 import java.util.Arrays;
21 import java.util.Collections;
2222
2323 import org.apache.commons.lang3.builder.ToStringStyleTest.Person;
2424 import org.junit.jupiter.api.AfterEach;
7070 assertEquals(baseStr + "[" + System.lineSeparator() + " a=3" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", i3).toString());
7171 assertEquals(baseStr + "[" + System.lineSeparator() + " a=3" + System.lineSeparator() + " b=4" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", i3).append("b", i4).toString());
7272 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<Integer>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", i3, false).toString());
73 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<size=0>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", new ArrayList<>(), false).toString());
74 assertEquals(baseStr + "[" + System.lineSeparator() + " a=[]" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", new ArrayList<>(), true).toString());
75 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<size=0>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", new HashMap<>(), false).toString());
76 assertEquals(baseStr + "[" + System.lineSeparator() + " a={}" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", new HashMap<>(), true).toString());
77 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<size=0>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", (Object) new String[0], false).toString());
78 assertEquals(baseStr + "[" + System.lineSeparator() + " a={}" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", (Object) new String[0], true).toString());
73 }
74
75 @Test
76 public void testCollection() {
77 final Integer i3 = Integer.valueOf(3);
78 final Integer i4 = Integer.valueOf(4);
79 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<size=0>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", Collections.emptyList(), false).toString());
80 assertEquals(baseStr + "[" + System.lineSeparator() + " a=[]" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", Collections.emptyList(), true).toString());
81 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<size=1>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), false).toString());
82 assertEquals(baseStr + "[" + System.lineSeparator() + " a=[3]" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), true).toString());
83 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<size=2>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), false).toString());
84 assertEquals(baseStr + "[" + System.lineSeparator() + " a=[3, 4]" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), true).toString());
85 }
86
87 @Test
88 public void testMap() {
89 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<size=0>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", Collections.emptyMap(), false).toString());
90 assertEquals(baseStr + "[" + System.lineSeparator() + " a={}" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", Collections.emptyMap(), true).toString());
91 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<size=1>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), false).toString());
92 assertEquals(baseStr + "[" + System.lineSeparator() + " a={k=v}" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), true).toString());
93 }
94
95 @Test
96 public void testArray() {
97 final Integer i3 = Integer.valueOf(3);
98 final Integer i4 = Integer.valueOf(4);
99 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<size=0>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", (Object) new Integer[0], false).toString());
100 assertEquals(baseStr + "[" + System.lineSeparator() + " a={}" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", (Object) new Integer[0], true).toString());
101 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<size=1>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, false).toString());
102 assertEquals(baseStr + "[" + System.lineSeparator() + " a={3}" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, true).toString());
103 assertEquals(baseStr + "[" + System.lineSeparator() + " a=<size=2>" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, false).toString());
104 assertEquals(baseStr + "[" + System.lineSeparator() + " a={3,4}" + System.lineSeparator() + "]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, true).toString());
79105 }
80106
81107 @Test
1717
1818 import static org.junit.jupiter.api.Assertions.assertEquals;
1919
20 import java.util.ArrayList;
21 import java.util.HashMap;
20 import java.util.Arrays;
21 import java.util.Collections;
2222
2323 import org.apache.commons.lang3.builder.ToStringStyleTest.Person;
2424 import org.junit.jupiter.api.AfterEach;
6969 assertEquals("[a=3]", new ToStringBuilder(base).append("a", i3).toString());
7070 assertEquals("[a=3,b=4]", new ToStringBuilder(base).append("a", i3).append("b", i4).toString());
7171 assertEquals("[a=<Integer>]", new ToStringBuilder(base).append("a", i3, false).toString());
72 assertEquals("[a=<size=0>]", new ToStringBuilder(base).append("a", new ArrayList<>(), false).toString());
73 assertEquals("[a=[]]", new ToStringBuilder(base).append("a", new ArrayList<>(), true).toString());
74 assertEquals("[a=<size=0>]", new ToStringBuilder(base).append("a", new HashMap<>(), false).toString());
75 assertEquals("[a={}]", new ToStringBuilder(base).append("a", new HashMap<>(), true).toString());
76 assertEquals("[a=<size=0>]", new ToStringBuilder(base).append("a", (Object) new String[0], false).toString());
77 assertEquals("[a={}]", new ToStringBuilder(base).append("a", (Object) new String[0], true).toString());
72 }
73
74 @Test
75 public void testCollection() {
76 final Integer i3 = Integer.valueOf(3);
77 final Integer i4 = Integer.valueOf(4);
78 assertEquals("[a=<size=0>]", new ToStringBuilder(base).append("a", Collections.emptyList(), false).toString());
79 assertEquals("[a=[]]", new ToStringBuilder(base).append("a", Collections.emptyList(), true).toString());
80 assertEquals("[a=<size=1>]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), false).toString());
81 assertEquals("[a=[3]]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), true).toString());
82 assertEquals("[a=<size=2>]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), false).toString());
83 assertEquals("[a=[3, 4]]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), true).toString());
84 }
85
86 @Test
87 public void testMap() {
88 assertEquals("[a=<size=0>]", new ToStringBuilder(base).append("a", Collections.emptyMap(), false).toString());
89 assertEquals("[a={}]", new ToStringBuilder(base).append("a", Collections.emptyMap(), true).toString());
90 assertEquals("[a=<size=1>]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), false).toString());
91 assertEquals("[a={k=v}]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), true).toString());
92 }
93
94 @Test
95 public void testArray() {
96 final Integer i3 = Integer.valueOf(3);
97 final Integer i4 = Integer.valueOf(4);
98 assertEquals("[a=<size=0>]", new ToStringBuilder(base).append("a", (Object) new Integer[0], false).toString());
99 assertEquals("[a={}]", new ToStringBuilder(base).append("a", (Object) new Integer[0], true).toString());
100 assertEquals("[a=<size=1>]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, false).toString());
101 assertEquals("[a={3}]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, true).toString());
102 assertEquals("[a=<size=2>]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, false).toString());
103 assertEquals("[a={3,4}]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, true).toString());
78104 }
79105
80106 @Test
1717
1818 import static org.junit.jupiter.api.Assertions.assertEquals;
1919
20 import java.util.ArrayList;
21 import java.util.HashMap;
20 import java.util.Arrays;
21 import java.util.Collections;
2222
2323 import org.apache.commons.lang3.builder.ToStringStyleTest.Person;
2424 import org.junit.jupiter.api.AfterEach;
7070 assertEquals(baseStr + "[3]", new ToStringBuilder(base).append("a", i3).toString());
7171 assertEquals(baseStr + "[3,4]", new ToStringBuilder(base).append("a", i3).append("b", i4).toString());
7272 assertEquals(baseStr + "[<Integer>]", new ToStringBuilder(base).append("a", i3, false).toString());
73 assertEquals(baseStr + "[<size=0>]", new ToStringBuilder(base).append("a", new ArrayList<>(), false).toString());
74 assertEquals(baseStr + "[[]]", new ToStringBuilder(base).append("a", new ArrayList<>(), true).toString());
75 assertEquals(baseStr + "[<size=0>]", new ToStringBuilder(base).append("a", new HashMap<>(), false).toString());
76 assertEquals(baseStr + "[{}]", new ToStringBuilder(base).append("a", new HashMap<>(), true).toString());
77 assertEquals(baseStr + "[<size=0>]", new ToStringBuilder(base).append("a", (Object) new String[0], false).toString());
78 assertEquals(baseStr + "[{}]", new ToStringBuilder(base).append("a", (Object) new String[0], true).toString());
73 }
74
75 @Test
76 public void testCollection() {
77 final Integer i3 = Integer.valueOf(3);
78 final Integer i4 = Integer.valueOf(4);
79 assertEquals(baseStr + "[<size=0>]", new ToStringBuilder(base).append("a", Collections.emptyList(), false).toString());
80 assertEquals(baseStr + "[[]]", new ToStringBuilder(base).append("a", Collections.emptyList(), true).toString());
81 assertEquals(baseStr + "[<size=1>]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), false).toString());
82 assertEquals(baseStr + "[[3]]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), true).toString());
83 assertEquals(baseStr + "[<size=2>]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), false).toString());
84 assertEquals(baseStr + "[[3, 4]]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), true).toString());
85 }
86
87 @Test
88 public void testMap() {
89 assertEquals(baseStr + "[<size=0>]", new ToStringBuilder(base).append("a", Collections.emptyMap(), false).toString());
90 assertEquals(baseStr + "[{}]", new ToStringBuilder(base).append("a", Collections.emptyMap(), true).toString());
91 assertEquals(baseStr + "[<size=1>]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), false).toString());
92 assertEquals(baseStr + "[{k=v}]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), true).toString());
93 }
94
95 @Test
96 public void testArray() {
97 final Integer i3 = Integer.valueOf(3);
98 final Integer i4 = Integer.valueOf(4);
99 assertEquals(baseStr + "[<size=0>]", new ToStringBuilder(base).append("a", (Object) new Integer[0], false).toString());
100 assertEquals(baseStr + "[{}]", new ToStringBuilder(base).append("a", (Object) new Integer[0], true).toString());
101 assertEquals(baseStr + "[<size=1>]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, false).toString());
102 assertEquals(baseStr + "[{3}]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, true).toString());
103 assertEquals(baseStr + "[<size=2>]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, false).toString());
104 assertEquals(baseStr + "[{3,4}]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, true).toString());
79105 }
80106
81107 @Test
1717
1818 import static org.junit.jupiter.api.Assertions.assertEquals;
1919
20 import java.util.ArrayList;
21 import java.util.HashMap;
20 import java.util.Arrays;
21 import java.util.Collections;
2222
2323 import org.apache.commons.lang3.builder.ToStringStyleTest.Person;
2424 import org.junit.jupiter.api.AfterEach;
7070 assertEquals(baseStr + "[a=3]", new ToStringBuilder(base).append("a", i3).toString());
7171 assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", i3).append("b", i4).toString());
7272 assertEquals(baseStr + "[a=<Integer>]", new ToStringBuilder(base).append("a", i3, false).toString());
73 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", new ArrayList<>(), false).toString());
74 assertEquals(baseStr + "[a=[]]", new ToStringBuilder(base).append("a", new ArrayList<>(), true).toString());
75 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", new HashMap<>(), false).toString());
76 assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", new HashMap<>(), true).toString());
77 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", (Object) new String[0], false).toString());
78 assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", (Object) new String[0], true).toString());
73 }
74
75 @Test
76 public void testCollection() {
77 final Integer i3 = Integer.valueOf(3);
78 final Integer i4 = Integer.valueOf(4);
79 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", Collections.emptyList(), false).toString());
80 assertEquals(baseStr + "[a=[]]", new ToStringBuilder(base).append("a", Collections.emptyList(), true).toString());
81 assertEquals(baseStr + "[a=<size=1>]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), false).toString());
82 assertEquals(baseStr + "[a=[3]]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), true).toString());
83 assertEquals(baseStr + "[a=<size=2>]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), false).toString());
84 assertEquals(baseStr + "[a=[3, 4]]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), true).toString());
85 }
86
87 @Test
88 public void testMap() {
89 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", Collections.emptyMap(), false).toString());
90 assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", Collections.emptyMap(), true).toString());
91 assertEquals(baseStr + "[a=<size=1>]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), false).toString());
92 assertEquals(baseStr + "[a={k=v}]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), true).toString());
93 }
94
95 @Test
96 public void testArray() {
97 final Integer i3 = Integer.valueOf(3);
98 final Integer i4 = Integer.valueOf(4);
99 assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", (Object) new Integer[0], false).toString());
100 assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", (Object) new Integer[0], true).toString());
101 assertEquals(baseStr + "[a=<size=1>]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, false).toString());
102 assertEquals(baseStr + "[a={3}]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, true).toString());
103 assertEquals(baseStr + "[a=<size=2>]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, false).toString());
104 assertEquals(baseStr + "[a={3,4}]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, true).toString());
79105 }
80106
81107 @Test
1717
1818 import static org.junit.jupiter.api.Assertions.assertEquals;
1919
20 import java.util.ArrayList;
21 import java.util.HashMap;
20 import java.util.Arrays;
21 import java.util.Collections;
2222
2323 import org.apache.commons.lang3.builder.ToStringStyleTest.Person;
2424 import org.junit.jupiter.api.AfterEach;
6969 assertEquals("3", new ToStringBuilder(base).append("a", i3).toString());
7070 assertEquals("3,4", new ToStringBuilder(base).append("a", i3).append("b", i4).toString());
7171 assertEquals("<Integer>", new ToStringBuilder(base).append("a", i3, false).toString());
72 assertEquals("<size=0>", new ToStringBuilder(base).append("a", new ArrayList<>(), false).toString());
73 assertEquals("[]", new ToStringBuilder(base).append("a", new ArrayList<>(), true).toString());
74 assertEquals("<size=0>", new ToStringBuilder(base).append("a", new HashMap<>(), false).toString());
75 assertEquals("{}", new ToStringBuilder(base).append("a", new HashMap<>(), true).toString());
76 assertEquals("<size=0>", new ToStringBuilder(base).append("a", (Object) new String[0], false).toString());
77 assertEquals("{}", new ToStringBuilder(base).append("a", (Object) new String[0], true).toString());
72 }
73
74 @Test
75 public void testCollection() {
76 final Integer i3 = Integer.valueOf(3);
77 final Integer i4 = Integer.valueOf(4);
78 assertEquals("<size=0>", new ToStringBuilder(base).append("a", Collections.emptyList(), false).toString());
79 assertEquals("[]", new ToStringBuilder(base).append("a", Collections.emptyList(), true).toString());
80 assertEquals("<size=1>", new ToStringBuilder(base).append("a", Collections.singletonList(i3), false).toString());
81 assertEquals("[3]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), true).toString());
82 assertEquals("<size=2>", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), false).toString());
83 assertEquals("[3, 4]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), true).toString());
84 }
85
86 @Test
87 public void testMap() {
88 assertEquals("<size=0>", new ToStringBuilder(base).append("a", Collections.emptyMap(), false).toString());
89 assertEquals("{}", new ToStringBuilder(base).append("a", Collections.emptyMap(), true).toString());
90 assertEquals("<size=1>", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), false).toString());
91 assertEquals("{k=v}", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), true).toString());
92 }
93
94 @Test
95 public void testArray() {
96 final Integer i3 = Integer.valueOf(3);
97 final Integer i4 = Integer.valueOf(4);
98 assertEquals("<size=0>", new ToStringBuilder(base).append("a", (Object) new Integer[0], false).toString());
99 assertEquals("{}", new ToStringBuilder(base).append("a", (Object) new Integer[0], true).toString());
100 assertEquals("<size=1>", new ToStringBuilder(base).append("a", (Object) new Integer[]{i3}, false).toString());
101 assertEquals("{3}", new ToStringBuilder(base).append("a", (Object) new Integer[]{i3}, true).toString());
102 assertEquals("<size=2>", new ToStringBuilder(base).append("a", (Object) new Integer[]{i3, i4}, false).toString());
103 assertEquals("{3,4}", new ToStringBuilder(base).append("a", (Object) new Integer[]{i3, i4}, true).toString());
78104 }
79105
80106 @Test
1919 import static org.junit.jupiter.api.Assertions.assertFalse;
2020 import static org.junit.jupiter.api.Assertions.assertTrue;
2121
22 import java.util.ArrayList;
23 import java.util.HashMap;
22 import java.util.Arrays;
23 import java.util.Collections;
2424
2525 import org.apache.commons.lang3.builder.ToStringStyleTest.Person;
2626 import org.junit.jupiter.api.AfterEach;
8787 assertEquals(baseStr + "[a=3]", new ToStringBuilder(base).append("a", i3).toString());
8888 assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", i3).append("b", i4).toString());
8989 assertEquals(baseStr + "[a=%Integer%]", new ToStringBuilder(base).append("a", i3, false).toString());
90 assertEquals(baseStr + "[a=%SIZE=0%]", new ToStringBuilder(base).append("a", new ArrayList<>(), false).toString());
91 assertEquals(baseStr + "[a=[]]", new ToStringBuilder(base).append("a", new ArrayList<>(), true).toString());
92 assertEquals(baseStr + "[a=%SIZE=0%]", new ToStringBuilder(base).append("a", new HashMap<>(), false).toString());
93 assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", new HashMap<>(), true).toString());
94 assertEquals(baseStr + "[a=%SIZE=0%]", new ToStringBuilder(base).append("a", (Object) new String[0], false).toString());
95 assertEquals(baseStr + "[a=[]]", new ToStringBuilder(base).append("a", (Object) new String[0], true).toString());
90 }
91
92 @Test
93 public void testCollection() {
94 final Integer i3 = Integer.valueOf(3);
95 final Integer i4 = Integer.valueOf(4);
96 assertEquals(baseStr + "[a=%SIZE=0%]", new ToStringBuilder(base).append("a", Collections.emptyList(), false).toString());
97 assertEquals(baseStr + "[a=[]]", new ToStringBuilder(base).append("a", Collections.emptyList(), true).toString());
98 assertEquals(baseStr + "[a=%SIZE=1%]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), false).toString());
99 assertEquals(baseStr + "[a=[3]]", new ToStringBuilder(base).append("a", Collections.singletonList(i3), true).toString());
100 assertEquals(baseStr + "[a=%SIZE=2%]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), false).toString());
101 assertEquals(baseStr + "[a=[3, 4]]", new ToStringBuilder(base).append("a", Arrays.asList(i3, i4), true).toString());
102 }
103
104 @Test
105 public void testMap() {
106 assertEquals(baseStr + "[a=%SIZE=0%]", new ToStringBuilder(base).append("a", Collections.emptyMap(), false).toString());
107 assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", Collections.emptyMap(), true).toString());
108 assertEquals(baseStr + "[a=%SIZE=1%]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), false).toString());
109 assertEquals(baseStr + "[a={k=v}]", new ToStringBuilder(base).append("a", Collections.singletonMap("k", "v"), true).toString());
110 }
111
112 @Test
113 public void testArray() {
114 final Integer i3 = Integer.valueOf(3);
115 final Integer i4 = Integer.valueOf(4);
116 assertEquals(baseStr + "[a=%SIZE=0%]", new ToStringBuilder(base).append("a", (Object) new Integer[0], false).toString());
117 assertEquals(baseStr + "[a=[]]", new ToStringBuilder(base).append("a", (Object) new Integer[0], true).toString());
118 assertEquals(baseStr + "[a=%SIZE=1%]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, false).toString());
119 assertEquals(baseStr + "[a=[3]]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3}, true).toString());
120 assertEquals(baseStr + "[a=%SIZE=2%]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, false).toString());
121 assertEquals(baseStr + "[a=[3, 4]]", new ToStringBuilder(base).append("a", (Object) new Integer[] {i3, i4}, true).toString());
96122 }
97123
98124 @Test
356356 @SuppressWarnings("unused")
357357 private final char a='a';
358358 @SuppressWarnings("unused")
359 private transient char transientA='t';
359 private final transient char transientA='t';
360360 }
361361
362362 static class ReflectionTestFixtureB extends ReflectionTestFixtureA {
363363 @SuppressWarnings("unused")
364364 private final char b='b';
365365 @SuppressWarnings("unused")
366 private transient char transientB='t';
366 private final transient char transientB='t';
367367 }
368368
369369 @Test
893893 assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", 3L).append("b", 4L).toString());
894894 }
895895
896 @SuppressWarnings("cast") // cast is not really needed, keep for consistency
897896 @Test
898897 public void testInt() {
899898 assertEquals(baseStr + "[3]", new ToStringBuilder(base).append(3).toString());
922921 assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", (byte) 3).append("b", (byte) 4).toString());
923922 }
924923
925 @SuppressWarnings("cast")
926924 @Test
927925 public void testDouble() {
928926 assertEquals(baseStr + "[3.2]", new ToStringBuilder(base).append(3.2).toString());
2323 import static org.junit.jupiter.api.Assertions.assertThrows;
2424 import static org.junit.jupiter.api.Assertions.assertTrue;
2525
26 import java.time.Duration;
2627 import java.util.concurrent.CountDownLatch;
2728 import java.util.concurrent.ExecutorService;
2829 import java.util.concurrent.Executors;
2930 import java.util.concurrent.TimeUnit;
3031 import java.util.concurrent.atomic.AtomicReference;
3132
33 import org.apache.commons.lang3.ThreadUtils;
3234 import org.junit.jupiter.api.Test;
3335
3436 public class BackgroundInitializerTest {
279281 volatile int initializeCalls;
280282
281283 BackgroundInitializerTestImpl() {
282 super();
283284 }
284285
285286 BackgroundInitializerTestImpl(final ExecutorService exec) {
298299 throw ex;
299300 }
300301 if (shouldSleep) {
301 Thread.sleep(60000L);
302 ThreadUtils.sleep(Duration.ofMinutes(1));
302303 }
303304 return Integer.valueOf(++initializeCalls);
304305 }
9595 public void testNow() {
9696 final EventCountCircuitBreaker breaker = new EventCountCircuitBreaker(OPENING_THRESHOLD, 1,
9797 TimeUnit.SECONDS);
98 final long now = breaker.now();
99 final long delta = Math.abs(System.nanoTime() - now);
100 assertTrue(delta < 100000, String.format("Delta %d ns to current time too large", delta));
98 final long nowNanos = breaker.nanoTime();
99 final long deltaNanos = Math.abs(System.nanoTime() - nowNanos);
100 assertTrue(deltaNanos < 100_000, String.format("Delta %,d ns to current time too large", deltaNanos));
101101 }
102102
103103 /**
363363 * method.
364364 */
365365 @Override
366 long now() {
366 long nanoTime() {
367367 return currentTime;
368368 }
369369 }
1919 import static org.junit.jupiter.api.Assertions.assertNotSame;
2020 import static org.junit.jupiter.api.Assertions.assertTrue;
2121
22 import java.time.Duration;
2223 import java.util.function.LongConsumer;
2324
25 import org.apache.commons.lang3.ArrayUtils;
26 import org.apache.commons.lang3.ThreadUtils;
2427 import org.apache.commons.lang3.concurrent.locks.LockingVisitors.LockVisitor;
2528 import org.apache.commons.lang3.concurrent.locks.LockingVisitors.StampedLockVisitor;
2629 import org.apache.commons.lang3.function.FailableConsumer;
2730 import org.junit.jupiter.api.Test;
2831
2932 public class LockingVisitorsTest {
33
34 private static final Duration SHORT_DELAY = Duration.ofMillis(100);
35 private static final Duration DELAY = Duration.ofMillis(1500);
3036 private static final int NUMBER_OF_THREADS = 10;
31 private static final long DELAY_MILLIS = 3000;
32 private static final long TOTAL_DELAY_MILLIS = NUMBER_OF_THREADS * DELAY_MILLIS;
37 private static final Duration TOTAL_DELAY = DELAY.multipliedBy(NUMBER_OF_THREADS);
38
39 protected boolean containsTrue(final boolean[] booleanArray) {
40 synchronized (booleanArray) {
41 return ArrayUtils.contains(booleanArray, true);
42 }
43 }
44
45 private void runTest(final Duration delay, final boolean exclusiveLock, final LongConsumer runTimeCheck,
46 final boolean[] booleanValues, final LockVisitor<boolean[], ?> visitor) throws InterruptedException {
47 final boolean[] runningValues = new boolean[10];
48
49 final long startTimeMillis = System.currentTimeMillis();
50 for (int i = 0; i < booleanValues.length; i++) {
51 final int index = i;
52 final FailableConsumer<boolean[], ?> consumer = b -> {
53 b[index] = false;
54 ThreadUtils.sleep(delay);
55 b[index] = true;
56 set(runningValues, index, false);
57 };
58 final Thread t = new Thread(() -> {
59 if (exclusiveLock) {
60 visitor.acceptWriteLocked(consumer);
61 } else {
62 visitor.acceptReadLocked(consumer);
63 }
64 });
65 set(runningValues, i, true);
66 t.start();
67 }
68 while (containsTrue(runningValues)) {
69 ThreadUtils.sleep(SHORT_DELAY);
70 }
71 final long endTimeMillis = System.currentTimeMillis();
72 for (final boolean booleanValue : booleanValues) {
73 assertTrue(booleanValue);
74 }
75 // WRONG assumption
76 // runTimeCheck.accept(endTimeMillis - startTimeMillis);
77 }
78
79 protected void set(final boolean[] booleanArray, final int offset, final boolean value) {
80 synchronized (booleanArray) {
81 booleanArray[offset] = value;
82 }
83 }
3384
3485 @Test
35 public void testStampedLockNotExclusive() throws Exception {
86 public void testReentrantReadWriteLockExclusive() throws Exception {
3687
3788 /*
38 * If our threads are running concurrently, then we expect to be faster than running one after the other.
89 * If our threads are running concurrently, then we expect to be no faster than running one after the other.
3990 */
40 boolean[] booleanValues = new boolean[10];
41 runTest(DELAY_MILLIS, false, l -> assertTrue(l < TOTAL_DELAY_MILLIS), booleanValues,
42 LockingVisitors.stampedLockVisitor(booleanValues));
91 final boolean[] booleanValues = new boolean[10];
92 runTest(DELAY, true, millis -> assertTrue(millis >= TOTAL_DELAY.toMillis()), booleanValues,
93 LockingVisitors.reentrantReadWriteLockVisitor(booleanValues));
4394 }
4495
4596 @Test
4899 /*
49100 * If our threads are running concurrently, then we expect to be faster than running one after the other.
50101 */
51 boolean[] booleanValues = new boolean[10];
52 runTest(DELAY_MILLIS, false, l -> assertTrue(l < TOTAL_DELAY_MILLIS), booleanValues,
102 final boolean[] booleanValues = new boolean[10];
103 runTest(DELAY, false, millis -> assertTrue(millis < TOTAL_DELAY.toMillis()), booleanValues,
53104 LockingVisitors.reentrantReadWriteLockVisitor(booleanValues));
105 }
106
107 @Test
108 public void testResultValidation() {
109 final Object hidden = new Object();
110 final StampedLockVisitor<Object> lock = LockingVisitors.stampedLockVisitor(hidden);
111 final Object o1 = lock.applyReadLocked(h -> new Object());
112 assertNotNull(o1);
113 assertNotSame(hidden, o1);
114 final Object o2 = lock.applyWriteLocked(h -> new Object());
115 assertNotNull(o2);
116 assertNotSame(hidden, o2);
54117 }
55118
56119 @Test
59122 /*
60123 * If our threads are running concurrently, then we expect to be no faster than running one after the other.
61124 */
62 boolean[] booleanValues = new boolean[10];
63 runTest(DELAY_MILLIS, true, l -> assertTrue(l >= TOTAL_DELAY_MILLIS), booleanValues,
125 final boolean[] booleanValues = new boolean[10];
126 runTest(DELAY, true, millis -> assertTrue(millis >= TOTAL_DELAY.toMillis()), booleanValues,
64127 LockingVisitors.stampedLockVisitor(booleanValues));
65128 }
66129
67130 @Test
68 public void testReentrantReadWriteLockExclusive() throws Exception {
131 public void testStampedLockNotExclusive() throws Exception {
69132
70133 /*
71 * If our threads are running concurrently, then we expect to be no faster than running one after the other.
134 * If our threads are running concurrently, then we expect to be faster than running one after the other.
72135 */
73 boolean[] booleanValues = new boolean[10];
74 runTest(DELAY_MILLIS, true, l -> assertTrue(l >= TOTAL_DELAY_MILLIS), booleanValues,
75 LockingVisitors.reentrantReadWriteLockVisitor(booleanValues));
76 }
77
78 @Test
79 public void testResultValidation() {
80 final Object hidden = new Object();
81 final StampedLockVisitor<Object> lock = LockingVisitors.stampedLockVisitor(hidden);
82 final Object o1 = lock.applyReadLocked(h -> {
83 return new Object(); });
84 assertNotNull(o1);
85 assertNotSame(hidden, o1);
86 final Object o2 = lock.applyWriteLocked(h -> {
87 return new Object(); });
88 assertNotNull(o2);
89 assertNotSame(hidden, o2);
90 }
91
92 private void runTest(final long delayMillis, final boolean exclusiveLock, final LongConsumer runTimeCheck,
93 boolean[] booleanValues, LockVisitor<boolean[], ?> visitor) throws InterruptedException {
94 final boolean[] runningValues = new boolean[10];
95
96 final long startTime = System.currentTimeMillis();
97 for (int i = 0; i < booleanValues.length; i++) {
98 final int index = i;
99 final FailableConsumer<boolean[], ?> consumer = b -> {
100 b[index] = false;
101 Thread.sleep(delayMillis);
102 b[index] = true;
103 modify(runningValues, index, false);
104 };
105 final Thread t = new Thread(() -> {
106 if (exclusiveLock) {
107 visitor.acceptWriteLocked(consumer);
108 } else {
109 visitor.acceptReadLocked(consumer);
110 }
111 });
112 modify(runningValues, i, true);
113 t.start();
114 }
115 while (someValueIsTrue(runningValues)) {
116 Thread.sleep(100);
117 }
118 final long endTime = System.currentTimeMillis();
119 for (int i = 0; i < booleanValues.length; i++) {
120 assertTrue(booleanValues[i]);
121 }
122 // WRONG assumption
123 // runTimeCheck.accept(endTime - startTime);
124 }
125
126 protected void modify(final boolean[] booleanArray, final int offset, final boolean value) {
127 synchronized (booleanArray) {
128 booleanArray[offset] = value;
129 }
130 }
131
132 protected boolean someValueIsTrue(final boolean[] booleanArray) {
133 synchronized (booleanArray) {
134 for (int i = 0; i < booleanArray.length; i++) {
135 if (booleanArray[i]) {
136 return true;
137 }
138 }
139 return false;
140 }
136 final boolean[] booleanValues = new boolean[10];
137 runTest(DELAY, false, millis -> assertTrue(millis < TOTAL_DELAY.toMillis()), booleanValues,
138 LockingVisitors.stampedLockVisitor(booleanValues));
141139 }
142140 }
6161 }
6262
6363 ExceptionWithCause(final Throwable cause) {
64 super();
6564 setCause(cause);
6665 }
6766
9493
9594 @SuppressWarnings("unused")
9695 NestableException() {
97 super();
9896 }
9997
10098 NestableException(final Throwable t) {
222222 return 0;
223223 }
224224
225 public short testAsShortPrimitive() throws Throwable {
226 return testAsShortPrimitive(throwable);
227 }
228
229 public short testAsShortPrimitive(final Throwable throwable) throws Throwable {
230 if (throwable != null) {
231 throw throwable;
232 }
233 return 0;
234 }
235
225236 public void testDouble(final double i) throws Throwable {
226237 test(throwable);
227238 acceptedPrimitiveObject1 = (P) ((Double) i);
10441055 }
10451056
10461057 @Test
1058 public void testGetAsShortSupplier() {
1059 final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
1060 Throwable e = assertThrows(IllegalStateException.class,
1061 () -> Failable.getAsShort(testable::testAsShortPrimitive));
1062 assertSame(ILLEGAL_STATE_EXCEPTION, e);
1063
1064 testable.setThrowable(ERROR);
1065 e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsShort(testable::testAsShortPrimitive));
1066 assertSame(ERROR, e);
1067
1068 final IOException ioe = new IOException("Unknown I/O error");
1069 testable.setThrowable(ioe);
1070 e = assertThrows(UncheckedIOException.class, () -> Failable.getAsShort(testable::testAsShortPrimitive));
1071 final Throwable t = e.getCause();
1072 assertNotNull(t);
1073 assertSame(ioe, t);
1074
1075 testable.setThrowable(null);
1076 final short i = Failable.getAsShort(testable::testAsShortPrimitive);
1077 assertEquals(0, i);
1078 }
1079
1080 @Test
10471081 public void testGetFromSupplier() {
10481082 FailureOnOddInvocations.invocations = 0;
10491083 final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class,
13391373 }
13401374
13411375 /**
1342 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1376 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
13431377 * Object and Throwable.
13441378 */
13451379 @Test
13701404 }
13711405
13721406 /**
1373 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1407 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
13741408 * Object and Throwable.
13751409 */
13761410 @Test
14001434 }
14011435
14021436 /**
1403 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1437 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
14041438 * Object and Throwable.
14051439 */
14061440 @Test
14301464 }
14311465
14321466 /**
1433 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1434 * Object and Throwable.
1435 */
1436 @Test
1437 public void testThrows_FailableBooleanSupplier_Object_Throwable() {
1467 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1468 * generic test types.
1469 */
1470 @Test
1471 public void testThrows_FailableBooleanSupplier_IOException() {
1472 new FailableBooleanSupplier<IOException>() {
1473
1474 @Override
1475 public boolean getAsBoolean() throws IOException {
1476 throw new IOException("test");
1477 }
1478 };
1479 }
1480
1481 /**
1482 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1483 * Object and Throwable.
1484 */
1485 @Test
1486 public void testThrows_FailableBooleanSupplier_Throwable() {
14381487 new FailableBooleanSupplier<Throwable>() {
14391488
14401489 @Override
14451494 }
14461495
14471496 /**
1448 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1449 * generic test types.
1450 */
1451 @Test
1452 public void testThrows_FailableBooleanSupplier_String_IOException() {
1453 new FailableBooleanSupplier<IOException>() {
1454
1455 @Override
1456 public boolean getAsBoolean() throws IOException {
1457 throw new IOException("test");
1458 }
1459 };
1460 }
1461
1462 ///////////////////////////////////////////////
1463
1464 /**
1465 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1497 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
14661498 * Object and Throwable.
14671499 */
14681500 @Test
14921524 }
14931525
14941526 /**
1495 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1527 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
14961528 * Object and Throwable.
14971529 */
14981530 @Test
15241556 }
15251557
15261558 /**
1527 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1528 * Object and Throwable.
1529 */
1530 @Test
1531 public void testThrows_FailableDoubleBinaryOperator_Object_Throwable() {
1559 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1560 * generic test types.
1561 */
1562 @Test
1563 public void testThrows_FailableDoubleBinaryOperator_IOException() {
1564 new FailableDoubleBinaryOperator<IOException>() {
1565
1566 @Override
1567 public double applyAsDouble(final double left, final double right) throws IOException {
1568 throw new IOException("test");
1569 }
1570 };
1571 }
1572
1573 /**
1574 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1575 * Object and Throwable.
1576 */
1577 @Test
1578 public void testThrows_FailableDoubleBinaryOperator_Throwable() {
15321579 new FailableDoubleBinaryOperator<Throwable>() {
15331580
15341581 @Override
15431590 * generic test types.
15441591 */
15451592 @Test
1546 public void testThrows_FailableDoubleBinaryOperator_String_IOException() {
1547 new FailableDoubleBinaryOperator<IOException>() {
1548
1549 @Override
1550 public double applyAsDouble(final double left, final double right) throws IOException {
1551 throw new IOException("test");
1552 }
1553 };
1554 }
1555
1556 /**
1557 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1558 * Object and Throwable.
1559 */
1560 @Test
1561 public void testThrows_FailableDoubleConsumer_Object_Throwable() {
1593 public void testThrows_FailableDoubleConsumer_IOException() {
1594 new FailableDoubleConsumer<IOException>() {
1595
1596 @Override
1597 public void accept(final double value) throws IOException {
1598 throw new IOException("test");
1599 }
1600 };
1601 }
1602
1603 /**
1604 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1605 * Object and Throwable.
1606 */
1607 @Test
1608 public void testThrows_FailableDoubleConsumer_Throwable() {
15621609 new FailableDoubleConsumer<Throwable>() {
15631610
15641611 @Override
15741621 * generic test types.
15751622 */
15761623 @Test
1577 public void testThrows_FailableDoubleConsumer_String_IOException() {
1578 new FailableDoubleConsumer<IOException>() {
1579
1580 @Override
1581 public void accept(final double value) throws IOException {
1582 throw new IOException("test");
1583 }
1584 };
1585 }
1586
1587 /**
1588 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1589 * Object and Throwable.
1590 */
1591 @Test
1592 public void testThrows_FailableDoubleFunction_Object_Throwable() {
1624 public void testThrows_FailableDoubleFunction_IOException() {
1625 new FailableDoubleFunction<String, IOException>() {
1626
1627 @Override
1628 public String apply(final double input) throws IOException {
1629 throw new IOException("test");
1630 }
1631 };
1632 }
1633
1634 /**
1635 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1636 * Object and Throwable.
1637 */
1638 @Test
1639 public void testThrows_FailableDoubleFunction_Throwable() {
15931640 new FailableDoubleFunction<Object, Throwable>() {
15941641
15951642 @Override
16041651 * generic test types.
16051652 */
16061653 @Test
1607 public void testThrows_FailableDoubleFunction_String_IOException() {
1608 new FailableDoubleFunction<String, IOException>() {
1609
1610 @Override
1611 public String apply(final double input) throws IOException {
1612 throw new IOException("test");
1613 }
1614 };
1615 }
1616
1617 /**
1618 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1619 * Object and Throwable.
1620 */
1621 @Test
1622 public void testThrows_FailableDoubleSupplier_Object_Throwable() {
1654 public void testThrows_FailableDoubleSupplier_IOException() {
1655 new FailableDoubleSupplier<IOException>() {
1656
1657 @Override
1658 public double getAsDouble() throws IOException {
1659 throw new IOException("test");
1660 }
1661 };
1662 }
1663
1664 /**
1665 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1666 * Object and Throwable.
1667 */
1668 @Test
1669 public void testThrows_FailableDoubleSupplier_Throwable() {
16231670 new FailableDoubleSupplier<Throwable>() {
16241671
16251672 @Override
16341681 * generic test types.
16351682 */
16361683 @Test
1637 public void testThrows_FailableDoubleSupplier_String_IOException() {
1638 new FailableDoubleSupplier<IOException>() {
1639
1640 @Override
1641 public double getAsDouble() throws IOException {
1642 throw new IOException("test");
1643 }
1644 };
1645 }
1646
1647 /**
1648 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1649 * Object and Throwable.
1650 */
1651 @Test
1652 public void testThrows_FailableDoubleToIntFunction_Object_Throwable() {
1684 public void testThrows_FailableDoubleToIntFunction_IOException() {
1685 new FailableDoubleToIntFunction<IOException>() {
1686
1687 @Override
1688 public int applyAsInt(final double value) throws IOException {
1689 throw new IOException("test");
1690 }
1691 };
1692 }
1693
1694 /**
1695 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1696 * Object and Throwable.
1697 */
1698 @Test
1699 public void testThrows_FailableDoubleToIntFunction_Throwable() {
16531700 new FailableDoubleToIntFunction<Throwable>() {
16541701
16551702 @Override
16641711 * generic test types.
16651712 */
16661713 @Test
1667 public void testThrows_FailableDoubleToIntFunction_String_IOException() {
1668 new FailableDoubleToIntFunction<IOException>() {
1669
1670 @Override
1671 public int applyAsInt(final double value) throws IOException {
1672 throw new IOException("test");
1673 }
1674 };
1675 }
1676
1677 /**
1678 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1679 * Object and Throwable.
1680 */
1681 @Test
1682 public void testThrows_FailableDoubleToLongFunction_Object_Throwable() {
1714 public void testThrows_FailableDoubleToLongFunction_IOException() {
1715 new FailableDoubleToLongFunction<IOException>() {
1716
1717 @Override
1718 public int applyAsLong(final double value) throws IOException {
1719 throw new IOException("test");
1720 }
1721 };
1722 }
1723
1724 /**
1725 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1726 * Object and Throwable.
1727 */
1728 @Test
1729 public void testThrows_FailableDoubleToLongFunction_Throwable() {
16831730 new FailableDoubleToLongFunction<Throwable>() {
16841731
16851732 @Override
16901737 }
16911738
16921739 /**
1693 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1694 * generic test types.
1695 */
1696 @Test
1697 public void testThrows_FailableDoubleToLongFunction_String_IOException() {
1698 new FailableDoubleToLongFunction<IOException>() {
1699
1700 @Override
1701 public int applyAsLong(final double value) throws IOException {
1702 throw new IOException("test");
1703 }
1704 };
1705 }
1706
1707 /**
1708 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1740 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
17091741 * Object and Throwable.
17101742 */
17111743 @Test
17351767 }
17361768
17371769 /**
1738 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1739 * Object and Throwable.
1740 */
1741 @Test
1742 public void testThrows_FailableIntBinaryOperator_Object_Throwable() {
1770 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1771 * generic test types.
1772 */
1773 @Test
1774 public void testThrows_FailableIntBinaryOperator_IOException() {
1775 new FailableIntBinaryOperator<IOException>() {
1776
1777 @Override
1778 public int applyAsInt(final int left, final int right) throws IOException {
1779 throw new IOException("test");
1780 }
1781 };
1782 }
1783
1784 /**
1785 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1786 * Object and Throwable.
1787 */
1788 @Test
1789 public void testThrows_FailableIntBinaryOperator_Throwable() {
17431790 new FailableIntBinaryOperator<Throwable>() {
17441791
17451792 @Override
17541801 * generic test types.
17551802 */
17561803 @Test
1757 public void testThrows_FailableIntBinaryOperator_String_IOException() {
1758 new FailableIntBinaryOperator<IOException>() {
1759
1760 @Override
1761 public int applyAsInt(final int left, final int right) throws IOException {
1762 throw new IOException("test");
1763 }
1764 };
1765 }
1766
1767 /**
1768 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1769 * Object and Throwable.
1770 */
1771 @Test
1772 public void testThrows_FailableIntConsumer_Object_Throwable() {
1804 public void testThrows_FailableIntConsumer_IOException() {
1805 new FailableIntConsumer<IOException>() {
1806
1807 @Override
1808 public void accept(final int value) throws IOException {
1809 throw new IOException("test");
1810 }
1811 };
1812 }
1813
1814 /**
1815 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1816 * Object and Throwable.
1817 */
1818 @Test
1819 public void testThrows_FailableIntConsumer_Throwable() {
17731820 new FailableIntConsumer<Throwable>() {
17741821
17751822 @Override
17811828 }
17821829
17831830 /**
1784 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1785 * generic test types.
1786 */
1787 @Test
1788 public void testThrows_FailableIntConsumer_String_IOException() {
1789 new FailableIntConsumer<IOException>() {
1790
1791 @Override
1792 public void accept(final int value) throws IOException {
1793 throw new IOException("test");
1794 }
1795 };
1796 }
1797
1798 /**
1799 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1831 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
18001832 * Object and Throwable.
18011833 */
18021834 @Test
18261858 }
18271859
18281860 /**
1829 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1830 * Object and Throwable.
1831 */
1832 @Test
1833 public void testThrows_FailableIntSupplier_Object_Throwable() {
1861 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1862 * generic test types.
1863 */
1864 @Test
1865 public void testThrows_FailableIntSupplier_IOException() {
1866 new FailableIntSupplier<IOException>() {
1867
1868 @Override
1869 public int getAsInt() throws IOException {
1870 throw new IOException("test");
1871 }
1872 };
1873 }
1874
1875 /**
1876 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1877 * Object and Throwable.
1878 */
1879 @Test
1880 public void testThrows_FailableIntSupplier_Throwable() {
18341881 new FailableIntSupplier<Throwable>() {
18351882
18361883 @Override
18451892 * generic test types.
18461893 */
18471894 @Test
1848 public void testThrows_FailableIntSupplier_String_IOException() {
1849 new FailableIntSupplier<IOException>() {
1850
1851 @Override
1852 public int getAsInt() throws IOException {
1853 throw new IOException("test");
1854 }
1855 };
1856 }
1857
1858 /**
1859 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1860 * Object and Throwable.
1861 */
1862 @Test
1863 public void testThrows_FailableIntToDoubleFunction_Object_Throwable() {
1895 public void testThrows_FailableIntToDoubleFunction_IOException() {
1896 new FailableIntToDoubleFunction<IOException>() {
1897
1898 @Override
1899 public double applyAsDouble(final int value) throws IOException {
1900 throw new IOException("test");
1901 }
1902 };
1903 }
1904
1905 /**
1906 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1907 * Object and Throwable.
1908 */
1909 @Test
1910 public void testThrows_FailableIntToDoubleFunction_Throwable() {
18641911 new FailableIntToDoubleFunction<Throwable>() {
18651912
18661913 @Override
18751922 * generic test types.
18761923 */
18771924 @Test
1878 public void testThrows_FailableIntToDoubleFunction_String_IOException() {
1879 new FailableIntToDoubleFunction<IOException>() {
1880
1881 @Override
1882 public double applyAsDouble(final int value) throws IOException {
1883 throw new IOException("test");
1884 }
1885 };
1886 }
1887
1888 /**
1889 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1890 * Object and Throwable.
1891 */
1892 @Test
1893 public void testThrows_FailableIntToLongFunction_Object_Throwable() {
1925 public void testThrows_FailableIntToLongFunction_IOException() {
1926 new FailableIntToLongFunction<IOException>() {
1927
1928 @Override
1929 public long applyAsLong(final int value) throws IOException {
1930 throw new IOException("test");
1931 }
1932 };
1933 }
1934
1935 /**
1936 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1937 * Object and Throwable.
1938 */
1939 @Test
1940 public void testThrows_FailableIntToLongFunction_Throwable() {
18941941 new FailableIntToLongFunction<Throwable>() {
18951942
18961943 @Override
19051952 * generic test types.
19061953 */
19071954 @Test
1908 public void testThrows_FailableIntToLongFunction_String_IOException() {
1909 new FailableIntToLongFunction<IOException>() {
1910
1911 @Override
1912 public long applyAsLong(final int value) throws IOException {
1913 throw new IOException("test");
1914 }
1915 };
1916 }
1917
1918 /**
1919 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1920 * Object and Throwable.
1921 */
1922 @Test
1923 public void testThrows_FailableLongBinaryOperator_Object_Throwable() {
1955 public void testThrows_FailableLongBinaryOperator_IOException() {
1956 new FailableLongBinaryOperator<IOException>() {
1957
1958 @Override
1959 public long applyAsLong(final long left, final long right) throws IOException {
1960 throw new IOException("test");
1961 }
1962 };
1963 }
1964
1965 /**
1966 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1967 * Object and Throwable.
1968 */
1969 @Test
1970 public void testThrows_FailableLongBinaryOperator_Throwable() {
19241971 new FailableLongBinaryOperator<Throwable>() {
19251972
19261973 @Override
19351982 * generic test types.
19361983 */
19371984 @Test
1938 public void testThrows_FailableLongBinaryOperator_String_IOException() {
1939 new FailableLongBinaryOperator<IOException>() {
1940
1941 @Override
1942 public long applyAsLong(final long left, final long right) throws IOException {
1943 throw new IOException("test");
1944 }
1945 };
1946 }
1947
1948 /**
1949 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1950 * Object and Throwable.
1951 */
1952 @Test
1953 public void testThrows_FailableLongConsumer_Object_Throwable() {
1985 public void testThrows_FailableLongConsumer_IOException() {
1986 new FailableLongConsumer<IOException>() {
1987
1988 @Override
1989 public void accept(final long object) throws IOException {
1990 throw new IOException("test");
1991
1992 }
1993 };
1994 }
1995
1996 /**
1997 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1998 * Object and Throwable.
1999 */
2000 @Test
2001 public void testThrows_FailableLongConsumer_Throwable() {
19542002 new FailableLongConsumer<Throwable>() {
19552003
19562004 @Override
19662014 * generic test types.
19672015 */
19682016 @Test
1969 public void testThrows_FailableLongConsumer_String_IOException() {
1970 new FailableLongConsumer<IOException>() {
1971
1972 @Override
1973 public void accept(final long object) throws IOException {
1974 throw new IOException("test");
1975
1976 }
1977 };
1978 }
1979
1980 /**
1981 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
1982 * Object and Throwable.
1983 */
1984 @Test
1985 public void testThrows_FailableLongFunction_Object_Throwable() {
2017 public void testThrows_FailableLongFunction_IOException() {
2018 new FailableLongFunction<String, IOException>() {
2019
2020 @Override
2021 public String apply(final long input) throws IOException {
2022 throw new IOException("test");
2023 }
2024 };
2025 }
2026
2027 /**
2028 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2029 * Object and Throwable.
2030 */
2031 @Test
2032 public void testThrows_FailableLongFunction_Throwable() {
19862033 new FailableLongFunction<Object, Throwable>() {
19872034
19882035 @Override
19972044 * generic test types.
19982045 */
19992046 @Test
2000 public void testThrows_FailableLongFunction_String_IOException() {
2001 new FailableLongFunction<String, IOException>() {
2002
2003 @Override
2004 public String apply(final long input) throws IOException {
2005 throw new IOException("test");
2006 }
2007 };
2008 }
2009
2010 /**
2011 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2012 * Object and Throwable.
2013 */
2014 @Test
2015 public void testThrows_FailableLongSupplier_Object_Throwable() {
2047 public void testThrows_FailableLongSupplier_IOException() {
2048 new FailableLongSupplier<IOException>() {
2049
2050 @Override
2051 public long getAsLong() throws IOException {
2052 throw new IOException("test");
2053 }
2054 };
2055 }
2056
2057 /**
2058 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2059 * Object and Throwable.
2060 */
2061 @Test
2062 public void testThrows_FailableLongSupplier_Throwable() {
20162063 new FailableLongSupplier<Throwable>() {
20172064
20182065 @Override
20272074 * generic test types.
20282075 */
20292076 @Test
2030 public void testThrows_FailableLongSupplier_String_IOException() {
2031 new FailableLongSupplier<IOException>() {
2032
2033 @Override
2034 public long getAsLong() throws IOException {
2035 throw new IOException("test");
2036 }
2037 };
2038 }
2039
2040 /**
2041 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2042 * Object and Throwable.
2043 */
2044 @Test
2045 public void testThrows_FailableLongToDoubleFunction_Object_Throwable() {
2077 public void testThrows_FailableLongToDoubleFunction_IOException() {
2078 new FailableLongToDoubleFunction<IOException>() {
2079
2080 @Override
2081 public double applyAsDouble(final long value) throws IOException {
2082 throw new IOException("test");
2083 }
2084 };
2085 }
2086
2087 /**
2088 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2089 * Object and Throwable.
2090 */
2091 @Test
2092 public void testThrows_FailableLongToDoubleFunction_Throwable() {
20462093 new FailableLongToDoubleFunction<Throwable>() {
20472094
20482095 @Override
20572104 * generic test types.
20582105 */
20592106 @Test
2060 public void testThrows_FailableLongToDoubleFunction_String_IOException() {
2061 new FailableLongToDoubleFunction<IOException>() {
2062
2063 @Override
2064 public double applyAsDouble(final long value) throws IOException {
2065 throw new IOException("test");
2066 }
2067 };
2068 }
2069
2070 /**
2071 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2072 * Object and Throwable.
2073 */
2074 @Test
2075 public void testThrows_FailableLongToIntFunction_Object_Throwable() {
2107 public void testThrows_FailableLongToIntFunction_IOException() {
2108 new FailableLongToIntFunction<IOException>() {
2109
2110 @Override
2111 public int applyAsInt(final long value) throws IOException {
2112 throw new IOException("test");
2113 }
2114 };
2115 }
2116
2117 /**
2118 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2119 * Object and Throwable.
2120 */
2121 @Test
2122 public void testThrows_FailableLongToIntFunction_Throwable() {
20762123 new FailableLongToIntFunction<Throwable>() {
20772124
20782125 @Override
20832130 }
20842131
20852132 /**
2086 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2087 * generic test types.
2088 */
2089 @Test
2090 public void testThrows_FailableLongToIntFunction_String_IOException() {
2091 new FailableLongToIntFunction<IOException>() {
2092
2093 @Override
2094 public int applyAsInt(final long value) throws IOException {
2095 throw new IOException("test");
2096 }
2097 };
2098 }
2099
2100 /**
2101 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2133 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
21022134 * Object and Throwable.
21032135 */
21042136 @Test
21292161 }
21302162
21312163 /**
2132 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2164 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
21332165 * Object and Throwable.
21342166 */
21352167 @Test
21602192 }
21612193
21622194 /**
2163 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2195 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
21642196 * Object and Throwable.
21652197 */
21662198 @Test
21912223 }
21922224
21932225 /**
2194 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2226 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
21952227 * Object and Throwable.
21962228 */
21972229 @Test
22212253 }
22222254
22232255 /**
2224 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2225 * Object and Throwable.
2226 */
2227 @Test
2228 public void testThrows_FailableRunnable_Object_Throwable() {
2256 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2257 * generic test types.
2258 */
2259 @Test
2260 public void testThrows_FailableRunnable_IOException() {
2261 new FailableRunnable<IOException>() {
2262
2263 @Override
2264 public void run() throws IOException {
2265 throw new IOException("test");
2266 }
2267 };
2268 }
2269
2270 /**
2271 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2272 * Object and Throwable.
2273 */
2274 @Test
2275 public void testThrows_FailableRunnable_Throwable() {
22292276 new FailableRunnable<Throwable>() {
22302277
22312278 @Override
22412288 * generic test types.
22422289 */
22432290 @Test
2244 public void testThrows_FailableRunnable_String_IOException() {
2245 new FailableRunnable<IOException>() {
2246
2247 @Override
2248 public void run() throws IOException {
2249 throw new IOException("test");
2250 }
2251 };
2252 }
2253
2254 /**
2255 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2291 public void testThrows_FailableShortSupplier_IOException() {
2292 new FailableShortSupplier<IOException>() {
2293
2294 @Override
2295 public short getAsShort() throws IOException {
2296 throw new IOException("test");
2297 }
2298 };
2299 }
2300
2301 /**
2302 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2303 * Object and Throwable.
2304 */
2305 @Test
2306 public void testThrows_FailableShortSupplier_Throwable() {
2307 new FailableShortSupplier<Throwable>() {
2308
2309 @Override
2310 public short getAsShort() throws Throwable {
2311 throw new IOException("test");
2312 }
2313 };
2314 }
2315
2316 /**
2317 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
22562318 * Object and Throwable.
22572319 */
22582320 @Test
22822344 }
22832345
22842346 /**
2285 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2347 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
22862348 * Object and Throwable.
22872349 */
22882350 @Test
23122374 }
23132375
23142376 /**
2315 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2377 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
23162378 * Object and Throwable.
23172379 */
23182380 @Test
23422404 }
23432405
23442406 /**
2345 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2407 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
23462408 * Object and Throwable.
23472409 */
23482410 @Test
23722434 }
23732435
23742436 /**
2375 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2437 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
23762438 * Object and Throwable.
23772439 */
23782440 @Test
24022464 }
24032465
24042466 /**
2405 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2467 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
24062468 * Object and Throwable.
24072469 */
24082470 @Test
24322494 }
24332495
24342496 /**
2435 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
2497 * Tests that our failable interface is properly defined to throw any exception using the top level generic types
24362498 * Object and Throwable.
24372499 */
24382500 @Test
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.commons.lang3.function;
18
19 import java.util.function.Supplier;
20
21 import javax.annotation.Nonnull;
22 import javax.annotation.Nullable;
23
24 import org.apache.commons.lang3.ObjectUtils;
25
26
27 /**
28 * This class provides some replacements for the corresponding methods in
29 * {@link java.util.Objects}. The replacements have the advantage, that they are properly
30 * annotated with {@link Nullable}, and/or {@link Nonnull}, so they let the
31 * compiler know, what their respective results are.
32 *
33 * The various {@code requireNonNull} methods are particularly handy, when
34 * dealing with external code, that a) doesn't support the {@link Nonnull}
35 * annotation, or if you know for other reasons, that an object is non-null.
36 * Take for example, a {@link java.util.Map map}, that you have filled with
37 * non-null values. So, in your opinion, the following should be perfectably
38 * valid code:
39 * <pre>
40 * final Map&lt;String,Object&gt; map = getMapOfNonNullValues();
41 * final @Nonnull Object o = map.get("SomeKey");
42 * </pre>
43 * However, if your Java compiler *does* null analysis, it will reject this
44 * example as invalid, because {@link java.util.Map#get(Object)} might return
45 * a null value. As a workaround, you can use this:
46 * <pre>
47 * import static org.apache.commons.lang3.function.Objects.requireNonNull;
48 *
49 * final Map&lt;String,Object&gt; map = getMapOfNonNullValues();
50 * final @Nonnull Object o = requireNonNull(map.get("SomeKey"));
51 * </pre>
52 *
53 * This class is somewhat redundant with regards to {@link ObjectUtils}.
54 * For example, {@link #requireNonNull(Object, Object)} is almost equivalent
55 * with {@link ObjectUtils#defaultIfNull(Object, Object)}. However, it isn't
56 * quite the same, because the latter can, in fact, return null. The former
57 * can't, and the Java compiler confirms this.(An alternative to redundancy
58 * would have been to change the {@code ObjectUtils} class. However, that
59 * would mean loosing upwards compatibility, and we don't do that.)
60 *
61 * @since 3.12.0
62 */
63 public class Objects {
64 /**
65 * Checks, whether the given object is non-null. If so, returns the non-null
66 * object as a result value. Otherwise, a NullPointerException is thrown.
67 * @param <T> The type of parameter {@code value}, also the result type.
68 * @param value The value, which is being checked.
69 * @return The given input value, if it was found to be non-null.
70 * @throws NullPointerException The input value was null.
71 * @see java.util.Objects#requireNonNull(Object)
72 */
73 public static <T> @Nonnull T requireNonNull(@Nullable final T value) throws NullPointerException {
74 return requireNonNull(value, "The value must not be null.");
75 }
76
77 /**
78 * Checks, whether the given object is non-null. If so, returns the non-null
79 * object as a result value. Otherwise, a NullPointerException is thrown.
80 * @param <T> The type of parameter {@code value}, also the result type.
81 * @param value The value, which is being checked.
82 * @param defaultValue The default value, which is being returned, if the
83 * check fails, and the {@code value} is null.
84 * @throws NullPointerException The input value, and the default value are null.
85 * @return The given input value, if it was found to be non-null.
86 * @see java.util.Objects#requireNonNull(Object)
87 */
88 public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final T defaultValue) throws NullPointerException {
89 return value == null ? requireNonNull(defaultValue) : value;
90 }
91
92 /**
93 * Checks, whether the given object is non-null. If so, returns the non-null
94 * object as a result value. Otherwise, a NullPointerException is thrown.
95 * @param <T> The type of parameter {@code value}, also the result type.
96 * @param value The value, which is being checked.
97 * @param msg A string, which is being used as the exceptions message, if the
98 * check fails.
99 * @return The given input value, if it was found to be non-null.
100 * @throws NullPointerException The input value was null.
101 * @see java.util.Objects#requireNonNull(Object, String)
102 * @see #requireNonNull(Object, Supplier)
103 */
104 public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final String msg) throws NullPointerException {
105 if (value == null) {
106 throw new NullPointerException(msg);
107 }
108 return value;
109 }
110
111 /**
112 * Checks, whether the given object is non-null. If so, returns the non-null
113 * object as a result value. Otherwise, a NullPointerException is thrown.
114 * @param <T> The type of parameter {@code value}, also the result type.
115 * @param value The value, which is being checked.
116 * @param msgSupplier A supplier, which creates the exception message, if the check fails.
117 * This supplier will only be invoked, if necessary.
118 * @return The given input value, if it was found to be non-null.
119 * @throws NullPointerException The input value was null.
120 * @see java.util.Objects#requireNonNull(Object, String)
121 * @see #requireNonNull(Object, String)
122 */
123 public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final Supplier<String> msgSupplier) throws NullPointerException {
124 if (value == null) {
125 throw new NullPointerException(msgSupplier.get());
126 }
127 return value;
128 }
129
130 /** Checks, whether the given object is non-null. If so, returns the non-null
131 * object as a result value. Otherwise, invokes the given {@link Supplier},
132 * and returns the suppliers result value.
133 * @param <T> The type of parameter {@code value}, also the result type of
134 * the default value supplier, and of the method itself.
135 * @param <E> The type of exception, that the {@code default value supplier},
136 * may throw.
137 * @param value The value, which is being checked.
138 * @param defaultValueSupplier The supplier, which returns the default value. This default
139 * value <em>must</em> be non-null. The supplier will only be invoked, if
140 * necessary. (If the {@code value} parameter is null, that is.)
141 * @return The given input value, if it was found to be non-null. Otherwise,
142 * the value, that has been returned by the default value supplier.
143 * @see #requireNonNull(Object)
144 * @see #requireNonNull(Object, String)
145 * @see #requireNonNull(Object, Supplier)
146 * @throws NullPointerException The default value supplier is null, or the default
147 * value supplier has returned null.
148 */
149 public static <T, E extends Throwable> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final FailableSupplier<T, E> defaultValueSupplier) throws NullPointerException {
150 if (value == null) {
151 final FailableSupplier<T, ?> supplier = requireNonNull(defaultValueSupplier, "The supplier must not be null");
152 final T defaultValue;
153 try {
154 defaultValue = supplier.get();
155 } catch (final Throwable t) {
156 throw Failable.rethrow(t);
157 }
158 return requireNonNull(defaultValue, "The supplier must not return null.");
159 }
160 return value;
161 }
162 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.commons.lang3.function;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertSame;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23 import static org.junit.jupiter.api.Assertions.fail;
24
25 import java.util.function.Supplier;
26
27 import org.junit.jupiter.api.Test;
28
29
30 class ObjectsTest {
31 @Test
32 void testRequireNonNullObject() {
33 assertSame("foo", Objects.requireNonNull("foo"));
34 try {
35 Objects.requireNonNull(null);
36 fail("Expected Exception");
37 } catch (final NullPointerException e) {
38 assertEquals("The value must not be null.", e.getMessage());
39 }
40 }
41
42 @Test
43 void testRequireNonNullObjectString() {
44 assertSame("foo", Objects.requireNonNull("foo", "bar"));
45 try {
46 Objects.requireNonNull(null, "bar");
47 fail("Expected Exception");
48 } catch (final NullPointerException e) {
49 assertEquals("bar", e.getMessage());
50 }
51 }
52
53 public static class TestableSupplier<O> implements Supplier<O> {
54 private final Supplier<O> supplier;
55 private boolean invoked;
56
57 TestableSupplier(final Supplier<O> pSupplier) {
58 this.supplier = pSupplier;
59 }
60
61 @Override
62 public O get() {
63 invoked = true;
64 return supplier.get();
65 }
66
67 public boolean isInvoked() {
68 return invoked;
69 }
70 }
71
72 @Test
73 void testRequireNonNullObjectSupplierString() {
74 final TestableSupplier<String> supplier = new TestableSupplier<>(() -> "bar");
75 assertSame("foo", Objects.requireNonNull("foo", supplier));
76 assertFalse(supplier.isInvoked());
77 try {
78 Objects.requireNonNull(null, supplier);
79 fail("Expected Exception");
80 } catch (final NullPointerException e) {
81 assertEquals("bar", e.getMessage());
82 assertTrue(supplier.isInvoked());
83 }
84 }
85
86 public static class TestableFailableSupplier<O, E extends Exception> implements FailableSupplier<O, E> {
87 private final FailableSupplier<O, E> supplier;
88 private boolean invoked;
89
90 TestableFailableSupplier(final FailableSupplier<O, E> pSupplier) {
91 this.supplier = pSupplier;
92 }
93
94 @Override
95 public O get() throws E {
96 invoked = true;
97 return supplier.get();
98 }
99
100 public boolean isInvoked() {
101 return invoked;
102 }
103 }
104
105 @Test
106 void testRequireNonNullObjectFailableSupplierString() {
107 final TestableFailableSupplier<String, ?> supplier = new TestableFailableSupplier<>(() -> null);
108 assertSame("foo", Objects.requireNonNull("foo", supplier));
109 assertFalse(supplier.isInvoked());
110 try {
111 Objects.requireNonNull(null, supplier);
112 fail("Expected Exception");
113 } catch (final NullPointerException e) {
114 assertEquals("The supplier must not return null.", e.getMessage());
115 assertTrue(supplier.isInvoked());
116 }
117 final TestableFailableSupplier<String, ?> supplier2 = new TestableFailableSupplier<>(() -> null);
118 try {
119 Objects.requireNonNull(null, supplier2);
120 fail("Expected Exception");
121 } catch (final NullPointerException e) {
122 assertEquals("The supplier must not return null.", e.getMessage());
123 assertTrue(supplier2.isInvoked());
124 }
125 final TestableFailableSupplier<String, ?> supplier3 = new TestableFailableSupplier<>(() -> "bar");
126 assertSame("bar", Objects.requireNonNull(null, supplier3));
127 final RuntimeException rte = new RuntimeException();
128 final TestableFailableSupplier<String, ?> supplier4 = new TestableFailableSupplier<>(() -> {
129 throw rte;
130 });
131 try {
132 Objects.requireNonNull(null, supplier4);
133 fail("Expected Exception");
134 } catch (final RuntimeException e) {
135 assertSame(rte, e);
136 assertTrue(supplier4.isInvoked());
137 }
138 }
139 }
3232
3333 private static final int SKIP = 500; //53
3434
35 @Test
36 public void testAbs() {
37 Fraction f;
38
39 f = Fraction.getFraction(50, 75);
40 f = f.abs();
41 assertEquals(50, f.getNumerator());
42 assertEquals(75, f.getDenominator());
43
44 f = Fraction.getFraction(-50, 75);
45 f = f.abs();
46 assertEquals(50, f.getNumerator());
47 assertEquals(75, f.getDenominator());
48
49 f = Fraction.getFraction(Integer.MAX_VALUE, 1);
50 f = f.abs();
51 assertEquals(Integer.MAX_VALUE, f.getNumerator());
52 assertEquals(1, f.getDenominator());
53
54 f = Fraction.getFraction(Integer.MAX_VALUE, -1);
55 f = f.abs();
56 assertEquals(Integer.MAX_VALUE, f.getNumerator());
57 assertEquals(1, f.getDenominator());
58
59 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(Integer.MIN_VALUE, 1).abs());
60 }
61
62 @Test
63 public void testAdd() {
64 Fraction f;
65 Fraction f1;
66 Fraction f2;
67
68 f1 = Fraction.getFraction(3, 5);
69 f2 = Fraction.getFraction(1, 5);
70 f = f1.add(f2);
71 assertEquals(4, f.getNumerator());
72 assertEquals(5, f.getDenominator());
73
74 f1 = Fraction.getFraction(3, 5);
75 f2 = Fraction.getFraction(2, 5);
76 f = f1.add(f2);
77 assertEquals(1, f.getNumerator());
78 assertEquals(1, f.getDenominator());
79
80 f1 = Fraction.getFraction(3, 5);
81 f2 = Fraction.getFraction(3, 5);
82 f = f1.add(f2);
83 assertEquals(6, f.getNumerator());
84 assertEquals(5, f.getDenominator());
85
86 f1 = Fraction.getFraction(3, 5);
87 f2 = Fraction.getFraction(-4, 5);
88 f = f1.add(f2);
89 assertEquals(-1, f.getNumerator());
90 assertEquals(5, f.getDenominator());
91
92 f1 = Fraction.getFraction(Integer.MAX_VALUE - 1, 1);
93 f2 = Fraction.ONE;
94 f = f1.add(f2);
95 assertEquals(Integer.MAX_VALUE, f.getNumerator());
96 assertEquals(1, f.getDenominator());
97
98 f1 = Fraction.getFraction(3, 5);
99 f2 = Fraction.getFraction(1, 2);
100 f = f1.add(f2);
101 assertEquals(11, f.getNumerator());
102 assertEquals(10, f.getDenominator());
103
104 f1 = Fraction.getFraction(3, 8);
105 f2 = Fraction.getFraction(1, 6);
106 f = f1.add(f2);
107 assertEquals(13, f.getNumerator());
108 assertEquals(24, f.getDenominator());
109
110 f1 = Fraction.getFraction(0, 5);
111 f2 = Fraction.getFraction(1, 5);
112 f = f1.add(f2);
113 assertSame(f2, f);
114 f = f2.add(f1);
115 assertSame(f2, f);
116
117 f1 = Fraction.getFraction(-1, 13*13*2*2);
118 f2 = Fraction.getFraction(-2, 13*17*2);
119 final Fraction fr = f1.add(f2);
120 assertEquals(13*13*17*2*2, fr.getDenominator());
121 assertEquals(-17 - 2*13*2, fr.getNumerator());
122
123 assertThrows(NullPointerException.class, () -> fr.add(null));
124
125 // if this fraction is added naively, it will overflow.
126 // check that it doesn't.
127 f1 = Fraction.getFraction(1, 32768*3);
128 f2 = Fraction.getFraction(1, 59049);
129 f = f1.add(f2);
130 assertEquals(52451, f.getNumerator());
131 assertEquals(1934917632, f.getDenominator());
132
133 f1 = Fraction.getFraction(Integer.MIN_VALUE, 3);
134 f2 = Fraction.ONE_THIRD;
135 f = f1.add(f2);
136 assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
137 assertEquals(3, f.getDenominator());
138
139 f1 = Fraction.getFraction(Integer.MAX_VALUE - 1, 1);
140 f2 = Fraction.ONE;
141 f = f1.add(f2);
142 assertEquals(Integer.MAX_VALUE, f.getNumerator());
143 assertEquals(1, f.getDenominator());
144
145 final Fraction overflower = f;
146 assertThrows(ArithmeticException.class, () -> overflower.add(Fraction.ONE)); // should overflow
147
148 // denominator should not be a multiple of 2 or 3 to trigger overflow
149 assertThrows(
150 ArithmeticException.class,
151 () -> Fraction.getFraction(Integer.MIN_VALUE, 5).add(Fraction.getFraction(-1, 5)));
152
153 final Fraction maxValue = Fraction.getFraction(-Integer.MAX_VALUE, 1);
154 assertThrows(ArithmeticException.class, () -> maxValue.add(maxValue));
155
156 final Fraction negativeMaxValue = Fraction.getFraction(-Integer.MAX_VALUE, 1);
157 assertThrows(ArithmeticException.class, () -> negativeMaxValue.add(negativeMaxValue));
158
159 final Fraction f3 = Fraction.getFraction(3, 327680);
160 final Fraction f4 = Fraction.getFraction(2, 59049);
161 assertThrows(ArithmeticException.class, () -> f3.add(f4)); // should overflow
162 }
163
164 @Test
165 public void testCompareTo() {
166 Fraction f1;
167 Fraction f2;
168
169 f1 = Fraction.getFraction(3, 5);
170 assertEquals(0, f1.compareTo(f1));
171
172 final Fraction fr = f1;
173 assertThrows(NullPointerException.class, () -> fr.compareTo(null));
174
175 f2 = Fraction.getFraction(2, 5);
176 assertTrue(f1.compareTo(f2) > 0);
177 assertEquals(0, f2.compareTo(f2));
178
179 f2 = Fraction.getFraction(4, 5);
180 assertTrue(f1.compareTo(f2) < 0);
181 assertEquals(0, f2.compareTo(f2));
182
183 f2 = Fraction.getFraction(3, 5);
184 assertEquals(0, f1.compareTo(f2));
185 assertEquals(0, f2.compareTo(f2));
186
187 f2 = Fraction.getFraction(6, 10);
188 assertEquals(0, f1.compareTo(f2));
189 assertEquals(0, f2.compareTo(f2));
190
191 f2 = Fraction.getFraction(-1, 1, Integer.MAX_VALUE);
192 assertTrue(f1.compareTo(f2) > 0);
193 assertEquals(0, f2.compareTo(f2));
194
195 }
196
35197 //--------------------------------------------------------------------------
36198 @Test
37199 public void testConstants() {
73235 }
74236
75237 @Test
76 public void testFactory_int_int() {
77 Fraction f = null;
78
79 // zero
80 f = Fraction.getFraction(0, 1);
81 assertEquals(0, f.getNumerator());
82 assertEquals(1, f.getDenominator());
83
84 f = Fraction.getFraction(0, 2);
85 assertEquals(0, f.getNumerator());
86 assertEquals(2, f.getDenominator());
87
88 // normal
89 f = Fraction.getFraction(1, 1);
90 assertEquals(1, f.getNumerator());
91 assertEquals(1, f.getDenominator());
92
93 f = Fraction.getFraction(2, 1);
238 public void testConversions() {
239 Fraction f;
240
241 f = Fraction.getFraction(3, 7, 8);
242 assertEquals(3, f.intValue());
243 assertEquals(3L, f.longValue());
244 assertEquals(3.875f, f.floatValue(), 0.00001f);
245 assertEquals(3.875d, f.doubleValue(), 0.00001d);
246 }
247
248 @Test
249 public void testDivide() {
250 Fraction f;
251 Fraction f1;
252 Fraction f2;
253
254 f1 = Fraction.getFraction(3, 5);
255 f2 = Fraction.getFraction(2, 5);
256 f = f1.divideBy(f2);
257 assertEquals(3, f.getNumerator());
258 assertEquals(2, f.getDenominator());
259
260 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(3, 5).divideBy(Fraction.ZERO));
261
262 f1 = Fraction.getFraction(0, 5);
263 f2 = Fraction.getFraction(2, 7);
264 f = f1.divideBy(f2);
265 assertSame(Fraction.ZERO, f);
266
267 f1 = Fraction.getFraction(2, 7);
268 f2 = Fraction.ONE;
269 f = f1.divideBy(f2);
94270 assertEquals(2, f.getNumerator());
95 assertEquals(1, f.getDenominator());
96
97 f = Fraction.getFraction(23, 345);
98 assertEquals(23, f.getNumerator());
99 assertEquals(345, f.getDenominator());
100
101 // improper
102 f = Fraction.getFraction(22, 7);
103 assertEquals(22, f.getNumerator());
104271 assertEquals(7, f.getDenominator());
105272
106 // negatives
107 f = Fraction.getFraction(-6, 10);
108 assertEquals(-6, f.getNumerator());
109 assertEquals(10, f.getDenominator());
110
111 f = Fraction.getFraction(6, -10);
112 assertEquals(-6, f.getNumerator());
113 assertEquals(10, f.getDenominator());
114
115 f = Fraction.getFraction(-6, -10);
116 assertEquals(6, f.getNumerator());
117 assertEquals(10, f.getDenominator());
118
119 // zero denominator
120 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, 0));
121 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(2, 0));
122 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-3, 0));
123
124 // very large: can't represent as unsimplified fraction, although
125 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(4, Integer.MIN_VALUE));
126 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, Integer.MIN_VALUE));
127 }
128
129 @Test
130 public void testFactory_int_int_int() {
131 Fraction f = null;
132
133 // zero
134 f = Fraction.getFraction(0, 0, 2);
135 assertEquals(0, f.getNumerator());
136 assertEquals(2, f.getDenominator());
137
138 f = Fraction.getFraction(2, 0, 2);
139 assertEquals(4, f.getNumerator());
140 assertEquals(2, f.getDenominator());
141
142 f = Fraction.getFraction(0, 1, 2);
143 assertEquals(1, f.getNumerator());
144 assertEquals(2, f.getDenominator());
145
146 // normal
147 f = Fraction.getFraction(1, 1, 2);
148 assertEquals(3, f.getNumerator());
149 assertEquals(2, f.getDenominator());
150
151 // negatives
152 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, -6, -10));
153 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, -6, -10));
154 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, -6, -10));
155
156 // negative whole
157 f = Fraction.getFraction(-1, 6, 10);
158 assertEquals(-16, f.getNumerator());
159 assertEquals(10, f.getDenominator());
160
161 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-1, -6, 10));
162 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-1, 6, -10));
163 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-1, -6, -10));
164
165 // zero denominator
166 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(0, 1, 0));
167 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, 2, 0));
168 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-1, -3, 0));
169 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(Integer.MAX_VALUE, 1, 2));
170 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-Integer.MAX_VALUE, 1, 2));
171
172 // very large
173 f = Fraction.getFraction(-1, 0, Integer.MAX_VALUE);
174 assertEquals(-Integer.MAX_VALUE, f.getNumerator());
175 assertEquals(Integer.MAX_VALUE, f.getDenominator());
176
177 // negative denominators not allowed in this constructor.
178 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(0, 4, Integer.MIN_VALUE));
179 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, 1, Integer.MAX_VALUE));
180 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-1, 2, Integer.MAX_VALUE));
181 }
182
183 @Test
184 public void testReducedFactory_int_int() {
185 Fraction f = null;
186
187 // zero
188 f = Fraction.getReducedFraction(0, 1);
189 assertEquals(0, f.getNumerator());
190 assertEquals(1, f.getDenominator());
191
192 // normal
193 f = Fraction.getReducedFraction(1, 1);
194 assertEquals(1, f.getNumerator());
195 assertEquals(1, f.getDenominator());
196
197 f = Fraction.getReducedFraction(2, 1);
198 assertEquals(2, f.getNumerator());
199 assertEquals(1, f.getDenominator());
200
201 // improper
202 f = Fraction.getReducedFraction(22, 7);
203 assertEquals(22, f.getNumerator());
204 assertEquals(7, f.getDenominator());
205
206 // negatives
207 f = Fraction.getReducedFraction(-6, 10);
208 assertEquals(-3, f.getNumerator());
209 assertEquals(5, f.getDenominator());
210
211 f = Fraction.getReducedFraction(6, -10);
212 assertEquals(-3, f.getNumerator());
213 assertEquals(5, f.getDenominator());
214
215 f = Fraction.getReducedFraction(-6, -10);
216 assertEquals(3, f.getNumerator());
217 assertEquals(5, f.getDenominator());
218
219 // zero denominator
220 assertThrows(ArithmeticException.class, () -> Fraction.getReducedFraction(1, 0));
221 assertThrows(ArithmeticException.class, () -> Fraction.getReducedFraction(2, 0));
222 assertThrows(ArithmeticException.class, () -> Fraction.getReducedFraction(-3, 0));
223
224 // reduced
225 f = Fraction.getReducedFraction(0, 2);
226 assertEquals(0, f.getNumerator());
227 assertEquals(1, f.getDenominator());
228
229 f = Fraction.getReducedFraction(2, 2);
230 assertEquals(1, f.getNumerator());
231 assertEquals(1, f.getDenominator());
232
233 f = Fraction.getReducedFraction(2, 4);
234 assertEquals(1, f.getNumerator());
235 assertEquals(2, f.getDenominator());
236
237 f = Fraction.getReducedFraction(15, 10);
238 assertEquals(3, f.getNumerator());
239 assertEquals(2, f.getDenominator());
240
241 f = Fraction.getReducedFraction(121, 22);
242 assertEquals(11, f.getNumerator());
243 assertEquals(2, f.getDenominator());
244
245 // Extreme values
246 // OK, can reduce before negating
247 f = Fraction.getReducedFraction(-2, Integer.MIN_VALUE);
248 assertEquals(1, f.getNumerator());
249 assertEquals(-(Integer.MIN_VALUE / 2), f.getDenominator());
250
251 // Can't reduce, negation will throw
252 assertThrows(ArithmeticException.class, () -> Fraction.getReducedFraction(-7, Integer.MIN_VALUE));
253
254 // LANG-662
255 f = Fraction.getReducedFraction(Integer.MIN_VALUE, 2);
256 assertEquals(Integer.MIN_VALUE / 2, f.getNumerator());
257 assertEquals(1, f.getDenominator());
273 f1 = Fraction.getFraction(1, Integer.MAX_VALUE);
274 f = f1.divideBy(f1);
275 assertEquals(1, f.getNumerator());
276 assertEquals(1, f.getDenominator());
277
278 f1 = Fraction.getFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
279 f2 = Fraction.getFraction(1, Integer.MAX_VALUE);
280 final Fraction fr = f1.divideBy(f2);
281 assertEquals(Integer.MIN_VALUE, fr.getNumerator());
282 assertEquals(1, fr.getDenominator());
283
284 assertThrows(NullPointerException.class, () -> fr.divideBy(null));
285
286 final Fraction smallest = Fraction.getFraction(1, Integer.MAX_VALUE);
287 assertThrows(ArithmeticException.class, () -> smallest.divideBy(smallest.invert())); // Should overflow
288
289 final Fraction negative = Fraction.getFraction(1, -Integer.MAX_VALUE);
290 assertThrows(ArithmeticException.class, () -> negative.divideBy(negative.invert())); // Should overflow
291 }
292
293
294 @Test
295 public void testEquals() {
296 Fraction f1;
297 Fraction f2;
298
299 f1 = Fraction.getFraction(3, 5);
300 assertNotEquals(null, f1);
301 assertNotEquals(f1, new Object());
302 assertNotEquals(f1, Integer.valueOf(6));
303
304 f1 = Fraction.getFraction(3, 5);
305 f2 = Fraction.getFraction(2, 5);
306 assertNotEquals(f1, f2);
307 assertEquals(f1, f1);
308 assertEquals(f2, f2);
309
310 f2 = Fraction.getFraction(3, 5);
311 assertEquals(f1, f2);
312
313 f2 = Fraction.getFraction(6, 10);
314 assertNotEquals(f1, f2);
258315 }
259316
260317 @Test
322379 }
323380
324381 @Test
382 public void testFactory_int_int() {
383 Fraction f;
384
385 // zero
386 f = Fraction.getFraction(0, 1);
387 assertEquals(0, f.getNumerator());
388 assertEquals(1, f.getDenominator());
389
390 f = Fraction.getFraction(0, 2);
391 assertEquals(0, f.getNumerator());
392 assertEquals(2, f.getDenominator());
393
394 // normal
395 f = Fraction.getFraction(1, 1);
396 assertEquals(1, f.getNumerator());
397 assertEquals(1, f.getDenominator());
398
399 f = Fraction.getFraction(2, 1);
400 assertEquals(2, f.getNumerator());
401 assertEquals(1, f.getDenominator());
402
403 f = Fraction.getFraction(23, 345);
404 assertEquals(23, f.getNumerator());
405 assertEquals(345, f.getDenominator());
406
407 // improper
408 f = Fraction.getFraction(22, 7);
409 assertEquals(22, f.getNumerator());
410 assertEquals(7, f.getDenominator());
411
412 // negatives
413 f = Fraction.getFraction(-6, 10);
414 assertEquals(-6, f.getNumerator());
415 assertEquals(10, f.getDenominator());
416
417 f = Fraction.getFraction(6, -10);
418 assertEquals(-6, f.getNumerator());
419 assertEquals(10, f.getDenominator());
420
421 f = Fraction.getFraction(-6, -10);
422 assertEquals(6, f.getNumerator());
423 assertEquals(10, f.getDenominator());
424
425 // zero denominator
426 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, 0));
427 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(2, 0));
428 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-3, 0));
429
430 // very large: can't represent as unsimplified fraction, although
431 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(4, Integer.MIN_VALUE));
432 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, Integer.MIN_VALUE));
433 }
434
435 @Test
436 public void testFactory_int_int_int() {
437 Fraction f;
438
439 // zero
440 f = Fraction.getFraction(0, 0, 2);
441 assertEquals(0, f.getNumerator());
442 assertEquals(2, f.getDenominator());
443
444 f = Fraction.getFraction(2, 0, 2);
445 assertEquals(4, f.getNumerator());
446 assertEquals(2, f.getDenominator());
447
448 f = Fraction.getFraction(0, 1, 2);
449 assertEquals(1, f.getNumerator());
450 assertEquals(2, f.getDenominator());
451
452 // normal
453 f = Fraction.getFraction(1, 1, 2);
454 assertEquals(3, f.getNumerator());
455 assertEquals(2, f.getDenominator());
456
457 // negatives
458 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, -6, -10));
459 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, -6, -10));
460 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, -6, -10));
461
462 // negative whole
463 f = Fraction.getFraction(-1, 6, 10);
464 assertEquals(-16, f.getNumerator());
465 assertEquals(10, f.getDenominator());
466
467 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-1, -6, 10));
468 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-1, 6, -10));
469 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-1, -6, -10));
470
471 // zero denominator
472 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(0, 1, 0));
473 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, 2, 0));
474 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-1, -3, 0));
475 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(Integer.MAX_VALUE, 1, 2));
476 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-Integer.MAX_VALUE, 1, 2));
477
478 // very large
479 f = Fraction.getFraction(-1, 0, Integer.MAX_VALUE);
480 assertEquals(-Integer.MAX_VALUE, f.getNumerator());
481 assertEquals(Integer.MAX_VALUE, f.getDenominator());
482
483 // negative denominators not allowed in this constructor.
484 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(0, 4, Integer.MIN_VALUE));
485 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, 1, Integer.MAX_VALUE));
486 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(-1, 2, Integer.MAX_VALUE));
487 }
488
489 @Test
325490 public void testFactory_String() {
326491 assertThrows(NullPointerException.class, () -> Fraction.getFraction(null));
327492 }
328493
329
330494 @Test
331495 public void testFactory_String_double() {
332 Fraction f = null;
496 Fraction f;
333497
334498 f = Fraction.getFraction("0.0");
335499 assertEquals(0, f.getNumerator());
353517 }
354518
355519 @Test
520 public void testFactory_String_improper() {
521 Fraction f;
522
523 f = Fraction.getFraction("0/1");
524 assertEquals(0, f.getNumerator());
525 assertEquals(1, f.getDenominator());
526
527 f = Fraction.getFraction("1/5");
528 assertEquals(1, f.getNumerator());
529 assertEquals(5, f.getDenominator());
530
531 f = Fraction.getFraction("1/2");
532 assertEquals(1, f.getNumerator());
533 assertEquals(2, f.getDenominator());
534
535 f = Fraction.getFraction("2/3");
536 assertEquals(2, f.getNumerator());
537 assertEquals(3, f.getDenominator());
538
539 f = Fraction.getFraction("7/3");
540 assertEquals(7, f.getNumerator());
541 assertEquals(3, f.getDenominator());
542
543 f = Fraction.getFraction("2/4");
544 assertEquals(2, f.getNumerator());
545 assertEquals(4, f.getDenominator());
546
547 assertThrows(NumberFormatException.class, () -> Fraction.getFraction("2/d"));
548 assertThrows(NumberFormatException.class, () -> Fraction.getFraction("2e/3"));
549 assertThrows(NumberFormatException.class, () -> Fraction.getFraction("2/"));
550 assertThrows(NumberFormatException.class, () -> Fraction.getFraction("/"));
551 }
552
553 @Test
356554 public void testFactory_String_proper() {
357 Fraction f = null;
555 Fraction f;
358556
359557 f = Fraction.getFraction("0 0/1");
360558 assertEquals(0, f.getNumerator());
389587 }
390588
391589 @Test
392 public void testFactory_String_improper() {
393 Fraction f = null;
394
395 f = Fraction.getFraction("0/1");
396 assertEquals(0, f.getNumerator());
397 assertEquals(1, f.getDenominator());
398
399 f = Fraction.getFraction("1/5");
400 assertEquals(1, f.getNumerator());
401 assertEquals(5, f.getDenominator());
402
403 f = Fraction.getFraction("1/2");
404 assertEquals(1, f.getNumerator());
405 assertEquals(2, f.getDenominator());
406
407 f = Fraction.getFraction("2/3");
408 assertEquals(2, f.getNumerator());
409 assertEquals(3, f.getDenominator());
410
411 f = Fraction.getFraction("7/3");
412 assertEquals(7, f.getNumerator());
413 assertEquals(3, f.getDenominator());
414
415 f = Fraction.getFraction("2/4");
416 assertEquals(2, f.getNumerator());
417 assertEquals(4, f.getDenominator());
418
419 assertThrows(NumberFormatException.class, () -> Fraction.getFraction("2/d"));
420 assertThrows(NumberFormatException.class, () -> Fraction.getFraction("2e/3"));
421 assertThrows(NumberFormatException.class, () -> Fraction.getFraction("2/"));
422 assertThrows(NumberFormatException.class, () -> Fraction.getFraction("/"));
423 }
424
425 @Test
426590 public void testGets() {
427 Fraction f = null;
591 Fraction f;
428592
429593 f = Fraction.getFraction(3, 5, 6);
430594 assertEquals(23, f.getNumerator());
446610 }
447611
448612 @Test
449 public void testConversions() {
450 Fraction f = null;
451
452 f = Fraction.getFraction(3, 7, 8);
453 assertEquals(3, f.intValue());
454 assertEquals(3L, f.longValue());
455 assertEquals(3.875f, f.floatValue(), 0.00001f);
456 assertEquals(3.875d, f.doubleValue(), 0.00001d);
457 }
458
459 @Test
460 public void testReduce() {
461 Fraction f = null;
462
463 f = Fraction.getFraction(50, 75);
464 Fraction result = f.reduce();
465 assertEquals(2, result.getNumerator());
466 assertEquals(3, result.getDenominator());
467
468 f = Fraction.getFraction(-2, -3);
469 result = f.reduce();
470 assertEquals(2, result.getNumerator());
471 assertEquals(3, result.getDenominator());
472
473 f = Fraction.getFraction(2, -3);
474 result = f.reduce();
475 assertEquals(-2, result.getNumerator());
476 assertEquals(3, result.getDenominator());
477
478 f = Fraction.getFraction(-2, 3);
479 result = f.reduce();
480 assertEquals(-2, result.getNumerator());
481 assertEquals(3, result.getDenominator());
482 assertSame(f, result);
483
484 f = Fraction.getFraction(2, 3);
485 result = f.reduce();
486 assertEquals(2, result.getNumerator());
487 assertEquals(3, result.getDenominator());
488 assertSame(f, result);
489
490 f = Fraction.getFraction(0, 1);
491 result = f.reduce();
492 assertEquals(0, result.getNumerator());
493 assertEquals(1, result.getDenominator());
494 assertSame(f, result);
495
496 f = Fraction.getFraction(0, 100);
497 result = f.reduce();
498 assertEquals(0, result.getNumerator());
499 assertEquals(1, result.getDenominator());
500 assertSame(result, Fraction.ZERO);
501
502 f = Fraction.getFraction(Integer.MIN_VALUE, 2);
503 result = f.reduce();
504 assertEquals(Integer.MIN_VALUE / 2, result.getNumerator());
505 assertEquals(1, result.getDenominator());
613 public void testHashCode() {
614 final Fraction f1 = Fraction.getFraction(3, 5);
615 Fraction f2 = Fraction.getFraction(3, 5);
616
617 assertEquals(f1.hashCode(), f2.hashCode());
618
619 f2 = Fraction.getFraction(2, 5);
620 assertTrue(f1.hashCode() != f2.hashCode());
621
622 f2 = Fraction.getFraction(6, 10);
623 assertTrue(f1.hashCode() != f2.hashCode());
506624 }
507625
508626 @Test
509627 public void testInvert() {
510 Fraction f = null;
628 Fraction f;
511629
512630 f = Fraction.getFraction(50, 75);
513631 f = f.invert();
534652 }
535653
536654 @Test
655 public void testMultiply() {
656 Fraction f;
657 Fraction f1;
658 Fraction f2;
659
660 f1 = Fraction.getFraction(3, 5);
661 f2 = Fraction.getFraction(2, 5);
662 f = f1.multiplyBy(f2);
663 assertEquals(6, f.getNumerator());
664 assertEquals(25, f.getDenominator());
665
666 f1 = Fraction.getFraction(6, 10);
667 f2 = Fraction.getFraction(6, 10);
668 f = f1.multiplyBy(f2);
669 assertEquals(9, f.getNumerator());
670 assertEquals(25, f.getDenominator());
671 f = f.multiplyBy(f2);
672 assertEquals(27, f.getNumerator());
673 assertEquals(125, f.getDenominator());
674
675 f1 = Fraction.getFraction(3, 5);
676 f2 = Fraction.getFraction(-2, 5);
677 f = f1.multiplyBy(f2);
678 assertEquals(-6, f.getNumerator());
679 assertEquals(25, f.getDenominator());
680
681 f1 = Fraction.getFraction(-3, 5);
682 f2 = Fraction.getFraction(-2, 5);
683 f = f1.multiplyBy(f2);
684 assertEquals(6, f.getNumerator());
685 assertEquals(25, f.getDenominator());
686
687
688 f1 = Fraction.getFraction(0, 5);
689 f2 = Fraction.getFraction(2, 7);
690 f = f1.multiplyBy(f2);
691 assertSame(Fraction.ZERO, f);
692
693 f1 = Fraction.getFraction(2, 7);
694 f2 = Fraction.ONE;
695 f = f1.multiplyBy(f2);
696 assertEquals(2, f.getNumerator());
697 assertEquals(7, f.getDenominator());
698
699 f1 = Fraction.getFraction(Integer.MAX_VALUE, 1);
700 f2 = Fraction.getFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
701 f = f1.multiplyBy(f2);
702 assertEquals(Integer.MIN_VALUE, f.getNumerator());
703 assertEquals(1, f.getDenominator());
704
705 final Fraction fr = f;
706 assertThrows(NullPointerException.class, () -> fr.multiplyBy(null));
707
708 final Fraction fr1 = Fraction.getFraction(1, Integer.MAX_VALUE);
709 assertThrows(ArithmeticException.class, () -> fr1.multiplyBy(fr1));
710
711 final Fraction fr2 = Fraction.getFraction(1, -Integer.MAX_VALUE);
712 assertThrows(ArithmeticException.class, () -> fr2.multiplyBy(fr2));
713 }
714
715 @Test
537716 public void testNegate() {
538 Fraction f = null;
717 Fraction f;
539718
540719 f = Fraction.getFraction(50, 75);
541720 f = f.negate();
557736 }
558737
559738 @Test
560 public void testAbs() {
561 Fraction f = null;
562
563 f = Fraction.getFraction(50, 75);
564 f = f.abs();
565 assertEquals(50, f.getNumerator());
566 assertEquals(75, f.getDenominator());
567
568 f = Fraction.getFraction(-50, 75);
569 f = f.abs();
570 assertEquals(50, f.getNumerator());
571 assertEquals(75, f.getDenominator());
572
573 f = Fraction.getFraction(Integer.MAX_VALUE, 1);
574 f = f.abs();
575 assertEquals(Integer.MAX_VALUE, f.getNumerator());
576 assertEquals(1, f.getDenominator());
577
578 f = Fraction.getFraction(Integer.MAX_VALUE, -1);
579 f = f.abs();
580 assertEquals(Integer.MAX_VALUE, f.getNumerator());
581 assertEquals(1, f.getDenominator());
582
583 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(Integer.MIN_VALUE, 1).abs());
584 }
585
586 @Test
587739 public void testPow() {
588 Fraction f = null;
740 Fraction f;
589741
590742 f = Fraction.getFraction(3, 5);
591743 assertEquals(Fraction.ONE, f.pow(0));
680832 }
681833
682834 @Test
683 public void testAdd() {
684 Fraction f = null;
685 Fraction f1 = null;
686 Fraction f2 = null;
687
688 f1 = Fraction.getFraction(3, 5);
689 f2 = Fraction.getFraction(1, 5);
690 f = f1.add(f2);
691 assertEquals(4, f.getNumerator());
692 assertEquals(5, f.getDenominator());
693
694 f1 = Fraction.getFraction(3, 5);
695 f2 = Fraction.getFraction(2, 5);
696 f = f1.add(f2);
697 assertEquals(1, f.getNumerator());
698 assertEquals(1, f.getDenominator());
699
700 f1 = Fraction.getFraction(3, 5);
701 f2 = Fraction.getFraction(3, 5);
702 f = f1.add(f2);
703 assertEquals(6, f.getNumerator());
704 assertEquals(5, f.getDenominator());
705
706 f1 = Fraction.getFraction(3, 5);
707 f2 = Fraction.getFraction(-4, 5);
708 f = f1.add(f2);
709 assertEquals(-1, f.getNumerator());
710 assertEquals(5, f.getDenominator());
711
712 f1 = Fraction.getFraction(Integer.MAX_VALUE - 1, 1);
713 f2 = Fraction.ONE;
714 f = f1.add(f2);
715 assertEquals(Integer.MAX_VALUE, f.getNumerator());
716 assertEquals(1, f.getDenominator());
717
718 f1 = Fraction.getFraction(3, 5);
719 f2 = Fraction.getFraction(1, 2);
720 f = f1.add(f2);
835 public void testReduce() {
836 Fraction f;
837
838 f = Fraction.getFraction(50, 75);
839 Fraction result = f.reduce();
840 assertEquals(2, result.getNumerator());
841 assertEquals(3, result.getDenominator());
842
843 f = Fraction.getFraction(-2, -3);
844 result = f.reduce();
845 assertEquals(2, result.getNumerator());
846 assertEquals(3, result.getDenominator());
847
848 f = Fraction.getFraction(2, -3);
849 result = f.reduce();
850 assertEquals(-2, result.getNumerator());
851 assertEquals(3, result.getDenominator());
852
853 f = Fraction.getFraction(-2, 3);
854 result = f.reduce();
855 assertEquals(-2, result.getNumerator());
856 assertEquals(3, result.getDenominator());
857 assertSame(f, result);
858
859 f = Fraction.getFraction(2, 3);
860 result = f.reduce();
861 assertEquals(2, result.getNumerator());
862 assertEquals(3, result.getDenominator());
863 assertSame(f, result);
864
865 f = Fraction.getFraction(0, 1);
866 result = f.reduce();
867 assertEquals(0, result.getNumerator());
868 assertEquals(1, result.getDenominator());
869 assertSame(f, result);
870
871 f = Fraction.getFraction(0, 100);
872 result = f.reduce();
873 assertEquals(0, result.getNumerator());
874 assertEquals(1, result.getDenominator());
875 assertSame(result, Fraction.ZERO);
876
877 f = Fraction.getFraction(Integer.MIN_VALUE, 2);
878 result = f.reduce();
879 assertEquals(Integer.MIN_VALUE / 2, result.getNumerator());
880 assertEquals(1, result.getDenominator());
881 }
882
883 @Test
884 public void testReducedFactory_int_int() {
885 Fraction f;
886
887 // zero
888 f = Fraction.getReducedFraction(0, 1);
889 assertEquals(0, f.getNumerator());
890 assertEquals(1, f.getDenominator());
891
892 // normal
893 f = Fraction.getReducedFraction(1, 1);
894 assertEquals(1, f.getNumerator());
895 assertEquals(1, f.getDenominator());
896
897 f = Fraction.getReducedFraction(2, 1);
898 assertEquals(2, f.getNumerator());
899 assertEquals(1, f.getDenominator());
900
901 // improper
902 f = Fraction.getReducedFraction(22, 7);
903 assertEquals(22, f.getNumerator());
904 assertEquals(7, f.getDenominator());
905
906 // negatives
907 f = Fraction.getReducedFraction(-6, 10);
908 assertEquals(-3, f.getNumerator());
909 assertEquals(5, f.getDenominator());
910
911 f = Fraction.getReducedFraction(6, -10);
912 assertEquals(-3, f.getNumerator());
913 assertEquals(5, f.getDenominator());
914
915 f = Fraction.getReducedFraction(-6, -10);
916 assertEquals(3, f.getNumerator());
917 assertEquals(5, f.getDenominator());
918
919 // zero denominator
920 assertThrows(ArithmeticException.class, () -> Fraction.getReducedFraction(1, 0));
921 assertThrows(ArithmeticException.class, () -> Fraction.getReducedFraction(2, 0));
922 assertThrows(ArithmeticException.class, () -> Fraction.getReducedFraction(-3, 0));
923
924 // reduced
925 f = Fraction.getReducedFraction(0, 2);
926 assertEquals(0, f.getNumerator());
927 assertEquals(1, f.getDenominator());
928
929 f = Fraction.getReducedFraction(2, 2);
930 assertEquals(1, f.getNumerator());
931 assertEquals(1, f.getDenominator());
932
933 f = Fraction.getReducedFraction(2, 4);
934 assertEquals(1, f.getNumerator());
935 assertEquals(2, f.getDenominator());
936
937 f = Fraction.getReducedFraction(15, 10);
938 assertEquals(3, f.getNumerator());
939 assertEquals(2, f.getDenominator());
940
941 f = Fraction.getReducedFraction(121, 22);
721942 assertEquals(11, f.getNumerator());
722 assertEquals(10, f.getDenominator());
723
724 f1 = Fraction.getFraction(3, 8);
725 f2 = Fraction.getFraction(1, 6);
726 f = f1.add(f2);
727 assertEquals(13, f.getNumerator());
728 assertEquals(24, f.getDenominator());
729
730 f1 = Fraction.getFraction(0, 5);
731 f2 = Fraction.getFraction(1, 5);
732 f = f1.add(f2);
733 assertSame(f2, f);
734 f = f2.add(f1);
735 assertSame(f2, f);
736
737 f1 = Fraction.getFraction(-1, 13*13*2*2);
738 f2 = Fraction.getFraction(-2, 13*17*2);
739 final Fraction fr = f1.add(f2);
740 assertEquals(13*13*17*2*2, fr.getDenominator());
741 assertEquals(-17 - 2*13*2, fr.getNumerator());
742
743 assertThrows(NullPointerException.class, () -> fr.add(null));
744
745 // if this fraction is added naively, it will overflow.
746 // check that it doesn't.
747 f1 = Fraction.getFraction(1, 32768*3);
748 f2 = Fraction.getFraction(1, 59049);
749 f = f1.add(f2);
750 assertEquals(52451, f.getNumerator());
751 assertEquals(1934917632, f.getDenominator());
752
753 f1 = Fraction.getFraction(Integer.MIN_VALUE, 3);
754 f2 = Fraction.ONE_THIRD;
755 f = f1.add(f2);
756 assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
757 assertEquals(3, f.getDenominator());
758
759 f1 = Fraction.getFraction(Integer.MAX_VALUE - 1, 1);
760 f2 = Fraction.ONE;
761 f = f1.add(f2);
762 assertEquals(Integer.MAX_VALUE, f.getNumerator());
763 assertEquals(1, f.getDenominator());
764
765 final Fraction overflower = f;
766 assertThrows(ArithmeticException.class, () -> overflower.add(Fraction.ONE)); // should overflow
767
768 // denominator should not be a multiple of 2 or 3 to trigger overflow
769 assertThrows(
770 ArithmeticException.class,
771 () -> Fraction.getFraction(Integer.MIN_VALUE, 5).add(Fraction.getFraction(-1, 5)));
772
773 final Fraction maxValue = Fraction.getFraction(-Integer.MAX_VALUE, 1);
774 assertThrows(ArithmeticException.class, () -> maxValue.add(maxValue));
775
776 final Fraction negativeMaxValue = Fraction.getFraction(-Integer.MAX_VALUE, 1);
777 assertThrows(ArithmeticException.class, () -> negativeMaxValue.add(negativeMaxValue));
778
779 final Fraction f3 = Fraction.getFraction(3, 327680);
780 final Fraction f4 = Fraction.getFraction(2, 59049);
781 assertThrows(ArithmeticException.class, () -> f3.add(f4)); // should overflow
943 assertEquals(2, f.getDenominator());
944
945 // Extreme values
946 // OK, can reduce before negating
947 f = Fraction.getReducedFraction(-2, Integer.MIN_VALUE);
948 assertEquals(1, f.getNumerator());
949 assertEquals(-(Integer.MIN_VALUE / 2), f.getDenominator());
950
951 // Can't reduce, negation will throw
952 assertThrows(ArithmeticException.class, () -> Fraction.getReducedFraction(-7, Integer.MIN_VALUE));
953
954 // LANG-662
955 f = Fraction.getReducedFraction(Integer.MIN_VALUE, 2);
956 assertEquals(Integer.MIN_VALUE / 2, f.getNumerator());
957 assertEquals(1, f.getDenominator());
782958 }
783959
784960 @Test
785961 public void testSubtract() {
786 Fraction f = null;
787 Fraction f1 = null;
788 Fraction f2 = null;
962 Fraction f;
963 Fraction f1;
964 Fraction f2;
789965
790966 f1 = Fraction.getFraction(3, 5);
791967 f2 = Fraction.getFraction(1, 5);
8821058 }
8831059
8841060 @Test
885 public void testMultiply() {
886 Fraction f = null;
887 Fraction f1 = null;
888 Fraction f2 = null;
889
890 f1 = Fraction.getFraction(3, 5);
891 f2 = Fraction.getFraction(2, 5);
892 f = f1.multiplyBy(f2);
893 assertEquals(6, f.getNumerator());
894 assertEquals(25, f.getDenominator());
895
896 f1 = Fraction.getFraction(6, 10);
897 f2 = Fraction.getFraction(6, 10);
898 f = f1.multiplyBy(f2);
899 assertEquals(9, f.getNumerator());
900 assertEquals(25, f.getDenominator());
901 f = f.multiplyBy(f2);
902 assertEquals(27, f.getNumerator());
903 assertEquals(125, f.getDenominator());
904
905 f1 = Fraction.getFraction(3, 5);
906 f2 = Fraction.getFraction(-2, 5);
907 f = f1.multiplyBy(f2);
908 assertEquals(-6, f.getNumerator());
909 assertEquals(25, f.getDenominator());
910
911 f1 = Fraction.getFraction(-3, 5);
912 f2 = Fraction.getFraction(-2, 5);
913 f = f1.multiplyBy(f2);
914 assertEquals(6, f.getNumerator());
915 assertEquals(25, f.getDenominator());
916
917
918 f1 = Fraction.getFraction(0, 5);
919 f2 = Fraction.getFraction(2, 7);
920 f = f1.multiplyBy(f2);
921 assertSame(Fraction.ZERO, f);
922
923 f1 = Fraction.getFraction(2, 7);
924 f2 = Fraction.ONE;
925 f = f1.multiplyBy(f2);
926 assertEquals(2, f.getNumerator());
927 assertEquals(7, f.getDenominator());
928
929 f1 = Fraction.getFraction(Integer.MAX_VALUE, 1);
930 f2 = Fraction.getFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
931 f = f1.multiplyBy(f2);
932 assertEquals(Integer.MIN_VALUE, f.getNumerator());
933 assertEquals(1, f.getDenominator());
934
935 final Fraction fr = f;
936 assertThrows(NullPointerException.class, () -> fr.multiplyBy(null));
937
938 final Fraction fr1 = Fraction.getFraction(1, Integer.MAX_VALUE);
939 assertThrows(ArithmeticException.class, () -> fr1.multiplyBy(fr1));
940
941 final Fraction fr2 = Fraction.getFraction(1, -Integer.MAX_VALUE);
942 assertThrows(ArithmeticException.class, () -> fr2.multiplyBy(fr2));
943 }
944
945 @Test
946 public void testDivide() {
947 Fraction f = null;
948 Fraction f1 = null;
949 Fraction f2 = null;
950
951 f1 = Fraction.getFraction(3, 5);
952 f2 = Fraction.getFraction(2, 5);
953 f = f1.divideBy(f2);
954 assertEquals(3, f.getNumerator());
955 assertEquals(2, f.getDenominator());
956
957 assertThrows(ArithmeticException.class, () -> Fraction.getFraction(3, 5).divideBy(Fraction.ZERO));
958
959 f1 = Fraction.getFraction(0, 5);
960 f2 = Fraction.getFraction(2, 7);
961 f = f1.divideBy(f2);
962 assertSame(Fraction.ZERO, f);
963
964 f1 = Fraction.getFraction(2, 7);
965 f2 = Fraction.ONE;
966 f = f1.divideBy(f2);
967 assertEquals(2, f.getNumerator());
968 assertEquals(7, f.getDenominator());
969
970 f1 = Fraction.getFraction(1, Integer.MAX_VALUE);
971 f = f1.divideBy(f1);
972 assertEquals(1, f.getNumerator());
973 assertEquals(1, f.getDenominator());
974
975 f1 = Fraction.getFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
976 f2 = Fraction.getFraction(1, Integer.MAX_VALUE);
977 final Fraction fr = f1.divideBy(f2);
978 assertEquals(Integer.MIN_VALUE, fr.getNumerator());
979 assertEquals(1, fr.getDenominator());
980
981 assertThrows(NullPointerException.class, () -> fr.divideBy(null));
982
983 final Fraction smallest = Fraction.getFraction(1, Integer.MAX_VALUE);
984 assertThrows(ArithmeticException.class, () -> smallest.divideBy(smallest.invert())); // Should overflow
985
986 final Fraction negative = Fraction.getFraction(1, -Integer.MAX_VALUE);
987 assertThrows(ArithmeticException.class, () -> negative.divideBy(negative.invert())); // Should overflow
988 }
989
990 @Test
991 public void testEquals() {
992 Fraction f1 = null;
993 Fraction f2 = null;
994
995 f1 = Fraction.getFraction(3, 5);
996 assertNotEquals(null, f1);
997 assertNotEquals(f1, new Object());
998 assertNotEquals(f1, Integer.valueOf(6));
999
1000 f1 = Fraction.getFraction(3, 5);
1001 f2 = Fraction.getFraction(2, 5);
1002 assertNotEquals(f1, f2);
1003 assertEquals(f1, f1);
1004 assertEquals(f2, f2);
1005
1006 f2 = Fraction.getFraction(3, 5);
1007 assertEquals(f1, f2);
1008
1009 f2 = Fraction.getFraction(6, 10);
1010 assertNotEquals(f1, f2);
1011 }
1012
1013 @Test
1014 public void testHashCode() {
1015 final Fraction f1 = Fraction.getFraction(3, 5);
1016 Fraction f2 = Fraction.getFraction(3, 5);
1017
1018 assertEquals(f1.hashCode(), f2.hashCode());
1019
1020 f2 = Fraction.getFraction(2, 5);
1021 assertTrue(f1.hashCode() != f2.hashCode());
1022
1023 f2 = Fraction.getFraction(6, 10);
1024 assertTrue(f1.hashCode() != f2.hashCode());
1025 }
1026
1027 @Test
1028 public void testCompareTo() {
1029 Fraction f1 = null;
1030 Fraction f2 = null;
1031
1032 f1 = Fraction.getFraction(3, 5);
1033 assertEquals(0, f1.compareTo(f1));
1034
1035 final Fraction fr = f1;
1036 assertThrows(NullPointerException.class, () -> fr.compareTo(null));
1037
1038 f2 = Fraction.getFraction(2, 5);
1039 assertTrue(f1.compareTo(f2) > 0);
1040 assertEquals(0, f2.compareTo(f2));
1041
1042 f2 = Fraction.getFraction(4, 5);
1043 assertTrue(f1.compareTo(f2) < 0);
1044 assertEquals(0, f2.compareTo(f2));
1045
1046 f2 = Fraction.getFraction(3, 5);
1047 assertEquals(0, f1.compareTo(f2));
1048 assertEquals(0, f2.compareTo(f2));
1049
1050 f2 = Fraction.getFraction(6, 10);
1051 assertEquals(0, f1.compareTo(f2));
1052 assertEquals(0, f2.compareTo(f2));
1053
1054 f2 = Fraction.getFraction(-1, 1, Integer.MAX_VALUE);
1055 assertTrue(f1.compareTo(f2) > 0);
1056 assertEquals(0, f2.compareTo(f2));
1057
1061 public void testToProperString() {
1062 Fraction f;
1063
1064 f = Fraction.getFraction(3, 5);
1065 final String str = f.toProperString();
1066 assertEquals("3/5", str);
1067 assertSame(str, f.toProperString());
1068
1069 f = Fraction.getFraction(7, 5);
1070 assertEquals("1 2/5", f.toProperString());
1071
1072 f = Fraction.getFraction(14, 10);
1073 assertEquals("1 4/10", f.toProperString());
1074
1075 f = Fraction.getFraction(4, 2);
1076 assertEquals("2", f.toProperString());
1077
1078 f = Fraction.getFraction(0, 2);
1079 assertEquals("0", f.toProperString());
1080
1081 f = Fraction.getFraction(2, 2);
1082 assertEquals("1", f.toProperString());
1083
1084 f = Fraction.getFraction(-7, 5);
1085 assertEquals("-1 2/5", f.toProperString());
1086
1087 f = Fraction.getFraction(Integer.MIN_VALUE, 0, 1);
1088 assertEquals("-2147483648", f.toProperString());
1089
1090 f = Fraction.getFraction(-1, 1, Integer.MAX_VALUE);
1091 assertEquals("-1 1/2147483647", f.toProperString());
1092
1093 assertEquals("-1", Fraction.getFraction(-1).toProperString());
10581094 }
10591095
10601096 @Test
10611097 public void testToString() {
1062 Fraction f = null;
1098 Fraction f;
10631099
10641100 f = Fraction.getFraction(3, 5);
10651101 final String str = f.toString();
10841120 f = Fraction.getFraction(-1, 1, Integer.MAX_VALUE);
10851121 assertEquals("-2147483648/2147483647", f.toString());
10861122 }
1087
1088 @Test
1089 public void testToProperString() {
1090 Fraction f = null;
1091
1092 f = Fraction.getFraction(3, 5);
1093 final String str = f.toProperString();
1094 assertEquals("3/5", str);
1095 assertSame(str, f.toProperString());
1096
1097 f = Fraction.getFraction(7, 5);
1098 assertEquals("1 2/5", f.toProperString());
1099
1100 f = Fraction.getFraction(14, 10);
1101 assertEquals("1 4/10", f.toProperString());
1102
1103 f = Fraction.getFraction(4, 2);
1104 assertEquals("2", f.toProperString());
1105
1106 f = Fraction.getFraction(0, 2);
1107 assertEquals("0", f.toProperString());
1108
1109 f = Fraction.getFraction(2, 2);
1110 assertEquals("1", f.toProperString());
1111
1112 f = Fraction.getFraction(-7, 5);
1113 assertEquals("-1 2/5", f.toProperString());
1114
1115 f = Fraction.getFraction(Integer.MIN_VALUE, 0, 1);
1116 assertEquals("-2147483648", f.toProperString());
1117
1118 f = Fraction.getFraction(-1, 1, Integer.MAX_VALUE);
1119 assertEquals("-1 1/2147483647", f.toProperString());
1120
1121 assertEquals("-1", Fraction.getFraction(-1).toProperString());
1122 }
11231123 }
2727 public class IEEE754rUtilsTest {
2828
2929 @Test
30 public void testLang381() {
31 assertEquals(1.2, IEEE754rUtils.min(1.2, 2.5, Double.NaN), 0.01);
32 assertEquals(2.5, IEEE754rUtils.max(1.2, 2.5, Double.NaN), 0.01);
33 assertTrue(Double.isNaN(IEEE754rUtils.max(Double.NaN, Double.NaN, Double.NaN)));
34 assertEquals(1.2f, IEEE754rUtils.min(1.2f, 2.5f, Float.NaN), 0.01);
35 assertEquals(2.5f, IEEE754rUtils.max(1.2f, 2.5f, Float.NaN), 0.01);
36 assertTrue(Float.isNaN(IEEE754rUtils.max(Float.NaN, Float.NaN, Float.NaN)));
37
38 final double[] a = new double[] { 1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN };
39 assertEquals(42.0, IEEE754rUtils.max(a), 0.01);
40 assertEquals(1.2, IEEE754rUtils.min(a), 0.01);
41
42 final double[] b = new double[] { Double.NaN, 1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN };
43 assertEquals(42.0, IEEE754rUtils.max(b), 0.01);
44 assertEquals(1.2, IEEE754rUtils.min(b), 0.01);
45
46 final float[] aF = new float[] { 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN };
47 assertEquals(1.2f, IEEE754rUtils.min(aF), 0.01);
48 assertEquals(42.0f, IEEE754rUtils.max(aF), 0.01);
49
50 final float[] bF = new float[] { Float.NaN, 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN };
51 assertEquals(1.2f, IEEE754rUtils.min(bF), 0.01);
52 assertEquals(42.0f, IEEE754rUtils.max(bF), 0.01);
30 public void testConstructorExists() {
31 new IEEE754rUtils();
5332 }
5433
5534 @Test
9675 }
9776
9877 @Test
99 public void testConstructorExists() {
100 new IEEE754rUtils();
78 public void testLang381() {
79 assertEquals(1.2, IEEE754rUtils.min(1.2, 2.5, Double.NaN), 0.01);
80 assertEquals(2.5, IEEE754rUtils.max(1.2, 2.5, Double.NaN), 0.01);
81 assertTrue(Double.isNaN(IEEE754rUtils.max(Double.NaN, Double.NaN, Double.NaN)));
82 assertEquals(1.2f, IEEE754rUtils.min(1.2f, 2.5f, Float.NaN), 0.01);
83 assertEquals(2.5f, IEEE754rUtils.max(1.2f, 2.5f, Float.NaN), 0.01);
84 assertTrue(Float.isNaN(IEEE754rUtils.max(Float.NaN, Float.NaN, Float.NaN)));
85
86 final double[] a = new double[] { 1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN };
87 assertEquals(42.0, IEEE754rUtils.max(a), 0.01);
88 assertEquals(1.2, IEEE754rUtils.min(a), 0.01);
89
90 final double[] b = new double[] { Double.NaN, 1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN };
91 assertEquals(42.0, IEEE754rUtils.max(b), 0.01);
92 assertEquals(1.2, IEEE754rUtils.min(b), 0.01);
93
94 final float[] aF = new float[] { 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN };
95 assertEquals(1.2f, IEEE754rUtils.min(aF), 0.01);
96 assertEquals(42.0f, IEEE754rUtils.max(aF), 0.01);
97
98 final float[] bF = new float[] { Float.NaN, 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN };
99 assertEquals(1.2f, IEEE754rUtils.min(bF), 0.01);
100 assertEquals(42.0f, IEEE754rUtils.max(bF), 0.01);
101101 }
102102
103103 }
3535 */
3636 public class NumberUtilsTest {
3737
38 //-----------------------------------------------------------------------
38 private boolean checkCreateNumber(final String val) {
39 try {
40 final Object obj = NumberUtils.createNumber(val);
41 return obj != null;
42 } catch (final NumberFormatException e) {
43 return false;
44 }
45 }
46
47 // ---------------------------------------------------------------------
48
49 @Test
50 public void compareByte() {
51 assertTrue(NumberUtils.compare((byte) -3, (byte) 0) < 0);
52 assertEquals(0, NumberUtils.compare((byte) 113, (byte) 113));
53 assertTrue(NumberUtils.compare((byte) 123, (byte) 32) > 0);
54 }
55
56 @Test
57 public void compareInt() {
58 assertTrue(NumberUtils.compare(-3, 0) < 0);
59 assertEquals(0, NumberUtils.compare(113, 113));
60 assertTrue(NumberUtils.compare(213, 32) > 0);
61 }
62
63 private void compareIsCreatableWithCreateNumber(final String val, final boolean expected) {
64 final boolean isValid = NumberUtils.isCreatable(val);
65 final boolean canCreate = checkCreateNumber(val);
66 assertTrue(isValid == expected && canCreate == expected, "Expecting " + expected
67 + " for isCreatable/createNumber using \"" + val + "\" but got " + isValid + " and " + canCreate);
68 }
69
70 private void compareIsNumberWithCreateNumber(final String val, final boolean expected) {
71 final boolean isValid = NumberUtils.isCreatable(val);
72 final boolean canCreate = checkCreateNumber(val);
73 assertTrue(isValid == expected && canCreate == expected, "Expecting " + expected
74 + " for isCreatable/createNumber using \"" + val + "\" but got " + isValid + " and " + canCreate);
75 }
76
77 @Test
78 public void compareLong() {
79 assertTrue(NumberUtils.compare(-3L, 0L) < 0);
80 assertEquals(0, NumberUtils.compare(113L, 113L));
81 assertTrue(NumberUtils.compare(213L, 32L) > 0);
82 }
83
84 @Test
85 public void compareShort() {
86 assertTrue(NumberUtils.compare((short) -3, (short) 0) < 0);
87 assertEquals(0, NumberUtils.compare((short) 113, (short) 113));
88 assertTrue(NumberUtils.compare((short) 213, (short) 32) > 0);
89 }
90
91 /**
92 * Test for {@link NumberUtils#toDouble(BigDecimal)}
93 */
94 @Test
95 public void testBigIntegerToDoubleBigInteger() {
96 assertEquals(0.0d, NumberUtils.toDouble((BigDecimal) null), "toDouble(BigInteger) 1 failed");
97 assertEquals(8.5d, NumberUtils.toDouble(BigDecimal.valueOf(8.5d)), "toDouble(BigInteger) 2 failed");
98 }
99
100 /**
101 * Test for {@link NumberUtils#toDouble(BigDecimal, double)}
102 */
103 @Test
104 public void testBigIntegerToDoubleBigIntegerD() {
105 assertEquals(1.1d, NumberUtils.toDouble((BigDecimal) null, 1.1d), "toDouble(BigInteger) 1 failed");
106 assertEquals(8.5d, NumberUtils.toDouble(BigDecimal.valueOf(8.5d), 1.1d), "toDouble(BigInteger) 2 failed");
107 }
108
109 // Testing JDK against old Lang functionality
110 @Test
111 public void testCompareDouble() {
112 assertEquals(0, Double.compare(Double.NaN, Double.NaN));
113 assertEquals(Double.compare(Double.NaN, Double.POSITIVE_INFINITY), +1);
114 assertEquals(Double.compare(Double.NaN, Double.MAX_VALUE), +1);
115 assertEquals(Double.compare(Double.NaN, 1.2d), +1);
116 assertEquals(Double.compare(Double.NaN, 0.0d), +1);
117 assertEquals(Double.compare(Double.NaN, -0.0d), +1);
118 assertEquals(Double.compare(Double.NaN, -1.2d), +1);
119 assertEquals(Double.compare(Double.NaN, -Double.MAX_VALUE), +1);
120 assertEquals(Double.compare(Double.NaN, Double.NEGATIVE_INFINITY), +1);
121
122 assertEquals(Double.compare(Double.POSITIVE_INFINITY, Double.NaN), -1);
123 assertEquals(0, Double.compare(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
124 assertEquals(Double.compare(Double.POSITIVE_INFINITY, Double.MAX_VALUE), +1);
125 assertEquals(Double.compare(Double.POSITIVE_INFINITY, 1.2d), +1);
126 assertEquals(Double.compare(Double.POSITIVE_INFINITY, 0.0d), +1);
127 assertEquals(Double.compare(Double.POSITIVE_INFINITY, -0.0d), +1);
128 assertEquals(Double.compare(Double.POSITIVE_INFINITY, -1.2d), +1);
129 assertEquals(Double.compare(Double.POSITIVE_INFINITY, -Double.MAX_VALUE), +1);
130 assertEquals(Double.compare(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY), +1);
131
132 assertEquals(Double.compare(Double.MAX_VALUE, Double.NaN), -1);
133 assertEquals(Double.compare(Double.MAX_VALUE, Double.POSITIVE_INFINITY), -1);
134 assertEquals(0, Double.compare(Double.MAX_VALUE, Double.MAX_VALUE));
135 assertEquals(Double.compare(Double.MAX_VALUE, 1.2d), +1);
136 assertEquals(Double.compare(Double.MAX_VALUE, 0.0d), +1);
137 assertEquals(Double.compare(Double.MAX_VALUE, -0.0d), +1);
138 assertEquals(Double.compare(Double.MAX_VALUE, -1.2d), +1);
139 assertEquals(Double.compare(Double.MAX_VALUE, -Double.MAX_VALUE), +1);
140 assertEquals(Double.compare(Double.MAX_VALUE, Double.NEGATIVE_INFINITY), +1);
141
142 assertEquals(Double.compare(1.2d, Double.NaN), -1);
143 assertEquals(Double.compare(1.2d, Double.POSITIVE_INFINITY), -1);
144 assertEquals(Double.compare(1.2d, Double.MAX_VALUE), -1);
145 assertEquals(0, Double.compare(1.2d, 1.2d));
146 assertEquals(Double.compare(1.2d, 0.0d), +1);
147 assertEquals(Double.compare(1.2d, -0.0d), +1);
148 assertEquals(Double.compare(1.2d, -1.2d), +1);
149 assertEquals(Double.compare(1.2d, -Double.MAX_VALUE), +1);
150 assertEquals(Double.compare(1.2d, Double.NEGATIVE_INFINITY), +1);
151
152 assertEquals(Double.compare(0.0d, Double.NaN), -1);
153 assertEquals(Double.compare(0.0d, Double.POSITIVE_INFINITY), -1);
154 assertEquals(Double.compare(0.0d, Double.MAX_VALUE), -1);
155 assertEquals(Double.compare(0.0d, 1.2d), -1);
156 assertEquals(0, Double.compare(0.0d, 0.0d));
157 assertEquals(Double.compare(0.0d, -0.0d), +1);
158 assertEquals(Double.compare(0.0d, -1.2d), +1);
159 assertEquals(Double.compare(0.0d, -Double.MAX_VALUE), +1);
160 assertEquals(Double.compare(0.0d, Double.NEGATIVE_INFINITY), +1);
161
162 assertEquals(Double.compare(-0.0d, Double.NaN), -1);
163 assertEquals(Double.compare(-0.0d, Double.POSITIVE_INFINITY), -1);
164 assertEquals(Double.compare(-0.0d, Double.MAX_VALUE), -1);
165 assertEquals(Double.compare(-0.0d, 1.2d), -1);
166 assertEquals(Double.compare(-0.0d, 0.0d), -1);
167 assertEquals(0, Double.compare(-0.0d, -0.0d));
168 assertEquals(Double.compare(-0.0d, -1.2d), +1);
169 assertEquals(Double.compare(-0.0d, -Double.MAX_VALUE), +1);
170 assertEquals(Double.compare(-0.0d, Double.NEGATIVE_INFINITY), +1);
171
172 assertEquals(Double.compare(-1.2d, Double.NaN), -1);
173 assertEquals(Double.compare(-1.2d, Double.POSITIVE_INFINITY), -1);
174 assertEquals(Double.compare(-1.2d, Double.MAX_VALUE), -1);
175 assertEquals(Double.compare(-1.2d, 1.2d), -1);
176 assertEquals(Double.compare(-1.2d, 0.0d), -1);
177 assertEquals(Double.compare(-1.2d, -0.0d), -1);
178 assertEquals(0, Double.compare(-1.2d, -1.2d));
179 assertEquals(Double.compare(-1.2d, -Double.MAX_VALUE), +1);
180 assertEquals(Double.compare(-1.2d, Double.NEGATIVE_INFINITY), +1);
181
182 assertEquals(Double.compare(-Double.MAX_VALUE, Double.NaN), -1);
183 assertEquals(Double.compare(-Double.MAX_VALUE, Double.POSITIVE_INFINITY), -1);
184 assertEquals(Double.compare(-Double.MAX_VALUE, Double.MAX_VALUE), -1);
185 assertEquals(Double.compare(-Double.MAX_VALUE, 1.2d), -1);
186 assertEquals(Double.compare(-Double.MAX_VALUE, 0.0d), -1);
187 assertEquals(Double.compare(-Double.MAX_VALUE, -0.0d), -1);
188 assertEquals(Double.compare(-Double.MAX_VALUE, -1.2d), -1);
189 assertEquals(0, Double.compare(-Double.MAX_VALUE, -Double.MAX_VALUE));
190 assertEquals(Double.compare(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY), +1);
191
192 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, Double.NaN), -1);
193 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY), -1);
194 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, Double.MAX_VALUE), -1);
195 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, 1.2d), -1);
196 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, 0.0d), -1);
197 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, -0.0d), -1);
198 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, -1.2d), -1);
199 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, -Double.MAX_VALUE), -1);
200 assertEquals(0, Double.compare(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
201 }
202
203 @Test
204 public void testCompareFloat() {
205 assertEquals(0, Float.compare(Float.NaN, Float.NaN));
206 assertEquals(Float.compare(Float.NaN, Float.POSITIVE_INFINITY), +1);
207 assertEquals(Float.compare(Float.NaN, Float.MAX_VALUE), +1);
208 assertEquals(Float.compare(Float.NaN, 1.2f), +1);
209 assertEquals(Float.compare(Float.NaN, 0.0f), +1);
210 assertEquals(Float.compare(Float.NaN, -0.0f), +1);
211 assertEquals(Float.compare(Float.NaN, -1.2f), +1);
212 assertEquals(Float.compare(Float.NaN, -Float.MAX_VALUE), +1);
213 assertEquals(Float.compare(Float.NaN, Float.NEGATIVE_INFINITY), +1);
214
215 assertEquals(Float.compare(Float.POSITIVE_INFINITY, Float.NaN), -1);
216 assertEquals(0, Float.compare(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
217 assertEquals(Float.compare(Float.POSITIVE_INFINITY, Float.MAX_VALUE), +1);
218 assertEquals(Float.compare(Float.POSITIVE_INFINITY, 1.2f), +1);
219 assertEquals(Float.compare(Float.POSITIVE_INFINITY, 0.0f), +1);
220 assertEquals(Float.compare(Float.POSITIVE_INFINITY, -0.0f), +1);
221 assertEquals(Float.compare(Float.POSITIVE_INFINITY, -1.2f), +1);
222 assertEquals(Float.compare(Float.POSITIVE_INFINITY, -Float.MAX_VALUE), +1);
223 assertEquals(Float.compare(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY), +1);
224
225 assertEquals(Float.compare(Float.MAX_VALUE, Float.NaN), -1);
226 assertEquals(Float.compare(Float.MAX_VALUE, Float.POSITIVE_INFINITY), -1);
227 assertEquals(0, Float.compare(Float.MAX_VALUE, Float.MAX_VALUE));
228 assertEquals(Float.compare(Float.MAX_VALUE, 1.2f), +1);
229 assertEquals(Float.compare(Float.MAX_VALUE, 0.0f), +1);
230 assertEquals(Float.compare(Float.MAX_VALUE, -0.0f), +1);
231 assertEquals(Float.compare(Float.MAX_VALUE, -1.2f), +1);
232 assertEquals(Float.compare(Float.MAX_VALUE, -Float.MAX_VALUE), +1);
233 assertEquals(Float.compare(Float.MAX_VALUE, Float.NEGATIVE_INFINITY), +1);
234
235 assertEquals(Float.compare(1.2f, Float.NaN), -1);
236 assertEquals(Float.compare(1.2f, Float.POSITIVE_INFINITY), -1);
237 assertEquals(Float.compare(1.2f, Float.MAX_VALUE), -1);
238 assertEquals(0, Float.compare(1.2f, 1.2f));
239 assertEquals(Float.compare(1.2f, 0.0f), +1);
240 assertEquals(Float.compare(1.2f, -0.0f), +1);
241 assertEquals(Float.compare(1.2f, -1.2f), +1);
242 assertEquals(Float.compare(1.2f, -Float.MAX_VALUE), +1);
243 assertEquals(Float.compare(1.2f, Float.NEGATIVE_INFINITY), +1);
244
245 assertEquals(Float.compare(0.0f, Float.NaN), -1);
246 assertEquals(Float.compare(0.0f, Float.POSITIVE_INFINITY), -1);
247 assertEquals(Float.compare(0.0f, Float.MAX_VALUE), -1);
248 assertEquals(Float.compare(0.0f, 1.2f), -1);
249 assertEquals(0, Float.compare(0.0f, 0.0f));
250 assertEquals(Float.compare(0.0f, -0.0f), +1);
251 assertEquals(Float.compare(0.0f, -1.2f), +1);
252 assertEquals(Float.compare(0.0f, -Float.MAX_VALUE), +1);
253 assertEquals(Float.compare(0.0f, Float.NEGATIVE_INFINITY), +1);
254
255 assertEquals(Float.compare(-0.0f, Float.NaN), -1);
256 assertEquals(Float.compare(-0.0f, Float.POSITIVE_INFINITY), -1);
257 assertEquals(Float.compare(-0.0f, Float.MAX_VALUE), -1);
258 assertEquals(Float.compare(-0.0f, 1.2f), -1);
259 assertEquals(Float.compare(-0.0f, 0.0f), -1);
260 assertEquals(0, Float.compare(-0.0f, -0.0f));
261 assertEquals(Float.compare(-0.0f, -1.2f), +1);
262 assertEquals(Float.compare(-0.0f, -Float.MAX_VALUE), +1);
263 assertEquals(Float.compare(-0.0f, Float.NEGATIVE_INFINITY), +1);
264
265 assertEquals(Float.compare(-1.2f, Float.NaN), -1);
266 assertEquals(Float.compare(-1.2f, Float.POSITIVE_INFINITY), -1);
267 assertEquals(Float.compare(-1.2f, Float.MAX_VALUE), -1);
268 assertEquals(Float.compare(-1.2f, 1.2f), -1);
269 assertEquals(Float.compare(-1.2f, 0.0f), -1);
270 assertEquals(Float.compare(-1.2f, -0.0f), -1);
271 assertEquals(0, Float.compare(-1.2f, -1.2f));
272 assertEquals(Float.compare(-1.2f, -Float.MAX_VALUE), +1);
273 assertEquals(Float.compare(-1.2f, Float.NEGATIVE_INFINITY), +1);
274
275 assertEquals(Float.compare(-Float.MAX_VALUE, Float.NaN), -1);
276 assertEquals(Float.compare(-Float.MAX_VALUE, Float.POSITIVE_INFINITY), -1);
277 assertEquals(Float.compare(-Float.MAX_VALUE, Float.MAX_VALUE), -1);
278 assertEquals(Float.compare(-Float.MAX_VALUE, 1.2f), -1);
279 assertEquals(Float.compare(-Float.MAX_VALUE, 0.0f), -1);
280 assertEquals(Float.compare(-Float.MAX_VALUE, -0.0f), -1);
281 assertEquals(Float.compare(-Float.MAX_VALUE, -1.2f), -1);
282 assertEquals(0, Float.compare(-Float.MAX_VALUE, -Float.MAX_VALUE));
283 assertEquals(Float.compare(-Float.MAX_VALUE, Float.NEGATIVE_INFINITY), +1);
284
285 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, Float.NaN), -1);
286 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY), -1);
287 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, Float.MAX_VALUE), -1);
288 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, 1.2f), -1);
289 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, 0.0f), -1);
290 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, -0.0f), -1);
291 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, -1.2f), -1);
292 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, -Float.MAX_VALUE), -1);
293 assertEquals(0, Float.compare(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
294 }
295
296 @SuppressWarnings("cast") // suppress instanceof warning check
297 @Test
298 public void testConstants() {
299 assertTrue(NumberUtils.LONG_ZERO instanceof Long);
300 assertTrue(NumberUtils.LONG_ONE instanceof Long);
301 assertTrue(NumberUtils.LONG_MINUS_ONE instanceof Long);
302 assertTrue(NumberUtils.INTEGER_ZERO instanceof Integer);
303 assertTrue(NumberUtils.INTEGER_ONE instanceof Integer);
304 assertTrue(NumberUtils.INTEGER_MINUS_ONE instanceof Integer);
305 assertTrue(NumberUtils.SHORT_ZERO instanceof Short);
306 assertTrue(NumberUtils.SHORT_ONE instanceof Short);
307 assertTrue(NumberUtils.SHORT_MINUS_ONE instanceof Short);
308 assertTrue(NumberUtils.BYTE_ZERO instanceof Byte);
309 assertTrue(NumberUtils.BYTE_ONE instanceof Byte);
310 assertTrue(NumberUtils.BYTE_MINUS_ONE instanceof Byte);
311 assertTrue(NumberUtils.DOUBLE_ZERO instanceof Double);
312 assertTrue(NumberUtils.DOUBLE_ONE instanceof Double);
313 assertTrue(NumberUtils.DOUBLE_MINUS_ONE instanceof Double);
314 assertTrue(NumberUtils.FLOAT_ZERO instanceof Float);
315 assertTrue(NumberUtils.FLOAT_ONE instanceof Float);
316 assertTrue(NumberUtils.FLOAT_MINUS_ONE instanceof Float);
317
318 assertEquals(0, NumberUtils.LONG_ZERO.longValue());
319 assertEquals(1, NumberUtils.LONG_ONE.longValue());
320 assertEquals(NumberUtils.LONG_MINUS_ONE.longValue(), -1);
321 assertEquals(0, NumberUtils.INTEGER_ZERO.intValue());
322 assertEquals(1, NumberUtils.INTEGER_ONE.intValue());
323 assertEquals(NumberUtils.INTEGER_MINUS_ONE.intValue(), -1);
324 assertEquals(0, NumberUtils.SHORT_ZERO.shortValue());
325 assertEquals(1, NumberUtils.SHORT_ONE.shortValue());
326 assertEquals(NumberUtils.SHORT_MINUS_ONE.shortValue(), -1);
327 assertEquals(0, NumberUtils.BYTE_ZERO.byteValue());
328 assertEquals(1, NumberUtils.BYTE_ONE.byteValue());
329 assertEquals(NumberUtils.BYTE_MINUS_ONE.byteValue(), -1);
330 assertEquals(0.0d, NumberUtils.DOUBLE_ZERO.doubleValue());
331 assertEquals(1.0d, NumberUtils.DOUBLE_ONE.doubleValue());
332 assertEquals(NumberUtils.DOUBLE_MINUS_ONE.doubleValue(), -1.0d);
333 assertEquals(0.0f, NumberUtils.FLOAT_ZERO.floatValue());
334 assertEquals(1.0f, NumberUtils.FLOAT_ONE.floatValue());
335 assertEquals(NumberUtils.FLOAT_MINUS_ONE.floatValue(), -1.0f);
336 }
337
338 // -----------------------------------------------------------------------
39339 @Test
40340 public void testConstructor() {
41341 assertNotNull(new NumberUtils());
46346 assertFalse(Modifier.isFinal(NumberUtils.class.getModifiers()));
47347 }
48348
49 //---------------------------------------------------------------------
50
51 /**
52 * Test for {@link NumberUtils#toInt(String)}.
53 */
54 @Test
55 public void testToIntString() {
56 assertEquals(12345, NumberUtils.toInt("12345"), "toInt(String) 1 failed");
57 assertEquals(0, NumberUtils.toInt("abc"), "toInt(String) 2 failed");
58 assertEquals(0, NumberUtils.toInt(""), "toInt(empty) failed");
59 assertEquals(0, NumberUtils.toInt(null), "toInt(null) failed");
60 }
61
62 /**
63 * Test for {@link NumberUtils#toInt(String, int)}.
64 */
65 @Test
66 public void testToIntStringI() {
67 assertEquals(12345, NumberUtils.toInt("12345", 5), "toInt(String, int) 1 failed");
68 assertEquals(5, NumberUtils.toInt("1234.5", 5), "toInt(String, int) 2 failed");
69 }
70
71 /**
72 * Test for {@link NumberUtils#toLong(String)}.
73 */
74 @Test
75 public void testToLongString() {
76 assertEquals(12345L, NumberUtils.toLong("12345"), "toLong(String) 1 failed");
77 assertEquals(0L, NumberUtils.toLong("abc"), "toLong(String) 2 failed");
78 assertEquals(0L, NumberUtils.toLong("1L"), "toLong(String) 3 failed");
79 assertEquals(0L, NumberUtils.toLong("1l"), "toLong(String) 4 failed");
80 assertEquals(NumberUtils.toLong(Long.MAX_VALUE + ""), Long.MAX_VALUE, "toLong(Long.MAX_VALUE) failed");
81 assertEquals(NumberUtils.toLong(Long.MIN_VALUE + ""), Long.MIN_VALUE, "toLong(Long.MIN_VALUE) failed");
82 assertEquals(0L, NumberUtils.toLong(""), "toLong(empty) failed");
83 assertEquals(0L, NumberUtils.toLong(null), "toLong(null) failed");
84 }
85
86 /**
87 * Test for {@link NumberUtils#toLong(String, long)}.
88 */
89 @Test
90 public void testToLongStringL() {
91 assertEquals(12345L, NumberUtils.toLong("12345", 5L), "toLong(String, long) 1 failed");
92 assertEquals(5L, NumberUtils.toLong("1234.5", 5L), "toLong(String, long) 2 failed");
93 }
94
95 /**
96 * Test for {@link NumberUtils#toFloat(String)}.
97 */
98 @Test
99 public void testToFloatString() {
100 assertEquals(NumberUtils.toFloat("-1.2345"), -1.2345f, "toFloat(String) 1 failed");
101 assertEquals(1.2345f, NumberUtils.toFloat("1.2345"), "toFloat(String) 2 failed");
102 assertEquals(0.0f, NumberUtils.toFloat("abc"), "toFloat(String) 3 failed");
103 // LANG-1060
104 assertEquals(NumberUtils.toFloat("-001.2345"), -1.2345f, "toFloat(String) 4 failed");
105 assertEquals(1.2345f, NumberUtils.toFloat("+001.2345"), "toFloat(String) 5 failed");
106 assertEquals(1.2345f, NumberUtils.toFloat("001.2345"), "toFloat(String) 6 failed");
107 assertEquals(0f, NumberUtils.toFloat("000.00"), "toFloat(String) 7 failed");
108
109 assertEquals(NumberUtils.toFloat(Float.MAX_VALUE + ""), Float.MAX_VALUE, "toFloat(Float.MAX_VALUE) failed");
110 assertEquals(NumberUtils.toFloat(Float.MIN_VALUE + ""), Float.MIN_VALUE, "toFloat(Float.MIN_VALUE) failed");
111 assertEquals(0.0f, NumberUtils.toFloat(""), "toFloat(empty) failed");
112 assertEquals(0.0f, NumberUtils.toFloat(null), "toFloat(null) failed");
113 }
114
115 /**
116 * Test for {@link NumberUtils#toFloat(String, float)}.
117 */
118 @Test
119 public void testToFloatStringF() {
120 assertEquals(1.2345f, NumberUtils.toFloat("1.2345", 5.1f), "toFloat(String, int) 1 failed");
121 assertEquals(5.0f, NumberUtils.toFloat("a", 5.0f), "toFloat(String, int) 2 failed");
122 // LANG-1060
123 assertEquals(5.0f, NumberUtils.toFloat("-001Z.2345", 5.0f), "toFloat(String, int) 3 failed");
124 assertEquals(5.0f, NumberUtils.toFloat("+001AB.2345", 5.0f), "toFloat(String, int) 4 failed");
125 assertEquals(5.0f, NumberUtils.toFloat("001Z.2345", 5.0f), "toFloat(String, int) 5 failed");
126 }
127
128 /**
129 * Test for {(@link NumberUtils#createNumber(String)}
130 */
131 @Test
132 public void testStringCreateNumberEnsureNoPrecisionLoss() {
133 final String shouldBeFloat = "1.23";
134 final String shouldBeDouble = "3.40282354e+38";
135 final String shouldBeBigDecimal = "1.797693134862315759e+308";
136 assertTrue(NumberUtils.createNumber(shouldBeFloat) instanceof Float);
137 assertTrue(NumberUtils.createNumber(shouldBeDouble) instanceof Double);
138 assertTrue(NumberUtils.createNumber(shouldBeBigDecimal) instanceof BigDecimal);
139 // LANG-1060
140 assertTrue(NumberUtils.createNumber("001.12") instanceof Float);
141 assertTrue(NumberUtils.createNumber("-001.12") instanceof Float);
142 assertTrue(NumberUtils.createNumber("+001.12") instanceof Float);
143 assertTrue(NumberUtils.createNumber("003.40282354e+38") instanceof Double);
144 assertTrue(NumberUtils.createNumber("-003.40282354e+38") instanceof Double);
145 assertTrue(NumberUtils.createNumber("+003.40282354e+38") instanceof Double);
146 assertTrue(NumberUtils.createNumber("0001.797693134862315759e+308") instanceof BigDecimal);
147 assertTrue(NumberUtils.createNumber("-001.797693134862315759e+308") instanceof BigDecimal);
148 assertTrue(NumberUtils.createNumber("+001.797693134862315759e+308") instanceof BigDecimal);
149 }
150 /**
151 * Test for {@link NumberUtils#toDouble(String)}.
152 */
153 @Test
154 public void testStringToDoubleString() {
155 assertEquals(NumberUtils.toDouble("-1.2345"), -1.2345d, "toDouble(String) 1 failed");
156 assertEquals(1.2345d, NumberUtils.toDouble("1.2345"), "toDouble(String) 2 failed");
157 assertEquals(0.0d, NumberUtils.toDouble("abc"), "toDouble(String) 3 failed");
158 // LANG-1060
159 assertEquals(NumberUtils.toDouble("-001.2345"), -1.2345d, "toDouble(String) 4 failed");
160 assertEquals(1.2345d, NumberUtils.toDouble("+001.2345"), "toDouble(String) 5 failed");
161 assertEquals(1.2345d, NumberUtils.toDouble("001.2345"), "toDouble(String) 6 failed");
162 assertEquals(0d, NumberUtils.toDouble("000.00000"), "toDouble(String) 7 failed");
163
164 assertEquals(NumberUtils.toDouble(Double.MAX_VALUE + ""), Double.MAX_VALUE, "toDouble(Double.MAX_VALUE) failed");
165 assertEquals(NumberUtils.toDouble(Double.MIN_VALUE + ""), Double.MIN_VALUE, "toDouble(Double.MIN_VALUE) failed");
166 assertEquals(0.0d, NumberUtils.toDouble(""), "toDouble(empty) failed");
167 assertEquals(0.0d, NumberUtils.toDouble((String) null), "toDouble(null) failed");
168 }
169
170 /**
171 * Test for {@link NumberUtils#toDouble(String, double)}.
172 */
173 @Test
174 public void testStringToDoubleStringD() {
175 assertEquals(1.2345d, NumberUtils.toDouble("1.2345", 5.1d), "toDouble(String, int) 1 failed");
176 assertEquals(5.0d, NumberUtils.toDouble("a", 5.0d), "toDouble(String, int) 2 failed");
177 // LANG-1060
178 assertEquals(1.2345d, NumberUtils.toDouble("001.2345", 5.1d), "toDouble(String, int) 3 failed");
179 assertEquals(NumberUtils.toDouble("-001.2345", 5.1d), -1.2345d, "toDouble(String, int) 4 failed");
180 assertEquals(1.2345d, NumberUtils.toDouble("+001.2345", 5.1d), "toDouble(String, int) 5 failed");
181 assertEquals(0d, NumberUtils.toDouble("000.00", 5.1d), "toDouble(String, int) 7 failed");
182 }
183
184 /**
185 * Test for {@link NumberUtils#toDouble(BigDecimal)}
186 */
187 @Test
188 public void testBigIntegerToDoubleBigInteger() {
189 assertEquals(0.0d, NumberUtils.toDouble((BigDecimal) null), "toDouble(BigInteger) 1 failed");
190 assertEquals(8.5d, NumberUtils.toDouble(BigDecimal.valueOf(8.5d)), "toDouble(BigInteger) 2 failed");
191 }
192
193 /**
194 * Test for {@link NumberUtils#toDouble(BigDecimal, double)}
195 */
196 @Test
197 public void testBigIntegerToDoubleBigIntegerD() {
198 assertEquals(1.1d, NumberUtils.toDouble((BigDecimal) null, 1.1d), "toDouble(BigInteger) 1 failed");
199 assertEquals(8.5d, NumberUtils.toDouble(BigDecimal.valueOf(8.5d), 1.1d), "toDouble(BigInteger) 2 failed");
200 }
201
202 /**
203 * Test for {@link NumberUtils#toByte(String)}.
204 */
205 @Test
206 public void testToByteString() {
207 assertEquals(123, NumberUtils.toByte("123"), "toByte(String) 1 failed");
208 assertEquals(0, NumberUtils.toByte("abc"), "toByte(String) 2 failed");
209 assertEquals(0, NumberUtils.toByte(""), "toByte(empty) failed");
210 assertEquals(0, NumberUtils.toByte(null), "toByte(null) failed");
211 }
212
213 /**
214 * Test for {@link NumberUtils#toByte(String, byte)}.
215 */
216 @Test
217 public void testToByteStringI() {
218 assertEquals(123, NumberUtils.toByte("123", (byte) 5), "toByte(String, byte) 1 failed");
219 assertEquals(5, NumberUtils.toByte("12.3", (byte) 5), "toByte(String, byte) 2 failed");
220 }
221
222 /**
223 * Test for {@link NumberUtils#toShort(String)}.
224 */
225 @Test
226 public void testToShortString() {
227 assertEquals(12345, NumberUtils.toShort("12345"), "toShort(String) 1 failed");
228 assertEquals(0, NumberUtils.toShort("abc"), "toShort(String) 2 failed");
229 assertEquals(0, NumberUtils.toShort(""), "toShort(empty) failed");
230 assertEquals(0, NumberUtils.toShort(null), "toShort(null) failed");
231 }
232
233 /**
234 * Test for {@link NumberUtils#toShort(String, short)}.
235 */
236 @Test
237 public void testToShortStringI() {
238 assertEquals(12345, NumberUtils.toShort("12345", (short) 5), "toShort(String, short) 1 failed");
239 assertEquals(5, NumberUtils.toShort("1234.5", (short) 5), "toShort(String, short) 2 failed");
240 }
241
242 /**
243 * Test for {@link NumberUtils#toScaledBigDecimal(BigDecimal)}.
244 */
245 @Test
246 public void testToScaledBigDecimalBigDecimal() {
247 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(123.456)), BigDecimal.valueOf(123.46), "toScaledBigDecimal(BigDecimal) 1 failed");
248 // Test RoudingMode.HALF_EVEN default rounding.
249 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.515)), BigDecimal.valueOf(23.52), "toScaledBigDecimal(BigDecimal) 2 failed");
250 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.525)), BigDecimal.valueOf(23.52), "toScaledBigDecimal(BigDecimal) 3 failed");
251 assertEquals("2352.00", NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.525))
252 .multiply(BigDecimal.valueOf(100)).toString(), "toScaledBigDecimal(BigDecimal) 4 failed");
253 assertEquals(NumberUtils.toScaledBigDecimal((BigDecimal) null), BigDecimal.ZERO, "toScaledBigDecimal(BigDecimal) 5 failed");
254 }
255
256 /**
257 * Test for {@link NumberUtils#toScaledBigDecimal(BigDecimal, int, RoundingMode)}.
258 */
259 @Test
260 public void testToScaledBigDecimalBigDecimalIRM() {
261 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(123.456), 1, RoundingMode.CEILING), BigDecimal.valueOf(123.5), "toScaledBigDecimal(BigDecimal, int, RoudingMode) 1 failed");
262 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.5159), 3, RoundingMode.FLOOR), BigDecimal.valueOf(23.515), "toScaledBigDecimal(BigDecimal, int, RoudingMode) 2 failed");
263 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.525), 2, RoundingMode.HALF_UP), BigDecimal.valueOf(23.53), "toScaledBigDecimal(BigDecimal, int, RoudingMode) 3 failed");
264 assertEquals("23521.0000", NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.521), 4, RoundingMode.HALF_EVEN)
265 .multiply(BigDecimal.valueOf(1000))
266 .toString(), "toScaledBigDecimal(BigDecimal, int, RoudingMode) 4 failed");
267 assertEquals(NumberUtils.toScaledBigDecimal((BigDecimal) null, 2, RoundingMode.HALF_UP), BigDecimal.ZERO, "toScaledBigDecimal(BigDecimal, int, RoudingMode) 5 failed");
268 }
269
270 /**
271 * Test for {@link NumberUtils#toScaledBigDecimal(Float)}.
272 */
273 @Test
274 public void testToScaledBigDecimalFloat() {
275 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(123.456f)), BigDecimal.valueOf(123.46), "toScaledBigDecimal(Float) 1 failed");
276 // Test RoudingMode.HALF_EVEN default rounding.
277 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(23.515f)), BigDecimal.valueOf(23.51), "toScaledBigDecimal(Float) 2 failed");
278 // Note. NumberUtils.toScaledBigDecimal(Float.valueOf(23.515f)).equals(BigDecimal.valueOf(23.51))
279 // because of roundoff error. It is ok.
280 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(23.525f)), BigDecimal.valueOf(23.52), "toScaledBigDecimal(Float) 3 failed");
281 assertEquals("2352.00", NumberUtils.toScaledBigDecimal(Float.valueOf(23.525f))
282 .multiply(BigDecimal.valueOf(100)).toString(), "toScaledBigDecimal(Float) 4 failed");
283 assertEquals(NumberUtils.toScaledBigDecimal((Float) null), BigDecimal.ZERO, "toScaledBigDecimal(Float) 5 failed");
284 }
285
286 /**
287 * Test for {@link NumberUtils#toScaledBigDecimal(Float, int, RoundingMode)}.
288 */
289 @Test
290 public void testToScaledBigDecimalFloatIRM() {
291 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(123.456f), 1, RoundingMode.CEILING), BigDecimal.valueOf(123.5), "toScaledBigDecimal(Float, int, RoudingMode) 1 failed");
292 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(23.5159f), 3, RoundingMode.FLOOR), BigDecimal.valueOf(23.515), "toScaledBigDecimal(Float, int, RoudingMode) 2 failed");
293 // The following happens due to roundoff error. We're ok with this.
294 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(23.525f), 2, RoundingMode.HALF_UP), BigDecimal.valueOf(23.52), "toScaledBigDecimal(Float, int, RoudingMode) 3 failed");
295 assertEquals("23521.0000", NumberUtils.toScaledBigDecimal(Float.valueOf(23.521f), 4, RoundingMode.HALF_EVEN)
296 .multiply(BigDecimal.valueOf(1000))
297 .toString(), "toScaledBigDecimal(Float, int, RoudingMode) 4 failed");
298 assertEquals(NumberUtils.toScaledBigDecimal((Float) null, 2, RoundingMode.HALF_UP), BigDecimal.ZERO, "toScaledBigDecimal(Float, int, RoudingMode) 5 failed");
299 }
300
301 /**
302 * Test for {@link NumberUtils#toScaledBigDecimal(Double)}.
303 */
304 @Test
305 public void testToScaledBigDecimalDouble() {
306 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(123.456d)), BigDecimal.valueOf(123.46), "toScaledBigDecimal(Double) 1 failed");
307 // Test RoudingMode.HALF_EVEN default rounding.
308 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(23.515d)), BigDecimal.valueOf(23.52), "toScaledBigDecimal(Double) 2 failed");
309 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(23.525d)), BigDecimal.valueOf(23.52), "toScaledBigDecimal(Double) 3 failed");
310 assertEquals("2352.00", NumberUtils.toScaledBigDecimal(Double.valueOf(23.525d))
311 .multiply(BigDecimal.valueOf(100)).toString(), "toScaledBigDecimal(Double) 4 failed");
312 assertEquals(NumberUtils.toScaledBigDecimal((Double) null), BigDecimal.ZERO, "toScaledBigDecimal(Double) 5 failed");
313 }
314
315 /**
316 * Test for {@link NumberUtils#toScaledBigDecimal(Double, int, RoundingMode)}.
317 */
318 @Test
319 public void testToScaledBigDecimalDoubleIRM() {
320 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(123.456d), 1, RoundingMode.CEILING), BigDecimal.valueOf(123.5), "toScaledBigDecimal(Double, int, RoudingMode) 1 failed");
321 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(23.5159d), 3, RoundingMode.FLOOR), BigDecimal.valueOf(23.515), "toScaledBigDecimal(Double, int, RoudingMode) 2 failed");
322 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(23.525d), 2, RoundingMode.HALF_UP), BigDecimal.valueOf(23.53), "toScaledBigDecimal(Double, int, RoudingMode) 3 failed");
323 assertEquals("23521.0000", NumberUtils.toScaledBigDecimal(Double.valueOf(23.521d), 4, RoundingMode.HALF_EVEN)
324 .multiply(BigDecimal.valueOf(1000))
325 .toString(), "toScaledBigDecimal(Double, int, RoudingMode) 4 failed");
326 assertEquals(NumberUtils.toScaledBigDecimal((Double) null, 2, RoundingMode.HALF_UP), BigDecimal.ZERO, "toScaledBigDecimal(Double, int, RoudingMode) 5 failed");
327 }
328
329 /**
330 * Test for {@link NumberUtils#toScaledBigDecimal(Double)}.
331 */
332 @Test
333 public void testToScaledBigDecimalString() {
334 assertEquals(NumberUtils.toScaledBigDecimal("123.456"), BigDecimal.valueOf(123.46), "toScaledBigDecimal(String) 1 failed");
335 // Test RoudingMode.HALF_EVEN default rounding.
336 assertEquals(NumberUtils.toScaledBigDecimal("23.515"), BigDecimal.valueOf(23.52), "toScaledBigDecimal(String) 2 failed");
337 assertEquals(NumberUtils.toScaledBigDecimal("23.525"), BigDecimal.valueOf(23.52), "toScaledBigDecimal(String) 3 failed");
338 assertEquals("2352.00", NumberUtils.toScaledBigDecimal("23.525")
339 .multiply(BigDecimal.valueOf(100)).toString(), "toScaledBigDecimal(String) 4 failed");
340 assertEquals(NumberUtils.toScaledBigDecimal((String) null), BigDecimal.ZERO, "toScaledBigDecimal(String) 5 failed");
341 }
342
343 /**
344 * Test for {@link NumberUtils#toScaledBigDecimal(Double, int, RoundingMode)}.
345 */
346 @Test
347 public void testToScaledBigDecimalStringIRM() {
348 assertEquals(NumberUtils.toScaledBigDecimal("123.456", 1, RoundingMode.CEILING), BigDecimal.valueOf(123.5), "toScaledBigDecimal(String, int, RoudingMode) 1 failed");
349 assertEquals(NumberUtils.toScaledBigDecimal("23.5159", 3, RoundingMode.FLOOR), BigDecimal.valueOf(23.515), "toScaledBigDecimal(String, int, RoudingMode) 2 failed");
350 assertEquals(NumberUtils.toScaledBigDecimal("23.525", 2, RoundingMode.HALF_UP), BigDecimal.valueOf(23.53), "toScaledBigDecimal(String, int, RoudingMode) 3 failed");
351 assertEquals("23521.0000", NumberUtils.toScaledBigDecimal("23.521", 4, RoundingMode.HALF_EVEN)
352 .multiply(BigDecimal.valueOf(1000))
353 .toString(), "toScaledBigDecimal(String, int, RoudingMode) 4 failed");
354 assertEquals(NumberUtils.toScaledBigDecimal((String) null, 2, RoundingMode.HALF_UP), BigDecimal.ZERO, "toScaledBigDecimal(String, int, RoudingMode) 5 failed");
355 }
356
357 @Test
358 public void testCreateNumber() {
359 // a lot of things can go wrong
360 assertEquals(Float.valueOf("1234.5"), NumberUtils.createNumber("1234.5"), "createNumber(String) 1 failed");
361 assertEquals(Integer.valueOf("12345"), NumberUtils.createNumber("12345"), "createNumber(String) 2 failed");
362 assertEquals(Double.valueOf("1234.5"), NumberUtils.createNumber("1234.5D"), "createNumber(String) 3 failed");
363 assertEquals(Double.valueOf("1234.5"), NumberUtils.createNumber("1234.5d"), "createNumber(String) 3 failed");
364 assertEquals(Float.valueOf("1234.5"), NumberUtils.createNumber("1234.5F"), "createNumber(String) 4 failed");
365 assertEquals(Float.valueOf("1234.5"), NumberUtils.createNumber("1234.5f"), "createNumber(String) 4 failed");
366 assertEquals(Long.valueOf(Integer.MAX_VALUE + 1L), NumberUtils.createNumber(""
367 + (Integer.MAX_VALUE + 1L)), "createNumber(String) 5 failed");
368 assertEquals(Long.valueOf(12345), NumberUtils.createNumber("12345L"), "createNumber(String) 6 failed");
369 assertEquals(Long.valueOf(12345), NumberUtils.createNumber("12345l"), "createNumber(String) 6 failed");
370 assertEquals(Float.valueOf("-1234.5"), NumberUtils.createNumber("-1234.5"), "createNumber(String) 7 failed");
371 assertEquals(Integer.valueOf("-12345"), NumberUtils.createNumber("-12345"), "createNumber(String) 8 failed");
372 assertEquals(0xFADE, NumberUtils.createNumber("0xFADE").intValue(), "createNumber(String) 9a failed");
373 assertEquals(0xFADE, NumberUtils.createNumber("0Xfade").intValue(), "createNumber(String) 9b failed");
374 assertEquals(-0xFADE, NumberUtils.createNumber("-0xFADE").intValue(), "createNumber(String) 10a failed");
375 assertEquals(-0xFADE, NumberUtils.createNumber("-0Xfade").intValue(), "createNumber(String) 10b failed");
376 assertEquals(Double.valueOf("1.1E200"), NumberUtils.createNumber("1.1E200"), "createNumber(String) 11 failed");
377 assertEquals(Float.valueOf("1.1E20"), NumberUtils.createNumber("1.1E20"), "createNumber(String) 12 failed");
378 assertEquals(Double.valueOf("-1.1E200"), NumberUtils.createNumber("-1.1E200"), "createNumber(String) 13 failed");
379 assertEquals(Double.valueOf("1.1E-200"), NumberUtils.createNumber("1.1E-200"), "createNumber(String) 14 failed");
380 assertNull(NumberUtils.createNumber(null), "createNumber(null) failed");
381 assertEquals(new BigInteger("12345678901234567890"), NumberUtils.createNumber("12345678901234567890L"), "createNumber(String) failed");
382
383 assertEquals(new BigDecimal("1.1E-700"), NumberUtils.createNumber("1.1E-700F"), "createNumber(String) 15 failed");
384
385 assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), NumberUtils.createNumber("10" + Integer.MAX_VALUE + "L"), "createNumber(String) 16 failed");
386 assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), NumberUtils.createNumber("10" + Integer.MAX_VALUE), "createNumber(String) 17 failed");
387 assertEquals(new BigInteger("10" + Long.MAX_VALUE), NumberUtils.createNumber("10" + Long.MAX_VALUE), "createNumber(String) 18 failed");
388
389 // LANG-521
390 assertEquals(Float.valueOf("2."), NumberUtils.createNumber("2."), "createNumber(String) LANG-521 failed");
391
392 // LANG-638
393 assertFalse(checkCreateNumber("1eE"), "createNumber(String) succeeded");
394
395 // LANG-693
396 assertEquals(Double.valueOf(Double.MAX_VALUE), NumberUtils.createNumber("" + Double.MAX_VALUE), "createNumber(String) LANG-693 failed");
397
398 // LANG-822
399 // ensure that the underlying negative number would create a BigDecimal
400 final Number bigNum = NumberUtils.createNumber("-1.1E-700F");
401 assertNotNull(bigNum);
402 assertEquals(BigDecimal.class, bigNum.getClass());
403
404 // LANG-1018
405 assertEquals(Double.valueOf("-160952.54"), NumberUtils.createNumber("-160952.54"),
406 "createNumber(String) LANG-1018 failed");
407 // LANG-1187
408 assertEquals(Double.valueOf("6264583.33"), NumberUtils.createNumber("6264583.33"),
409 "createNumber(String) LANG-1187 failed");
410 // LANG-1215
411 assertEquals(Double.valueOf("193343.82"), NumberUtils.createNumber("193343.82"),
412 "createNumber(String) LANG-1215 failed");
413 // LANG-1060
414 assertEquals(Double.valueOf("001234.5678"), NumberUtils.createNumber("001234.5678"), "createNumber(String) LANG-1060a failed");
415 assertEquals(Double.valueOf("+001234.5678"), NumberUtils.createNumber("+001234.5678"), "createNumber(String) LANG-1060b failed");
416 assertEquals(Double.valueOf("-001234.5678"), NumberUtils.createNumber("-001234.5678"), "createNumber(String) LANG-1060c failed");
417 assertEquals(Double.valueOf("0000.00000"), NumberUtils.createNumber("0000.00000d"), "createNumber(String) LANG-1060d failed");
418 assertEquals(Float.valueOf("001234.56"), NumberUtils.createNumber("001234.56"), "createNumber(String) LANG-1060e failed");
419 assertEquals(Float.valueOf("+001234.56"), NumberUtils.createNumber("+001234.56"), "createNumber(String) LANG-1060f failed");
420 assertEquals(Float.valueOf("-001234.56"), NumberUtils.createNumber("-001234.56"), "createNumber(String) LANG-1060g failed");
421 assertEquals(Float.valueOf("0000.10"), NumberUtils.createNumber("0000.10"), "createNumber(String) LANG-1060h failed");
422 assertEquals(Float.valueOf("001.1E20"), NumberUtils.createNumber("001.1E20"), "createNumber(String) LANG-1060i failed");
423 assertEquals(Float.valueOf("+001.1E20"), NumberUtils.createNumber("+001.1E20"), "createNumber(String) LANG-1060j failed");
424 assertEquals(Float.valueOf("-001.1E20"), NumberUtils.createNumber("-001.1E20"), "createNumber(String) LANG-1060k failed");
425 assertEquals(Double.valueOf("001.1E200"), NumberUtils.createNumber("001.1E200"), "createNumber(String) LANG-1060l failed");
426 assertEquals(Double.valueOf("+001.1E200"), NumberUtils.createNumber("+001.1E200"), "createNumber(String) LANG-1060m failed");
427 assertEquals(Double.valueOf("-001.1E200"), NumberUtils.createNumber("-001.1E200"), "createNumber(String) LANG-1060n failed");
428 }
429
430 @Test
431 public void testLang1087() {
432 // no sign cases
433 assertEquals(Float.class, NumberUtils.createNumber("0.0").getClass());
434 assertEquals(Float.valueOf("0.0"), NumberUtils.createNumber("0.0"));
435 // explicit positive sign cases
436 assertEquals(Float.class, NumberUtils.createNumber("+0.0").getClass());
437 assertEquals(Float.valueOf("+0.0"), NumberUtils.createNumber("+0.0"));
438 // negative sign cases
439 assertEquals(Float.class, NumberUtils.createNumber("-0.0").getClass());
440 assertEquals(Float.valueOf("-0.0"), NumberUtils.createNumber("-0.0"));
441 }
442
443 @Test
444 public void TestLang747() {
445 assertEquals(Integer.valueOf(0x8000), NumberUtils.createNumber("0x8000"));
446 assertEquals(Integer.valueOf(0x80000), NumberUtils.createNumber("0x80000"));
447 assertEquals(Integer.valueOf(0x800000), NumberUtils.createNumber("0x800000"));
448 assertEquals(Integer.valueOf(0x8000000), NumberUtils.createNumber("0x8000000"));
449 assertEquals(Integer.valueOf(0x7FFFFFFF), NumberUtils.createNumber("0x7FFFFFFF"));
450 assertEquals(Long.valueOf(0x80000000L), NumberUtils.createNumber("0x80000000"));
451 assertEquals(Long.valueOf(0xFFFFFFFFL), NumberUtils.createNumber("0xFFFFFFFF"));
452
453 // Leading zero tests
454 assertEquals(Integer.valueOf(0x8000000), NumberUtils.createNumber("0x08000000"));
455 assertEquals(Integer.valueOf(0x7FFFFFFF), NumberUtils.createNumber("0x007FFFFFFF"));
456 assertEquals(Long.valueOf(0x80000000L), NumberUtils.createNumber("0x080000000"));
457 assertEquals(Long.valueOf(0xFFFFFFFFL), NumberUtils.createNumber("0x00FFFFFFFF"));
458
459 assertEquals(Long.valueOf(0x800000000L), NumberUtils.createNumber("0x800000000"));
460 assertEquals(Long.valueOf(0x8000000000L), NumberUtils.createNumber("0x8000000000"));
461 assertEquals(Long.valueOf(0x80000000000L), NumberUtils.createNumber("0x80000000000"));
462 assertEquals(Long.valueOf(0x800000000000L), NumberUtils.createNumber("0x800000000000"));
463 assertEquals(Long.valueOf(0x8000000000000L), NumberUtils.createNumber("0x8000000000000"));
464 assertEquals(Long.valueOf(0x80000000000000L), NumberUtils.createNumber("0x80000000000000"));
465 assertEquals(Long.valueOf(0x800000000000000L), NumberUtils.createNumber("0x800000000000000"));
466 assertEquals(Long.valueOf(0x7FFFFFFFFFFFFFFFL), NumberUtils.createNumber("0x7FFFFFFFFFFFFFFF"));
467 // N.B. Cannot use a hex constant such as 0x8000000000000000L here as that is interpreted as a negative long
468 assertEquals(new BigInteger("8000000000000000", 16), NumberUtils.createNumber("0x8000000000000000"));
469 assertEquals(new BigInteger("FFFFFFFFFFFFFFFF", 16), NumberUtils.createNumber("0xFFFFFFFFFFFFFFFF"));
470
471 // Leading zero tests
472 assertEquals(Long.valueOf(0x80000000000000L), NumberUtils.createNumber("0x00080000000000000"));
473 assertEquals(Long.valueOf(0x800000000000000L), NumberUtils.createNumber("0x0800000000000000"));
474 assertEquals(Long.valueOf(0x7FFFFFFFFFFFFFFFL), NumberUtils.createNumber("0x07FFFFFFFFFFFFFFF"));
475 // N.B. Cannot use a hex constant such as 0x8000000000000000L here as that is interpreted as a negative long
476 assertEquals(new BigInteger("8000000000000000", 16), NumberUtils.createNumber("0x00008000000000000000"));
477 assertEquals(new BigInteger("FFFFFFFFFFFFFFFF", 16), NumberUtils.createNumber("0x0FFFFFFFFFFFFFFFF"));
478 }
479
480 @Test
481 // Check that the code fails to create a valid number when preceded by -- rather than -
482 public void testCreateNumberFailure_1() {
483 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("--1.1E-700F"));
484 }
485
486 @Test
487 // Check that the code fails to create a valid number when both e and E are present (with decimal)
488 public void testCreateNumberFailure_2() {
489 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("-1.1E+0-7e00"));
490 }
491
492 @Test
493 // Check that the code fails to create a valid number when both e and E are present (no decimal)
494 public void testCreateNumberFailure_3() {
495 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("-11E+0-7e00"));
496 }
497
498 @Test
499 // Check that the code fails to create a valid number when both e and E are present (no decimal)
500 public void testCreateNumberFailure_4() {
501 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("1eE+00001"));
502 }
503
504 @Test
505 // Check that the code fails to create a valid number when there are multiple trailing 'f' characters (LANG-1205)
506 public void testCreateNumberFailure_5() {
507 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("1234.5ff"));
508 }
509
510 @Test
511 // Check that the code fails to create a valid number when there are multiple trailing 'F' characters (LANG-1205)
512 public void testCreateNumberFailure_6() {
513 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("1234.5FF"));
514 }
515
516 @Test
517 // Check that the code fails to create a valid number when there are multiple trailing 'd' characters (LANG-1205)
518 public void testCreateNumberFailure_7() {
519 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("1234.5dd"));
520 }
521
522 @Test
523 // Check that the code fails to create a valid number when there are multiple trailing 'D' characters (LANG-1205)
524 public void testCreateNumberFailure_8() {
525 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("1234.5DD"));
526 }
527
528 // Tests to show when magnitude causes switch to next Number type
529 // Will probably need to be adjusted if code is changed to check precision (LANG-693)
530 @Test
531 public void testCreateNumberMagnitude() {
532 // Test Float.MAX_VALUE, and same with +1 in final digit to check conversion changes to next Number type
533 assertEquals(Float.valueOf(Float.MAX_VALUE), NumberUtils.createNumber("3.4028235e+38"));
534 assertEquals(Double.valueOf(3.4028236e+38), NumberUtils.createNumber("3.4028236e+38"));
535
536 // Test Double.MAX_VALUE
537 assertEquals(Double.valueOf(Double.MAX_VALUE), NumberUtils.createNumber("1.7976931348623157e+308"));
538 // Test with +2 in final digit (+1 does not cause roll-over to BigDecimal)
539 assertEquals(new BigDecimal("1.7976931348623159e+308"), NumberUtils.createNumber("1.7976931348623159e+308"));
540
541 assertEquals(Integer.valueOf(0x12345678), NumberUtils.createNumber("0x12345678"));
542 assertEquals(Long.valueOf(0x123456789L), NumberUtils.createNumber("0x123456789"));
543
544 assertEquals(Long.valueOf(0x7fffffffffffffffL), NumberUtils.createNumber("0x7fffffffffffffff"));
545 // Does not appear to be a way to create a literal BigInteger of this magnitude
546 assertEquals(new BigInteger("7fffffffffffffff0", 16), NumberUtils.createNumber("0x7fffffffffffffff0"));
547
548 assertEquals(Long.valueOf(0x7fffffffffffffffL), NumberUtils.createNumber("#7fffffffffffffff"));
549 assertEquals(new BigInteger("7fffffffffffffff0", 16), NumberUtils.createNumber("#7fffffffffffffff0"));
550
551 assertEquals(Integer.valueOf(017777777777), NumberUtils.createNumber("017777777777")); // 31 bits
552 assertEquals(Long.valueOf(037777777777L), NumberUtils.createNumber("037777777777")); // 32 bits
553
554 assertEquals(Long.valueOf(0777777777777777777777L), NumberUtils.createNumber("0777777777777777777777")); // 63 bits
555 assertEquals(new BigInteger("1777777777777777777777", 8), NumberUtils.createNumber("01777777777777777777777")); // 64 bits
556 }
557
558 @Test
559 public void testCreateFloat() {
560 assertEquals(Float.valueOf("1234.5"), NumberUtils.createFloat("1234.5"), "createFloat(String) failed");
561 assertNull(NumberUtils.createFloat(null), "createFloat(null) failed");
562 this.testCreateFloatFailure("");
563 this.testCreateFloatFailure(" ");
564 this.testCreateFloatFailure("\b\t\n\f\r");
349 @Test
350 public void testCreateBigDecimal() {
351 assertEquals(new BigDecimal("1234.5"), NumberUtils.createBigDecimal("1234.5"),
352 "createBigDecimal(String) failed");
353 assertNull(NumberUtils.createBigDecimal(null), "createBigDecimal(null) failed");
354 this.testCreateBigDecimalFailure("");
355 this.testCreateBigDecimalFailure(" ");
356 this.testCreateBigDecimalFailure("\b\t\n\f\r");
565357 // Funky whitespaces
566 this.testCreateFloatFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F");
567 }
568
569 protected void testCreateFloatFailure(final String str) {
570 assertThrows(
571 NumberFormatException.class,
572 () -> NumberUtils.createFloat(str), "createFloat(\"" + str + "\") should have failed.");
573 }
574
575 @Test
576 public void testCreateDouble() {
577 assertEquals(Double.valueOf("1234.5"), NumberUtils.createDouble("1234.5"), "createDouble(String) failed");
578 assertNull(NumberUtils.createDouble(null), "createDouble(null) failed");
579 this.testCreateDoubleFailure("");
580 this.testCreateDoubleFailure(" ");
581 this.testCreateDoubleFailure("\b\t\n\f\r");
582 // Funky whitespaces
583 this.testCreateDoubleFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F");
584 }
585
586 protected void testCreateDoubleFailure(final String str) {
587 assertThrows(
588 NumberFormatException.class,
589 () -> NumberUtils.createDouble(str),
590 "createDouble(\"" + str + "\") should have failed.");
591 }
592
593 @Test
594 public void testCreateInteger() {
595 assertEquals(Integer.valueOf("12345"), NumberUtils.createInteger("12345"), "createInteger(String) failed");
596 assertNull(NumberUtils.createInteger(null), "createInteger(null) failed");
597 this.testCreateIntegerFailure("");
598 this.testCreateIntegerFailure(" ");
599 this.testCreateIntegerFailure("\b\t\n\f\r");
600 // Funky whitespaces
601 this.testCreateIntegerFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F");
602 }
603
604 protected void testCreateIntegerFailure(final String str) {
605 assertThrows(
606 NumberFormatException.class,
607 () -> NumberUtils.createInteger(str),
608 "createInteger(\"" + str + "\") should have failed.");
609 }
610
611 @Test
612 public void testCreateLong() {
613 assertEquals(Long.valueOf("12345"), NumberUtils.createLong("12345"), "createLong(String) failed");
614 assertNull(NumberUtils.createLong(null), "createLong(null) failed");
615 this.testCreateLongFailure("");
616 this.testCreateLongFailure(" ");
617 this.testCreateLongFailure("\b\t\n\f\r");
618 // Funky whitespaces
619 this.testCreateLongFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F");
620 }
621
622 protected void testCreateLongFailure(final String str) {
623 assertThrows(
624 NumberFormatException.class,
625 () -> NumberUtils.createLong(str),
626 "createLong(\"" + str + "\") should have failed.");
358 this.testCreateBigDecimalFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F");
359 // sign alone not valid
360 this.testCreateBigDecimalFailure("-");
361 // comment in NumberUtils suggests some implementations may incorrectly allow this
362 this.testCreateBigDecimalFailure("--");
363 this.testCreateBigDecimalFailure("--0");
364 // sign alone not valid
365 this.testCreateBigDecimalFailure("+");
366 // in case this was also allowed by some JVMs
367 this.testCreateBigDecimalFailure("++");
368 this.testCreateBigDecimalFailure("++0");
369 }
370
371 protected void testCreateBigDecimalFailure(final String str) {
372 assertThrows(NumberFormatException.class, () -> NumberUtils.createBigDecimal(str),
373 "createBigDecimal(\"" + str + "\") should have failed.");
627374 }
628375
629376 @Test
651398 }
652399
653400 protected void testCreateBigIntegerFailure(final String str) {
654 assertThrows(
655 NumberFormatException.class,
656 () -> NumberUtils.createBigInteger(str),
657 "createBigInteger(\"" + str + "\") should have failed.");
658 }
659
660 @Test
661 public void testCreateBigDecimal() {
662 assertEquals(new BigDecimal("1234.5"), NumberUtils.createBigDecimal("1234.5"), "createBigDecimal(String) failed");
663 assertNull(NumberUtils.createBigDecimal(null), "createBigDecimal(null) failed");
664 this.testCreateBigDecimalFailure("");
665 this.testCreateBigDecimalFailure(" ");
666 this.testCreateBigDecimalFailure("\b\t\n\f\r");
401 assertThrows(NumberFormatException.class, () -> NumberUtils.createBigInteger(str),
402 "createBigInteger(\"" + str + "\") should have failed.");
403 }
404
405 @Test
406 public void testCreateDouble() {
407 assertEquals(Double.valueOf("1234.5"), NumberUtils.createDouble("1234.5"), "createDouble(String) failed");
408 assertNull(NumberUtils.createDouble(null), "createDouble(null) failed");
409 this.testCreateDoubleFailure("");
410 this.testCreateDoubleFailure(" ");
411 this.testCreateDoubleFailure("\b\t\n\f\r");
667412 // Funky whitespaces
668 this.testCreateBigDecimalFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F");
669 this.testCreateBigDecimalFailure("-"); // sign alone not valid
670 this.testCreateBigDecimalFailure("--"); // comment in NumberUtils suggests some implementations may incorrectly allow this
671 this.testCreateBigDecimalFailure("--0");
672 this.testCreateBigDecimalFailure("+"); // sign alone not valid
673 this.testCreateBigDecimalFailure("++"); // in case this was also allowed by some JVMs
674 this.testCreateBigDecimalFailure("++0");
675 }
676
677 protected void testCreateBigDecimalFailure(final String str) {
678 assertThrows(
679 NumberFormatException.class,
680 () -> NumberUtils.createBigDecimal(str),
681 "createBigDecimal(\"" + str + "\") should have failed.");
682 }
683
684 // min/max tests
685 // ----------------------------------------------------------------------
686 @Test
687 public void testMinLong_nullArray() {
688 assertThrows(NullPointerException.class, () -> NumberUtils.min((long[]) null));
689 }
690
691 @Test
692 public void testMinLong_emptyArray() {
693 assertThrows(IllegalArgumentException.class, NumberUtils::min);
694 }
695
696 @Test
697 public void testMinLong() {
698 assertEquals(5, NumberUtils.min(5), "min(long[]) failed for array length 1");
699 assertEquals(6, NumberUtils.min(6, 9), "min(long[]) failed for array length 2");
700
701 assertEquals(-10, NumberUtils.min(-10, -5, 0, 5, 10));
702 assertEquals(-10, NumberUtils.min(-5, 0, -10, 5, 10));
703 }
704
705 @Test
706 public void testMinInt_nullArray() {
707 assertThrows(NullPointerException.class, () -> NumberUtils.min((int[]) null));
708 }
709
710 @Test
711 public void testMinInt_emptyArray() {
712 assertThrows(IllegalArgumentException.class, NumberUtils::min);
713 }
714
715 @Test
716 public void testMinInt() {
717 assertEquals(5, NumberUtils.min(5), "min(int[]) failed for array length 1");
718 assertEquals(6, NumberUtils.min(6, 9), "min(int[]) failed for array length 2");
719
720 assertEquals(-10, NumberUtils.min(-10, -5, 0, 5, 10));
721 assertEquals(-10, NumberUtils.min(-5, 0, -10, 5, 10));
722 }
723
724 @Test
725 public void testMinShort_nullArray() {
726 assertThrows(NullPointerException.class, () -> NumberUtils.min((short[]) null));
727 }
728
729 @Test
730 public void testMinShort_emptyArray() {
731 assertThrows(IllegalArgumentException.class, NumberUtils::min);
732 }
733
734 @Test
735 public void testMinShort() {
736 assertEquals(5, NumberUtils.min(5), "min(short[]) failed for array length 1");
737 assertEquals(6, NumberUtils.min(6, 9), "min(short[]) failed for array length 2");
738
739 assertEquals(-10, NumberUtils.min(-10, -5, 0, 5, 10));
740 assertEquals(-10, NumberUtils.min(-5, 0, -10, 5, 10));
741 }
742
743 @Test
744 public void testMinByte_nullArray() {
745 assertThrows(NullPointerException.class, () -> NumberUtils.min((byte[]) null));
746 }
747
748 @Test
749 public void testMinByte_emptyArray() {
750 assertThrows(IllegalArgumentException.class, NumberUtils::min);
751 }
752
753 @Test
754 public void testMinByte() {
755 assertEquals(5, NumberUtils.min(5), "min(byte[]) failed for array length 1");
756 assertEquals(6, NumberUtils.min(6, 9), "min(byte[]) failed for array length 2");
757
758 assertEquals(-10, NumberUtils.min(-10, -5, 0, 5, 10));
759 assertEquals(-10, NumberUtils.min(-5, 0, -10, 5, 10));
760 }
761
762 @Test
763 public void testMinDouble_nullArray() {
764 assertThrows(NullPointerException.class, () -> NumberUtils.min((double[]) null));
765 }
766
767 @Test
768 public void testMinDouble_emptyArray() {
769 assertThrows(IllegalArgumentException.class, NumberUtils::min);
770 }
771
772 @Test
773 public void testMinDouble() {
774 assertEquals(5.12, NumberUtils.min(5.12), "min(double[]) failed for array length 1");
775 assertEquals(6.23, NumberUtils.min(6.23, 9.34), "min(double[]) failed for array length 2");
776 assertEquals(-10.45, NumberUtils.min(-10.45, -5.56, 0, 5.67, 10.78), "min(double[]) failed for array length 5");
777 assertEquals(-10, NumberUtils.min(-10, -5, 0, 5, 10), 0.0001);
778 assertEquals(-10, NumberUtils.min(-5, 0, -10, 5, 10), 0.0001);
779 }
780
781 @Test
782 public void testMinFloat_nullArray() {
783 assertThrows(NullPointerException.class, () -> NumberUtils.min((float[]) null));
784 }
785
786 @Test
787 public void testMinFloat_emptyArray() {
788 assertThrows(IllegalArgumentException.class, NumberUtils::min);
789 }
790
791 @Test
792 public void testMinFloat() {
793 assertEquals(5.9f, NumberUtils.min(5.9f), "min(float[]) failed for array length 1");
794 assertEquals(6.8f, NumberUtils.min(6.8f, 9.7f), "min(float[]) failed for array length 2");
795 assertEquals(-10.6f, NumberUtils.min(-10.6f, -5.5f, 0, 5.4f, 10.3f), "min(float[]) failed for array length 5");
796 assertEquals(-10, NumberUtils.min(-10, -5, 0, 5, 10), 0.0001f);
797 assertEquals(-10, NumberUtils.min(-5, 0, -10, 5, 10), 0.0001f);
798 }
799
800 @Test
801 public void testMaxLong_nullArray() {
802 assertThrows(NullPointerException.class, () -> NumberUtils.max((long[]) null));
803 }
804
805 @Test
806 public void testMaxLong_emptyArray() {
807 assertThrows(IllegalArgumentException.class, NumberUtils::max);
808 }
809
810 @Test
811 public void testMaxLong() {
812 assertEquals(5, NumberUtils.max(5), "max(long[]) failed for array length 1");
813 assertEquals(9, NumberUtils.max(6, 9), "max(long[]) failed for array length 2");
814 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10), "max(long[]) failed for array length 5");
815 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10));
816 assertEquals(10, NumberUtils.max(-5, 0, 10, 5, -10));
817 }
818
819 @Test
820 public void testMaxInt_nullArray() {
821 assertThrows(NullPointerException.class, () -> NumberUtils.max((int[]) null));
822 }
823
824 @Test
825 public void testMaxInt_emptyArray() {
826 assertThrows(IllegalArgumentException.class, NumberUtils::max);
827 }
828
829 @Test
830 public void testMaxInt() {
831 assertEquals(5, NumberUtils.max(5), "max(int[]) failed for array length 1");
832 assertEquals(9, NumberUtils.max(6, 9), "max(int[]) failed for array length 2");
833 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10), "max(int[]) failed for array length 5");
834 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10));
835 assertEquals(10, NumberUtils.max(-5, 0, 10, 5, -10));
836 }
837
838 @Test
839 public void testMaxShort_nullArray() {
840 assertThrows(NullPointerException.class, () -> NumberUtils.max((short[]) null));
841 }
842
843 @Test
844 public void testMaxShort_emptyArray() {
845 assertThrows(IllegalArgumentException.class, NumberUtils::max);
846 }
847
848 @Test
849 public void testMaxShort() {
850 assertEquals(5, NumberUtils.max(5), "max(short[]) failed for array length 1");
851 assertEquals(9, NumberUtils.max(6, 9), "max(short[]) failed for array length 2");
852 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10), "max(short[]) failed for array length 5");
853 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10));
854 assertEquals(10, NumberUtils.max(-5, 0, 10, 5, -10));
855 }
856
857 @Test
858 public void testMaxByte_nullArray() {
859 assertThrows(NullPointerException.class, () -> NumberUtils.max((byte[]) null));
860 }
861
862 @Test
863 public void testMaxByte_emptyArray() {
864 assertThrows(IllegalArgumentException.class, NumberUtils::max);
865 }
866
867 @Test
868 public void testMaxByte() {
869 assertEquals(5, NumberUtils.max(5), "max(byte[]) failed for array length 1");
870 assertEquals(9, NumberUtils.max(6, 9), "max(byte[]) failed for array length 2");
871 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10), "max(byte[]) failed for array length 5");
872 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10));
873 assertEquals(10, NumberUtils.max(-5, 0, 10, 5, -10));
874 }
875
876 @Test
877 public void testMaxDouble_nullArray() {
878 assertThrows(NullPointerException.class, () -> NumberUtils.max((double[]) null));
879 }
880
881 @Test
882 public void testMaxDouble_emptyArray() {
883 assertThrows(IllegalArgumentException.class, NumberUtils::max);
884 }
885
886 @Test
887 public void testMaxDouble() {
888 final double[] d = null;
889 assertThrows(
890 NullPointerException.class, () -> NumberUtils.max(d), "No exception was thrown for null input.");
891
892 assertThrows(
893 IllegalArgumentException.class,
894 NumberUtils::max,
895 "No exception was thrown for empty input.");
896
897 assertEquals(5.1f, NumberUtils.max(5.1f), "max(double[]) failed for array length 1");
898 assertEquals(9.2f, NumberUtils.max(6.3f, 9.2f), "max(double[]) failed for array length 2");
899 assertEquals(10.4f, NumberUtils.max(-10.5f, -5.6f, 0, 5.7f, 10.4f), "max(double[]) failed for float length 5");
900 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10), 0.0001);
901 assertEquals(10, NumberUtils.max(-5, 0, 10, 5, -10), 0.0001);
902 }
903
904 @Test
905 public void testMaxFloat_nullArray() {
906 assertThrows(NullPointerException.class, () -> NumberUtils.max((float[]) null));
907 }
908
909 @Test
910 public void testMaxFloat_emptyArray() {
911 assertThrows(IllegalArgumentException.class, NumberUtils::max);
912 }
913
914 @Test
915 public void testMaxFloat() {
916 assertEquals(5.1f, NumberUtils.max(5.1f), "max(float[]) failed for array length 1");
917 assertEquals(9.2f, NumberUtils.max(6.3f, 9.2f), "max(float[]) failed for array length 2");
918 assertEquals(10.4f, NumberUtils.max(-10.5f, -5.6f, 0, 5.7f, 10.4f), "max(float[]) failed for float length 5");
919 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10), 0.0001f);
920 assertEquals(10, NumberUtils.max(-5, 0, 10, 5, -10), 0.0001f);
921 }
922
923 @Test
924 public void testMinimumLong() {
925 assertEquals(12345L, NumberUtils.min(12345L, 12345L + 1L, 12345L + 2L), "minimum(long, long, long) 1 failed");
926 assertEquals(12345L, NumberUtils.min(12345L + 1L, 12345L, 12345 + 2L), "minimum(long, long, long) 2 failed");
927 assertEquals(12345L, NumberUtils.min(12345L + 1L, 12345L + 2L, 12345L), "minimum(long, long, long) 3 failed");
928 assertEquals(12345L, NumberUtils.min(12345L + 1L, 12345L, 12345L), "minimum(long, long, long) 4 failed");
929 assertEquals(12345L, NumberUtils.min(12345L, 12345L, 12345L), "minimum(long, long, long) 5 failed");
930 }
931
932 @Test
933 public void testMinimumInt() {
934 assertEquals(12345, NumberUtils.min(12345, 12345 + 1, 12345 + 2), "minimum(int, int, int) 1 failed");
935 assertEquals(12345, NumberUtils.min(12345 + 1, 12345, 12345 + 2), "minimum(int, int, int) 2 failed");
936 assertEquals(12345, NumberUtils.min(12345 + 1, 12345 + 2, 12345), "minimum(int, int, int) 3 failed");
937 assertEquals(12345, NumberUtils.min(12345 + 1, 12345, 12345), "minimum(int, int, int) 4 failed");
938 assertEquals(12345, NumberUtils.min(12345, 12345, 12345), "minimum(int, int, int) 5 failed");
939 }
940
941 @Test
942 public void testMinimumShort() {
943 final short low = 1234;
944 final short mid = 1234 + 1;
945 final short high = 1234 + 2;
946 assertEquals(low, NumberUtils.min(low, mid, high), "minimum(short, short, short) 1 failed");
947 assertEquals(low, NumberUtils.min(mid, low, high), "minimum(short, short, short) 2 failed");
948 assertEquals(low, NumberUtils.min(mid, high, low), "minimum(short, short, short) 3 failed");
949 assertEquals(low, NumberUtils.min(low, mid, low), "minimum(short, short, short) 4 failed");
950 }
951
952 @Test
953 public void testMinimumByte() {
954 final byte low = 123;
955 final byte mid = 123 + 1;
956 final byte high = 123 + 2;
957 assertEquals(low, NumberUtils.min(low, mid, high), "minimum(byte, byte, byte) 1 failed");
958 assertEquals(low, NumberUtils.min(mid, low, high), "minimum(byte, byte, byte) 2 failed");
959 assertEquals(low, NumberUtils.min(mid, high, low), "minimum(byte, byte, byte) 3 failed");
960 assertEquals(low, NumberUtils.min(low, mid, low), "minimum(byte, byte, byte) 4 failed");
961 }
962
963 @Test
964 public void testMinimumDouble() {
965 final double low = 12.3;
966 final double mid = 12.3 + 1;
967 final double high = 12.3 + 2;
968 assertEquals(low, NumberUtils.min(low, mid, high), 0.0001);
969 assertEquals(low, NumberUtils.min(mid, low, high), 0.0001);
970 assertEquals(low, NumberUtils.min(mid, high, low), 0.0001);
971 assertEquals(low, NumberUtils.min(low, mid, low), 0.0001);
972 assertEquals(mid, NumberUtils.min(high, mid, high), 0.0001);
973 }
974
975 @Test
976 public void testMinimumFloat() {
977 final float low = 12.3f;
978 final float mid = 12.3f + 1;
979 final float high = 12.3f + 2;
980 assertEquals(low, NumberUtils.min(low, mid, high), 0.0001f);
981 assertEquals(low, NumberUtils.min(mid, low, high), 0.0001f);
982 assertEquals(low, NumberUtils.min(mid, high, low), 0.0001f);
983 assertEquals(low, NumberUtils.min(low, mid, low), 0.0001f);
984 assertEquals(mid, NumberUtils.min(high, mid, high), 0.0001f);
985 }
986
987 @Test
988 public void testMaximumLong() {
989 assertEquals(12345L, NumberUtils.max(12345L, 12345L - 1L, 12345L - 2L), "maximum(long, long, long) 1 failed");
990 assertEquals(12345L, NumberUtils.max(12345L - 1L, 12345L, 12345L - 2L), "maximum(long, long, long) 2 failed");
991 assertEquals(12345L, NumberUtils.max(12345L - 1L, 12345L - 2L, 12345L), "maximum(long, long, long) 3 failed");
992 assertEquals(12345L, NumberUtils.max(12345L - 1L, 12345L, 12345L), "maximum(long, long, long) 4 failed");
993 assertEquals(12345L, NumberUtils.max(12345L, 12345L, 12345L), "maximum(long, long, long) 5 failed");
994 }
995
996 @Test
997 public void testMaximumInt() {
998 assertEquals(12345, NumberUtils.max(12345, 12345 - 1, 12345 - 2), "maximum(int, int, int) 1 failed");
999 assertEquals(12345, NumberUtils.max(12345 - 1, 12345, 12345 - 2), "maximum(int, int, int) 2 failed");
1000 assertEquals(12345, NumberUtils.max(12345 - 1, 12345 - 2, 12345), "maximum(int, int, int) 3 failed");
1001 assertEquals(12345, NumberUtils.max(12345 - 1, 12345, 12345), "maximum(int, int, int) 4 failed");
1002 assertEquals(12345, NumberUtils.max(12345, 12345, 12345), "maximum(int, int, int) 5 failed");
1003 }
1004
1005 @Test
1006 public void testMaximumShort() {
1007 final short low = 1234;
1008 final short mid = 1234 + 1;
1009 final short high = 1234 + 2;
1010 assertEquals(high, NumberUtils.max(low, mid, high), "maximum(short, short, short) 1 failed");
1011 assertEquals(high, NumberUtils.max(mid, low, high), "maximum(short, short, short) 2 failed");
1012 assertEquals(high, NumberUtils.max(mid, high, low), "maximum(short, short, short) 3 failed");
1013 assertEquals(high, NumberUtils.max(high, mid, high), "maximum(short, short, short) 4 failed");
1014 }
1015
1016 @Test
1017 public void testMaximumByte() {
1018 final byte low = 123;
1019 final byte mid = 123 + 1;
1020 final byte high = 123 + 2;
1021 assertEquals(high, NumberUtils.max(low, mid, high), "maximum(byte, byte, byte) 1 failed");
1022 assertEquals(high, NumberUtils.max(mid, low, high), "maximum(byte, byte, byte) 2 failed");
1023 assertEquals(high, NumberUtils.max(mid, high, low), "maximum(byte, byte, byte) 3 failed");
1024 assertEquals(high, NumberUtils.max(high, mid, high), "maximum(byte, byte, byte) 4 failed");
1025 }
1026
1027 @Test
1028 public void testMaximumDouble() {
1029 final double low = 12.3;
1030 final double mid = 12.3 + 1;
1031 final double high = 12.3 + 2;
1032 assertEquals(high, NumberUtils.max(low, mid, high), 0.0001);
1033 assertEquals(high, NumberUtils.max(mid, low, high), 0.0001);
1034 assertEquals(high, NumberUtils.max(mid, high, low), 0.0001);
1035 assertEquals(mid, NumberUtils.max(low, mid, low), 0.0001);
1036 assertEquals(high, NumberUtils.max(high, mid, high), 0.0001);
1037 }
1038
1039 @Test
1040 public void testMaximumFloat() {
1041 final float low = 12.3f;
1042 final float mid = 12.3f + 1;
1043 final float high = 12.3f + 2;
1044 assertEquals(high, NumberUtils.max(low, mid, high), 0.0001f);
1045 assertEquals(high, NumberUtils.max(mid, low, high), 0.0001f);
1046 assertEquals(high, NumberUtils.max(mid, high, low), 0.0001f);
1047 assertEquals(mid, NumberUtils.max(low, mid, low), 0.0001f);
1048 assertEquals(high, NumberUtils.max(high, mid, high), 0.0001f);
1049 }
1050
1051 // Testing JDK against old Lang functionality
1052 @Test
1053 public void testCompareDouble() {
1054 assertEquals(0, Double.compare(Double.NaN, Double.NaN));
1055 assertEquals(Double.compare(Double.NaN, Double.POSITIVE_INFINITY), +1);
1056 assertEquals(Double.compare(Double.NaN, Double.MAX_VALUE), +1);
1057 assertEquals(Double.compare(Double.NaN, 1.2d), +1);
1058 assertEquals(Double.compare(Double.NaN, 0.0d), +1);
1059 assertEquals(Double.compare(Double.NaN, -0.0d), +1);
1060 assertEquals(Double.compare(Double.NaN, -1.2d), +1);
1061 assertEquals(Double.compare(Double.NaN, -Double.MAX_VALUE), +1);
1062 assertEquals(Double.compare(Double.NaN, Double.NEGATIVE_INFINITY), +1);
1063
1064 assertEquals(Double.compare(Double.POSITIVE_INFINITY, Double.NaN), -1);
1065 assertEquals(0, Double.compare(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
1066 assertEquals(Double.compare(Double.POSITIVE_INFINITY, Double.MAX_VALUE), +1);
1067 assertEquals(Double.compare(Double.POSITIVE_INFINITY, 1.2d), +1);
1068 assertEquals(Double.compare(Double.POSITIVE_INFINITY, 0.0d), +1);
1069 assertEquals(Double.compare(Double.POSITIVE_INFINITY, -0.0d), +1);
1070 assertEquals(Double.compare(Double.POSITIVE_INFINITY, -1.2d), +1);
1071 assertEquals(Double.compare(Double.POSITIVE_INFINITY, -Double.MAX_VALUE), +1);
1072 assertEquals(Double.compare(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY), +1);
1073
1074 assertEquals(Double.compare(Double.MAX_VALUE, Double.NaN), -1);
1075 assertEquals(Double.compare(Double.MAX_VALUE, Double.POSITIVE_INFINITY), -1);
1076 assertEquals(0, Double.compare(Double.MAX_VALUE, Double.MAX_VALUE));
1077 assertEquals(Double.compare(Double.MAX_VALUE, 1.2d), +1);
1078 assertEquals(Double.compare(Double.MAX_VALUE, 0.0d), +1);
1079 assertEquals(Double.compare(Double.MAX_VALUE, -0.0d), +1);
1080 assertEquals(Double.compare(Double.MAX_VALUE, -1.2d), +1);
1081 assertEquals(Double.compare(Double.MAX_VALUE, -Double.MAX_VALUE), +1);
1082 assertEquals(Double.compare(Double.MAX_VALUE, Double.NEGATIVE_INFINITY), +1);
1083
1084 assertEquals(Double.compare(1.2d, Double.NaN), -1);
1085 assertEquals(Double.compare(1.2d, Double.POSITIVE_INFINITY), -1);
1086 assertEquals(Double.compare(1.2d, Double.MAX_VALUE), -1);
1087 assertEquals(0, Double.compare(1.2d, 1.2d));
1088 assertEquals(Double.compare(1.2d, 0.0d), +1);
1089 assertEquals(Double.compare(1.2d, -0.0d), +1);
1090 assertEquals(Double.compare(1.2d, -1.2d), +1);
1091 assertEquals(Double.compare(1.2d, -Double.MAX_VALUE), +1);
1092 assertEquals(Double.compare(1.2d, Double.NEGATIVE_INFINITY), +1);
1093
1094 assertEquals(Double.compare(0.0d, Double.NaN), -1);
1095 assertEquals(Double.compare(0.0d, Double.POSITIVE_INFINITY), -1);
1096 assertEquals(Double.compare(0.0d, Double.MAX_VALUE), -1);
1097 assertEquals(Double.compare(0.0d, 1.2d), -1);
1098 assertEquals(0, Double.compare(0.0d, 0.0d));
1099 assertEquals(Double.compare(0.0d, -0.0d), +1);
1100 assertEquals(Double.compare(0.0d, -1.2d), +1);
1101 assertEquals(Double.compare(0.0d, -Double.MAX_VALUE), +1);
1102 assertEquals(Double.compare(0.0d, Double.NEGATIVE_INFINITY), +1);
1103
1104 assertEquals(Double.compare(-0.0d, Double.NaN), -1);
1105 assertEquals(Double.compare(-0.0d, Double.POSITIVE_INFINITY), -1);
1106 assertEquals(Double.compare(-0.0d, Double.MAX_VALUE), -1);
1107 assertEquals(Double.compare(-0.0d, 1.2d), -1);
1108 assertEquals(Double.compare(-0.0d, 0.0d), -1);
1109 assertEquals(0, Double.compare(-0.0d, -0.0d));
1110 assertEquals(Double.compare(-0.0d, -1.2d), +1);
1111 assertEquals(Double.compare(-0.0d, -Double.MAX_VALUE), +1);
1112 assertEquals(Double.compare(-0.0d, Double.NEGATIVE_INFINITY), +1);
1113
1114 assertEquals(Double.compare(-1.2d, Double.NaN), -1);
1115 assertEquals(Double.compare(-1.2d, Double.POSITIVE_INFINITY), -1);
1116 assertEquals(Double.compare(-1.2d, Double.MAX_VALUE), -1);
1117 assertEquals(Double.compare(-1.2d, 1.2d), -1);
1118 assertEquals(Double.compare(-1.2d, 0.0d), -1);
1119 assertEquals(Double.compare(-1.2d, -0.0d), -1);
1120 assertEquals(0, Double.compare(-1.2d, -1.2d));
1121 assertEquals(Double.compare(-1.2d, -Double.MAX_VALUE), +1);
1122 assertEquals(Double.compare(-1.2d, Double.NEGATIVE_INFINITY), +1);
1123
1124 assertEquals(Double.compare(-Double.MAX_VALUE, Double.NaN), -1);
1125 assertEquals(Double.compare(-Double.MAX_VALUE, Double.POSITIVE_INFINITY), -1);
1126 assertEquals(Double.compare(-Double.MAX_VALUE, Double.MAX_VALUE), -1);
1127 assertEquals(Double.compare(-Double.MAX_VALUE, 1.2d), -1);
1128 assertEquals(Double.compare(-Double.MAX_VALUE, 0.0d), -1);
1129 assertEquals(Double.compare(-Double.MAX_VALUE, -0.0d), -1);
1130 assertEquals(Double.compare(-Double.MAX_VALUE, -1.2d), -1);
1131 assertEquals(0, Double.compare(-Double.MAX_VALUE, -Double.MAX_VALUE));
1132 assertEquals(Double.compare(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY), +1);
1133
1134 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, Double.NaN), -1);
1135 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY), -1);
1136 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, Double.MAX_VALUE), -1);
1137 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, 1.2d), -1);
1138 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, 0.0d), -1);
1139 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, -0.0d), -1);
1140 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, -1.2d), -1);
1141 assertEquals(Double.compare(Double.NEGATIVE_INFINITY, -Double.MAX_VALUE), -1);
1142 assertEquals(0, Double.compare(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
1143 }
1144
1145 @Test
1146 public void testCompareFloat() {
1147 assertEquals(0, Float.compare(Float.NaN, Float.NaN));
1148 assertEquals(Float.compare(Float.NaN, Float.POSITIVE_INFINITY), +1);
1149 assertEquals(Float.compare(Float.NaN, Float.MAX_VALUE), +1);
1150 assertEquals(Float.compare(Float.NaN, 1.2f), +1);
1151 assertEquals(Float.compare(Float.NaN, 0.0f), +1);
1152 assertEquals(Float.compare(Float.NaN, -0.0f), +1);
1153 assertEquals(Float.compare(Float.NaN, -1.2f), +1);
1154 assertEquals(Float.compare(Float.NaN, -Float.MAX_VALUE), +1);
1155 assertEquals(Float.compare(Float.NaN, Float.NEGATIVE_INFINITY), +1);
1156
1157 assertEquals(Float.compare(Float.POSITIVE_INFINITY, Float.NaN), -1);
1158 assertEquals(0, Float.compare(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
1159 assertEquals(Float.compare(Float.POSITIVE_INFINITY, Float.MAX_VALUE), +1);
1160 assertEquals(Float.compare(Float.POSITIVE_INFINITY, 1.2f), +1);
1161 assertEquals(Float.compare(Float.POSITIVE_INFINITY, 0.0f), +1);
1162 assertEquals(Float.compare(Float.POSITIVE_INFINITY, -0.0f), +1);
1163 assertEquals(Float.compare(Float.POSITIVE_INFINITY, -1.2f), +1);
1164 assertEquals(Float.compare(Float.POSITIVE_INFINITY, -Float.MAX_VALUE), +1);
1165 assertEquals(Float.compare(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY), +1);
1166
1167 assertEquals(Float.compare(Float.MAX_VALUE, Float.NaN), -1);
1168 assertEquals(Float.compare(Float.MAX_VALUE, Float.POSITIVE_INFINITY), -1);
1169 assertEquals(0, Float.compare(Float.MAX_VALUE, Float.MAX_VALUE));
1170 assertEquals(Float.compare(Float.MAX_VALUE, 1.2f), +1);
1171 assertEquals(Float.compare(Float.MAX_VALUE, 0.0f), +1);
1172 assertEquals(Float.compare(Float.MAX_VALUE, -0.0f), +1);
1173 assertEquals(Float.compare(Float.MAX_VALUE, -1.2f), +1);
1174 assertEquals(Float.compare(Float.MAX_VALUE, -Float.MAX_VALUE), +1);
1175 assertEquals(Float.compare(Float.MAX_VALUE, Float.NEGATIVE_INFINITY), +1);
1176
1177 assertEquals(Float.compare(1.2f, Float.NaN), -1);
1178 assertEquals(Float.compare(1.2f, Float.POSITIVE_INFINITY), -1);
1179 assertEquals(Float.compare(1.2f, Float.MAX_VALUE), -1);
1180 assertEquals(0, Float.compare(1.2f, 1.2f));
1181 assertEquals(Float.compare(1.2f, 0.0f), +1);
1182 assertEquals(Float.compare(1.2f, -0.0f), +1);
1183 assertEquals(Float.compare(1.2f, -1.2f), +1);
1184 assertEquals(Float.compare(1.2f, -Float.MAX_VALUE), +1);
1185 assertEquals(Float.compare(1.2f, Float.NEGATIVE_INFINITY), +1);
1186
1187 assertEquals(Float.compare(0.0f, Float.NaN), -1);
1188 assertEquals(Float.compare(0.0f, Float.POSITIVE_INFINITY), -1);
1189 assertEquals(Float.compare(0.0f, Float.MAX_VALUE), -1);
1190 assertEquals(Float.compare(0.0f, 1.2f), -1);
1191 assertEquals(0, Float.compare(0.0f, 0.0f));
1192 assertEquals(Float.compare(0.0f, -0.0f), +1);
1193 assertEquals(Float.compare(0.0f, -1.2f), +1);
1194 assertEquals(Float.compare(0.0f, -Float.MAX_VALUE), +1);
1195 assertEquals(Float.compare(0.0f, Float.NEGATIVE_INFINITY), +1);
1196
1197 assertEquals(Float.compare(-0.0f, Float.NaN), -1);
1198 assertEquals(Float.compare(-0.0f, Float.POSITIVE_INFINITY), -1);
1199 assertEquals(Float.compare(-0.0f, Float.MAX_VALUE), -1);
1200 assertEquals(Float.compare(-0.0f, 1.2f), -1);
1201 assertEquals(Float.compare(-0.0f, 0.0f), -1);
1202 assertEquals(0, Float.compare(-0.0f, -0.0f));
1203 assertEquals(Float.compare(-0.0f, -1.2f), +1);
1204 assertEquals(Float.compare(-0.0f, -Float.MAX_VALUE), +1);
1205 assertEquals(Float.compare(-0.0f, Float.NEGATIVE_INFINITY), +1);
1206
1207 assertEquals(Float.compare(-1.2f, Float.NaN), -1);
1208 assertEquals(Float.compare(-1.2f, Float.POSITIVE_INFINITY), -1);
1209 assertEquals(Float.compare(-1.2f, Float.MAX_VALUE), -1);
1210 assertEquals(Float.compare(-1.2f, 1.2f), -1);
1211 assertEquals(Float.compare(-1.2f, 0.0f), -1);
1212 assertEquals(Float.compare(-1.2f, -0.0f), -1);
1213 assertEquals(0, Float.compare(-1.2f, -1.2f));
1214 assertEquals(Float.compare(-1.2f, -Float.MAX_VALUE), +1);
1215 assertEquals(Float.compare(-1.2f, Float.NEGATIVE_INFINITY), +1);
1216
1217 assertEquals(Float.compare(-Float.MAX_VALUE, Float.NaN), -1);
1218 assertEquals(Float.compare(-Float.MAX_VALUE, Float.POSITIVE_INFINITY), -1);
1219 assertEquals(Float.compare(-Float.MAX_VALUE, Float.MAX_VALUE), -1);
1220 assertEquals(Float.compare(-Float.MAX_VALUE, 1.2f), -1);
1221 assertEquals(Float.compare(-Float.MAX_VALUE, 0.0f), -1);
1222 assertEquals(Float.compare(-Float.MAX_VALUE, -0.0f), -1);
1223 assertEquals(Float.compare(-Float.MAX_VALUE, -1.2f), -1);
1224 assertEquals(0, Float.compare(-Float.MAX_VALUE, -Float.MAX_VALUE));
1225 assertEquals(Float.compare(-Float.MAX_VALUE, Float.NEGATIVE_INFINITY), +1);
1226
1227 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, Float.NaN), -1);
1228 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY), -1);
1229 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, Float.MAX_VALUE), -1);
1230 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, 1.2f), -1);
1231 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, 0.0f), -1);
1232 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, -0.0f), -1);
1233 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, -1.2f), -1);
1234 assertEquals(Float.compare(Float.NEGATIVE_INFINITY, -Float.MAX_VALUE), -1);
1235 assertEquals(0, Float.compare(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
1236 }
1237
1238 @Test
1239 public void testIsDigits() {
1240 assertFalse(NumberUtils.isDigits(null), "isDigits(null) failed");
1241 assertFalse(NumberUtils.isDigits(""), "isDigits('') failed");
1242 assertTrue(NumberUtils.isDigits("12345"), "isDigits(String) failed");
1243 assertFalse(NumberUtils.isDigits("1234.5"), "isDigits(String) neg 1 failed");
1244 assertFalse(NumberUtils.isDigits("1ab"), "isDigits(String) neg 3 failed");
1245 assertFalse(NumberUtils.isDigits("abc"), "isDigits(String) neg 4 failed");
1246 }
1247
1248 /**
1249 * Tests isCreatable(String) and tests that createNumber(String) returns
1250 * a valid number iff isCreatable(String) returns false.
413 this.testCreateDoubleFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F");
414 }
415
416 protected void testCreateDoubleFailure(final String str) {
417 assertThrows(NumberFormatException.class, () -> NumberUtils.createDouble(str),
418 "createDouble(\"" + str + "\") should have failed.");
419 }
420
421 @Test
422 public void testCreateFloat() {
423 assertEquals(Float.valueOf("1234.5"), NumberUtils.createFloat("1234.5"), "createFloat(String) failed");
424 assertNull(NumberUtils.createFloat(null), "createFloat(null) failed");
425 this.testCreateFloatFailure("");
426 this.testCreateFloatFailure(" ");
427 this.testCreateFloatFailure("\b\t\n\f\r");
428 // Funky whitespaces
429 this.testCreateFloatFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F");
430 }
431
432 protected void testCreateFloatFailure(final String str) {
433 assertThrows(NumberFormatException.class, () -> NumberUtils.createFloat(str),
434 "createFloat(\"" + str + "\") should have failed.");
435 }
436
437 @Test
438 public void testCreateInteger() {
439 assertEquals(Integer.valueOf("12345"), NumberUtils.createInteger("12345"), "createInteger(String) failed");
440 assertNull(NumberUtils.createInteger(null), "createInteger(null) failed");
441 this.testCreateIntegerFailure("");
442 this.testCreateIntegerFailure(" ");
443 this.testCreateIntegerFailure("\b\t\n\f\r");
444 // Funky whitespaces
445 this.testCreateIntegerFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F");
446 }
447
448 protected void testCreateIntegerFailure(final String str) {
449 assertThrows(NumberFormatException.class, () -> NumberUtils.createInteger(str),
450 "createInteger(\"" + str + "\") should have failed.");
451 }
452
453 @Test
454 public void testCreateLong() {
455 assertEquals(Long.valueOf("12345"), NumberUtils.createLong("12345"), "createLong(String) failed");
456 assertNull(NumberUtils.createLong(null), "createLong(null) failed");
457 this.testCreateLongFailure("");
458 this.testCreateLongFailure(" ");
459 this.testCreateLongFailure("\b\t\n\f\r");
460 // Funky whitespaces
461 this.testCreateLongFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F");
462 }
463
464 protected void testCreateLongFailure(final String str) {
465 assertThrows(NumberFormatException.class, () -> NumberUtils.createLong(str),
466 "createLong(\"" + str + "\") should have failed.");
467 }
468
469 @Test
470 public void testCreateNumber() {
471 // a lot of things can go wrong
472 assertEquals(Float.valueOf("1234.5"), NumberUtils.createNumber("1234.5"), "createNumber(String) 1 failed");
473 assertEquals(Integer.valueOf("12345"), NumberUtils.createNumber("12345"), "createNumber(String) 2 failed");
474 assertEquals(Double.valueOf("1234.5"), NumberUtils.createNumber("1234.5D"), "createNumber(String) 3 failed");
475 assertEquals(Double.valueOf("1234.5"), NumberUtils.createNumber("1234.5d"), "createNumber(String) 3 failed");
476 assertEquals(Float.valueOf("1234.5"), NumberUtils.createNumber("1234.5F"), "createNumber(String) 4 failed");
477 assertEquals(Float.valueOf("1234.5"), NumberUtils.createNumber("1234.5f"), "createNumber(String) 4 failed");
478 assertEquals(Long.valueOf(Integer.MAX_VALUE + 1L), NumberUtils.createNumber("" + (Integer.MAX_VALUE + 1L)),
479 "createNumber(String) 5 failed");
480 assertEquals(Long.valueOf(12345), NumberUtils.createNumber("12345L"), "createNumber(String) 6 failed");
481 assertEquals(Long.valueOf(12345), NumberUtils.createNumber("12345l"), "createNumber(String) 6 failed");
482 assertEquals(Float.valueOf("-1234.5"), NumberUtils.createNumber("-1234.5"), "createNumber(String) 7 failed");
483 assertEquals(Integer.valueOf("-12345"), NumberUtils.createNumber("-12345"), "createNumber(String) 8 failed");
484 assertEquals(0xFADE, NumberUtils.createNumber("0xFADE").intValue(), "createNumber(String) 9a failed");
485 assertEquals(0xFADE, NumberUtils.createNumber("0Xfade").intValue(), "createNumber(String) 9b failed");
486 assertEquals(-0xFADE, NumberUtils.createNumber("-0xFADE").intValue(), "createNumber(String) 10a failed");
487 assertEquals(-0xFADE, NumberUtils.createNumber("-0Xfade").intValue(), "createNumber(String) 10b failed");
488 assertEquals(Double.valueOf("1.1E200"), NumberUtils.createNumber("1.1E200"), "createNumber(String) 11 failed");
489 assertEquals(Float.valueOf("1.1E20"), NumberUtils.createNumber("1.1E20"), "createNumber(String) 12 failed");
490 assertEquals(Double.valueOf("-1.1E200"), NumberUtils.createNumber("-1.1E200"),
491 "createNumber(String) 13 failed");
492 assertEquals(Double.valueOf("1.1E-200"), NumberUtils.createNumber("1.1E-200"),
493 "createNumber(String) 14 failed");
494 assertNull(NumberUtils.createNumber(null), "createNumber(null) failed");
495 assertEquals(new BigInteger("12345678901234567890"), NumberUtils.createNumber("12345678901234567890L"),
496 "createNumber(String) failed");
497
498 assertEquals(new BigDecimal("1.1E-700"), NumberUtils.createNumber("1.1E-700F"),
499 "createNumber(String) 15 failed");
500
501 assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), NumberUtils.createNumber("10" + Integer.MAX_VALUE + "L"),
502 "createNumber(String) 16 failed");
503 assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), NumberUtils.createNumber("10" + Integer.MAX_VALUE),
504 "createNumber(String) 17 failed");
505 assertEquals(new BigInteger("10" + Long.MAX_VALUE), NumberUtils.createNumber("10" + Long.MAX_VALUE),
506 "createNumber(String) 18 failed");
507
508 // LANG-521
509 assertEquals(Float.valueOf("2."), NumberUtils.createNumber("2."), "createNumber(String) LANG-521 failed");
510
511 // LANG-638
512 assertFalse(checkCreateNumber("1eE"), "createNumber(String) succeeded");
513
514 // LANG-693
515 assertEquals(Double.valueOf(Double.MAX_VALUE), NumberUtils.createNumber("" + Double.MAX_VALUE),
516 "createNumber(String) LANG-693 failed");
517
518 // LANG-822
519 // ensure that the underlying negative number would create a BigDecimal
520 final Number bigNum = NumberUtils.createNumber("-1.1E-700F");
521 assertNotNull(bigNum);
522 assertEquals(BigDecimal.class, bigNum.getClass());
523
524 // LANG-1018
525 assertEquals(Double.valueOf("-160952.54"), NumberUtils.createNumber("-160952.54"),
526 "createNumber(String) LANG-1018 failed");
527 // LANG-1187
528 assertEquals(Double.valueOf("6264583.33"), NumberUtils.createNumber("6264583.33"),
529 "createNumber(String) LANG-1187 failed");
530 // LANG-1215
531 assertEquals(Double.valueOf("193343.82"), NumberUtils.createNumber("193343.82"),
532 "createNumber(String) LANG-1215 failed");
533 // LANG-1060
534 assertEquals(Double.valueOf("001234.5678"), NumberUtils.createNumber("001234.5678"),
535 "createNumber(String) LANG-1060a failed");
536 assertEquals(Double.valueOf("+001234.5678"), NumberUtils.createNumber("+001234.5678"),
537 "createNumber(String) LANG-1060b failed");
538 assertEquals(Double.valueOf("-001234.5678"), NumberUtils.createNumber("-001234.5678"),
539 "createNumber(String) LANG-1060c failed");
540 assertEquals(Double.valueOf("0000.00000"), NumberUtils.createNumber("0000.00000d"),
541 "createNumber(String) LANG-1060d failed");
542 assertEquals(Float.valueOf("001234.56"), NumberUtils.createNumber("001234.56"),
543 "createNumber(String) LANG-1060e failed");
544 assertEquals(Float.valueOf("+001234.56"), NumberUtils.createNumber("+001234.56"),
545 "createNumber(String) LANG-1060f failed");
546 assertEquals(Float.valueOf("-001234.56"), NumberUtils.createNumber("-001234.56"),
547 "createNumber(String) LANG-1060g failed");
548 assertEquals(Float.valueOf("0000.10"), NumberUtils.createNumber("0000.10"),
549 "createNumber(String) LANG-1060h failed");
550 assertEquals(Float.valueOf("001.1E20"), NumberUtils.createNumber("001.1E20"),
551 "createNumber(String) LANG-1060i failed");
552 assertEquals(Float.valueOf("+001.1E20"), NumberUtils.createNumber("+001.1E20"),
553 "createNumber(String) LANG-1060j failed");
554 assertEquals(Float.valueOf("-001.1E20"), NumberUtils.createNumber("-001.1E20"),
555 "createNumber(String) LANG-1060k failed");
556 assertEquals(Double.valueOf("001.1E200"), NumberUtils.createNumber("001.1E200"),
557 "createNumber(String) LANG-1060l failed");
558 assertEquals(Double.valueOf("+001.1E200"), NumberUtils.createNumber("+001.1E200"),
559 "createNumber(String) LANG-1060m failed");
560 assertEquals(Double.valueOf("-001.1E200"), NumberUtils.createNumber("-001.1E200"),
561 "createNumber(String) LANG-1060n failed");
562 }
563
564 @Test
565 // Check that the code fails to create a valid number when preceded by -- rather than -
566 public void testCreateNumberFailure_1() {
567 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("--1.1E-700F"));
568 }
569
570 @Test
571 // Check that the code fails to create a valid number when both e and E are present (with decimal)
572 public void testCreateNumberFailure_2() {
573 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("-1.1E+0-7e00"));
574 }
575
576 @Test
577 // Check that the code fails to create a valid number when both e and E are present (no decimal)
578 public void testCreateNumberFailure_3() {
579 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("-11E+0-7e00"));
580 }
581
582 @Test
583 // Check that the code fails to create a valid number when both e and E are present (no decimal)
584 public void testCreateNumberFailure_4() {
585 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("1eE+00001"));
586 }
587
588 @Test
589 // Check that the code fails to create a valid number when there are multiple trailing 'f' characters (LANG-1205)
590 public void testCreateNumberFailure_5() {
591 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("1234.5ff"));
592 }
593
594 @Test
595 // Check that the code fails to create a valid number when there are multiple trailing 'F' characters (LANG-1205)
596 public void testCreateNumberFailure_6() {
597 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("1234.5FF"));
598 }
599
600 @Test
601 // Check that the code fails to create a valid number when there are multiple trailing 'd' characters (LANG-1205)
602 public void testCreateNumberFailure_7() {
603 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("1234.5dd"));
604 }
605
606 @Test
607 // Check that the code fails to create a valid number when there are multiple trailing 'D' characters (LANG-1205)
608 public void testCreateNumberFailure_8() {
609 assertThrows(NumberFormatException.class, () -> NumberUtils.createNumber("1234.5DD"));
610 }
611
612 // Tests to show when magnitude causes switch to next Number type
613 // Will probably need to be adjusted if code is changed to check precision (LANG-693)
614 @Test
615 public void testCreateNumberMagnitude() {
616 // Test Float.MAX_VALUE, and same with +1 in final digit to check conversion changes to next Number type
617 assertEquals(Float.valueOf(Float.MAX_VALUE), NumberUtils.createNumber("3.4028235e+38"));
618 assertEquals(Double.valueOf(3.4028236e+38), NumberUtils.createNumber("3.4028236e+38"));
619
620 // Test Double.MAX_VALUE
621 assertEquals(Double.valueOf(Double.MAX_VALUE), NumberUtils.createNumber("1.7976931348623157e+308"));
622 // Test with +2 in final digit (+1 does not cause roll-over to BigDecimal)
623 assertEquals(new BigDecimal("1.7976931348623159e+308"), NumberUtils.createNumber("1.7976931348623159e+308"));
624
625 assertEquals(Integer.valueOf(0x12345678), NumberUtils.createNumber("0x12345678"));
626 assertEquals(Long.valueOf(0x123456789L), NumberUtils.createNumber("0x123456789"));
627
628 assertEquals(Long.valueOf(0x7fffffffffffffffL), NumberUtils.createNumber("0x7fffffffffffffff"));
629 // Does not appear to be a way to create a literal BigInteger of this magnitude
630 assertEquals(new BigInteger("7fffffffffffffff0", 16), NumberUtils.createNumber("0x7fffffffffffffff0"));
631
632 assertEquals(Long.valueOf(0x7fffffffffffffffL), NumberUtils.createNumber("#7fffffffffffffff"));
633 assertEquals(new BigInteger("7fffffffffffffff0", 16), NumberUtils.createNumber("#7fffffffffffffff0"));
634
635 assertEquals(Integer.valueOf(017777777777), NumberUtils.createNumber("017777777777")); // 31 bits
636 assertEquals(Long.valueOf(037777777777L), NumberUtils.createNumber("037777777777")); // 32 bits
637
638 // 63 bits
639 assertEquals(Long.valueOf(0777777777777777777777L), NumberUtils.createNumber("0777777777777777777777"));
640 // 64 bits
641 assertEquals(new BigInteger("1777777777777777777777", 8), NumberUtils.createNumber("01777777777777777777777"));
642 }
643
644 /**
645 * Tests isCreatable(String) and tests that createNumber(String) returns a valid number iff isCreatable(String)
646 * returns false.
1251647 */
1252648 @Test
1253649 public void testIsCreatable() {
1305701 }
1306702
1307703 @Test
1308 public void testLANG971() {
1309 compareIsCreatableWithCreateNumber("0085", false);
1310 compareIsCreatableWithCreateNumber("085", false);
1311 compareIsCreatableWithCreateNumber("08", false);
1312 compareIsCreatableWithCreateNumber("07", true);
1313 compareIsCreatableWithCreateNumber("00", true);
1314 }
1315
1316 @Test
1317 public void testLANG992() {
1318 compareIsCreatableWithCreateNumber("0.0", true);
1319 compareIsCreatableWithCreateNumber("0.4790", true);
1320 }
1321
1322 @Test
1323 public void testLANG972() {
1324 compareIsCreatableWithCreateNumber("0xABCD", true);
1325 compareIsCreatableWithCreateNumber("0XABCD", true);
1326 }
1327
1328 @Test
1329 public void testLANG1252() {
1330 compareIsCreatableWithCreateNumber("+2", true);
1331 compareIsCreatableWithCreateNumber("+2.0", true);
1332 }
1333
1334 private void compareIsCreatableWithCreateNumber(final String val, final boolean expected) {
1335 final boolean isValid = NumberUtils.isCreatable(val);
1336 final boolean canCreate = checkCreateNumber(val);
1337 assertTrue(
1338 isValid == expected && canCreate == expected,
1339 "Expecting " + expected + " for isCreatable/createNumber using \"" + val + "\" but got " + isValid + " and " + canCreate);
1340 }
1341
1342 /**
1343 * Tests isCreatable(String) and tests that createNumber(String) returns
1344 * a valid number iff isCreatable(String) returns false.
704 public void testIsDigits() {
705 assertFalse(NumberUtils.isDigits(null), "isDigits(null) failed");
706 assertFalse(NumberUtils.isDigits(""), "isDigits('') failed");
707 assertTrue(NumberUtils.isDigits("12345"), "isDigits(String) failed");
708 assertFalse(NumberUtils.isDigits("1234.5"), "isDigits(String) neg 1 failed");
709 assertFalse(NumberUtils.isDigits("1ab"), "isDigits(String) neg 3 failed");
710 assertFalse(NumberUtils.isDigits("abc"), "isDigits(String) neg 4 failed");
711 }
712
713 /**
714 * Tests isCreatable(String) and tests that createNumber(String) returns a valid number iff isCreatable(String)
715 * returns false.
1345716 */
1346717 @Test
1347718 public void testIsNumber() {
1405776 }
1406777
1407778 @Test
779 public void testIsNumberLANG1252() {
780 compareIsNumberWithCreateNumber("+2", true);
781 compareIsNumberWithCreateNumber("+2.0", true);
782 }
783
784 @Test
785 public void testIsNumberLANG1385() {
786 compareIsNumberWithCreateNumber("L", false);
787 }
788
789 @Test
1408790 public void testIsNumberLANG971() {
1409791 compareIsNumberWithCreateNumber("0085", false);
1410792 compareIsNumberWithCreateNumber("085", false);
1414796 }
1415797
1416798 @Test
799 public void testIsNumberLANG972() {
800 compareIsNumberWithCreateNumber("0xABCD", true);
801 compareIsNumberWithCreateNumber("0XABCD", true);
802 }
803
804 @Test
1417805 public void testIsNumberLANG992() {
1418806 compareIsNumberWithCreateNumber("0.0", true);
1419807 compareIsNumberWithCreateNumber("0.4790", true);
1420 }
1421
1422 @Test
1423 public void testIsNumberLANG972() {
1424 compareIsNumberWithCreateNumber("0xABCD", true);
1425 compareIsNumberWithCreateNumber("0XABCD", true);
1426 }
1427
1428 @Test
1429 public void testIsNumberLANG1252() {
1430 compareIsNumberWithCreateNumber("+2", true);
1431 compareIsNumberWithCreateNumber("+2.0", true);
1432 }
1433
1434 @Test
1435 public void testIsNumberLANG1385() {
1436 compareIsNumberWithCreateNumber("L", false);
1437 }
1438
1439 private void compareIsNumberWithCreateNumber(final String val, final boolean expected) {
1440 final boolean isValid = NumberUtils.isCreatable(val);
1441 final boolean canCreate = checkCreateNumber(val);
1442 assertTrue(
1443 isValid == expected && canCreate == expected,
1444 "Expecting "+ expected + " for isCreatable/createNumber using \"" + val + "\" but got " + isValid + " and " + canCreate);
1445808 }
1446809
1447810 @Test
1467830 assertTrue(NumberUtils.isParsable("-.236"));
1468831 }
1469832
1470 private boolean checkCreateNumber(final String val) {
1471 try {
1472 final Object obj = NumberUtils.createNumber(val);
1473 return obj != null;
1474 } catch (final NumberFormatException e) {
1475 return false;
1476 }
1477 }
1478
1479 @SuppressWarnings("cast") // suppress instanceof warning check
1480 @Test
1481 public void testConstants() {
1482 assertTrue(NumberUtils.LONG_ZERO instanceof Long);
1483 assertTrue(NumberUtils.LONG_ONE instanceof Long);
1484 assertTrue(NumberUtils.LONG_MINUS_ONE instanceof Long);
1485 assertTrue(NumberUtils.INTEGER_ZERO instanceof Integer);
1486 assertTrue(NumberUtils.INTEGER_ONE instanceof Integer);
1487 assertTrue(NumberUtils.INTEGER_MINUS_ONE instanceof Integer);
1488 assertTrue(NumberUtils.SHORT_ZERO instanceof Short);
1489 assertTrue(NumberUtils.SHORT_ONE instanceof Short);
1490 assertTrue(NumberUtils.SHORT_MINUS_ONE instanceof Short);
1491 assertTrue(NumberUtils.BYTE_ZERO instanceof Byte);
1492 assertTrue(NumberUtils.BYTE_ONE instanceof Byte);
1493 assertTrue(NumberUtils.BYTE_MINUS_ONE instanceof Byte);
1494 assertTrue(NumberUtils.DOUBLE_ZERO instanceof Double);
1495 assertTrue(NumberUtils.DOUBLE_ONE instanceof Double);
1496 assertTrue(NumberUtils.DOUBLE_MINUS_ONE instanceof Double);
1497 assertTrue(NumberUtils.FLOAT_ZERO instanceof Float);
1498 assertTrue(NumberUtils.FLOAT_ONE instanceof Float);
1499 assertTrue(NumberUtils.FLOAT_MINUS_ONE instanceof Float);
1500
1501 assertEquals(0, NumberUtils.LONG_ZERO.longValue());
1502 assertEquals(1, NumberUtils.LONG_ONE.longValue());
1503 assertEquals(NumberUtils.LONG_MINUS_ONE.longValue(), -1);
1504 assertEquals(0, NumberUtils.INTEGER_ZERO.intValue());
1505 assertEquals(1, NumberUtils.INTEGER_ONE.intValue());
1506 assertEquals(NumberUtils.INTEGER_MINUS_ONE.intValue(), -1);
1507 assertEquals(0, NumberUtils.SHORT_ZERO.shortValue());
1508 assertEquals(1, NumberUtils.SHORT_ONE.shortValue());
1509 assertEquals(NumberUtils.SHORT_MINUS_ONE.shortValue(), -1);
1510 assertEquals(0, NumberUtils.BYTE_ZERO.byteValue());
1511 assertEquals(1, NumberUtils.BYTE_ONE.byteValue());
1512 assertEquals(NumberUtils.BYTE_MINUS_ONE.byteValue(), -1);
1513 assertEquals(0.0d, NumberUtils.DOUBLE_ZERO.doubleValue());
1514 assertEquals(1.0d, NumberUtils.DOUBLE_ONE.doubleValue());
1515 assertEquals(NumberUtils.DOUBLE_MINUS_ONE.doubleValue(), -1.0d);
1516 assertEquals(0.0f, NumberUtils.FLOAT_ZERO.floatValue());
1517 assertEquals(1.0f, NumberUtils.FLOAT_ONE.floatValue());
1518 assertEquals(NumberUtils.FLOAT_MINUS_ONE.floatValue(), -1.0f);
833 @Test
834 public void testLang1087() {
835 // no sign cases
836 assertEquals(Float.class, NumberUtils.createNumber("0.0").getClass());
837 assertEquals(Float.valueOf("0.0"), NumberUtils.createNumber("0.0"));
838 // explicit positive sign cases
839 assertEquals(Float.class, NumberUtils.createNumber("+0.0").getClass());
840 assertEquals(Float.valueOf("+0.0"), NumberUtils.createNumber("+0.0"));
841 // negative sign cases
842 assertEquals(Float.class, NumberUtils.createNumber("-0.0").getClass());
843 assertEquals(Float.valueOf("-0.0"), NumberUtils.createNumber("-0.0"));
844 }
845
846 @Test
847 public void testLANG1252() {
848 compareIsCreatableWithCreateNumber("+2", true);
849 compareIsCreatableWithCreateNumber("+2.0", true);
1519850 }
1520851
1521852 @Test
1532863 assertTrue(Float.isNaN(NumberUtils.min(1.2f, 2.5f, Float.NaN)));
1533864 assertTrue(Float.isNaN(NumberUtils.max(1.2f, 2.5f, Float.NaN)));
1534865
1535 final double[] a = new double[] { 1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN };
866 final double[] a = new double[] {1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN};
1536867 assertTrue(Double.isNaN(NumberUtils.max(a)));
1537868 assertTrue(Double.isNaN(NumberUtils.min(a)));
1538869
1539 final double[] b = new double[] { Double.NaN, 1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN };
870 final double[] b = new double[] {Double.NaN, 1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN};
1540871 assertTrue(Double.isNaN(NumberUtils.max(b)));
1541872 assertTrue(Double.isNaN(NumberUtils.min(b)));
1542873
1543 final float[] aF = new float[] { 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN };
874 final float[] aF = new float[] {1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN};
1544875 assertTrue(Float.isNaN(NumberUtils.max(aF)));
1545876
1546 final float[] bF = new float[] { Float.NaN, 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN };
877 final float[] bF = new float[] {Float.NaN, 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN};
1547878 assertTrue(Float.isNaN(NumberUtils.max(bF)));
1548879 }
1549880
1550881 @Test
1551 public void compareInt() {
1552 assertTrue(NumberUtils.compare(-3, 0) < 0);
1553 assertEquals(0, NumberUtils.compare(113, 113));
1554 assertTrue(NumberUtils.compare(213, 32) > 0);
1555 }
1556
1557 @Test
1558 public void compareLong() {
1559 assertTrue(NumberUtils.compare(-3L, 0L) < 0);
1560 assertEquals(0, NumberUtils.compare(113L, 113L));
1561 assertTrue(NumberUtils.compare(213L, 32L) > 0);
1562 }
1563
1564 @Test
1565 public void compareShort() {
1566 assertTrue(NumberUtils.compare((short) -3, (short) 0) < 0);
1567 assertEquals(0, NumberUtils.compare((short) 113, (short) 113));
1568 assertTrue(NumberUtils.compare((short) 213, (short) 32) > 0);
1569 }
1570
1571 @Test
1572 public void compareByte() {
1573 assertTrue(NumberUtils.compare((byte) -3, (byte) 0) < 0);
1574 assertEquals(0, NumberUtils.compare((byte) 113, (byte) 113));
1575 assertTrue(NumberUtils.compare((byte) 123, (byte) 32) > 0);
882 public void TestLang747() {
883 assertEquals(Integer.valueOf(0x8000), NumberUtils.createNumber("0x8000"));
884 assertEquals(Integer.valueOf(0x80000), NumberUtils.createNumber("0x80000"));
885 assertEquals(Integer.valueOf(0x800000), NumberUtils.createNumber("0x800000"));
886 assertEquals(Integer.valueOf(0x8000000), NumberUtils.createNumber("0x8000000"));
887 assertEquals(Integer.valueOf(0x7FFFFFFF), NumberUtils.createNumber("0x7FFFFFFF"));
888 assertEquals(Long.valueOf(0x80000000L), NumberUtils.createNumber("0x80000000"));
889 assertEquals(Long.valueOf(0xFFFFFFFFL), NumberUtils.createNumber("0xFFFFFFFF"));
890
891 // Leading zero tests
892 assertEquals(Integer.valueOf(0x8000000), NumberUtils.createNumber("0x08000000"));
893 assertEquals(Integer.valueOf(0x7FFFFFFF), NumberUtils.createNumber("0x007FFFFFFF"));
894 assertEquals(Long.valueOf(0x80000000L), NumberUtils.createNumber("0x080000000"));
895 assertEquals(Long.valueOf(0xFFFFFFFFL), NumberUtils.createNumber("0x00FFFFFFFF"));
896
897 assertEquals(Long.valueOf(0x800000000L), NumberUtils.createNumber("0x800000000"));
898 assertEquals(Long.valueOf(0x8000000000L), NumberUtils.createNumber("0x8000000000"));
899 assertEquals(Long.valueOf(0x80000000000L), NumberUtils.createNumber("0x80000000000"));
900 assertEquals(Long.valueOf(0x800000000000L), NumberUtils.createNumber("0x800000000000"));
901 assertEquals(Long.valueOf(0x8000000000000L), NumberUtils.createNumber("0x8000000000000"));
902 assertEquals(Long.valueOf(0x80000000000000L), NumberUtils.createNumber("0x80000000000000"));
903 assertEquals(Long.valueOf(0x800000000000000L), NumberUtils.createNumber("0x800000000000000"));
904 assertEquals(Long.valueOf(0x7FFFFFFFFFFFFFFFL), NumberUtils.createNumber("0x7FFFFFFFFFFFFFFF"));
905 // N.B. Cannot use a hex constant such as 0x8000000000000000L here as that is interpreted as a negative long
906 assertEquals(new BigInteger("8000000000000000", 16), NumberUtils.createNumber("0x8000000000000000"));
907 assertEquals(new BigInteger("FFFFFFFFFFFFFFFF", 16), NumberUtils.createNumber("0xFFFFFFFFFFFFFFFF"));
908
909 // Leading zero tests
910 assertEquals(Long.valueOf(0x80000000000000L), NumberUtils.createNumber("0x00080000000000000"));
911 assertEquals(Long.valueOf(0x800000000000000L), NumberUtils.createNumber("0x0800000000000000"));
912 assertEquals(Long.valueOf(0x7FFFFFFFFFFFFFFFL), NumberUtils.createNumber("0x07FFFFFFFFFFFFFFF"));
913 // N.B. Cannot use a hex constant such as 0x8000000000000000L here as that is interpreted as a negative long
914 assertEquals(new BigInteger("8000000000000000", 16), NumberUtils.createNumber("0x00008000000000000000"));
915 assertEquals(new BigInteger("FFFFFFFFFFFFFFFF", 16), NumberUtils.createNumber("0x0FFFFFFFFFFFFFFFF"));
916 }
917
918 @Test
919 public void testLANG971() {
920 compareIsCreatableWithCreateNumber("0085", false);
921 compareIsCreatableWithCreateNumber("085", false);
922 compareIsCreatableWithCreateNumber("08", false);
923 compareIsCreatableWithCreateNumber("07", true);
924 compareIsCreatableWithCreateNumber("00", true);
925 }
926
927 @Test
928 public void testLANG972() {
929 compareIsCreatableWithCreateNumber("0xABCD", true);
930 compareIsCreatableWithCreateNumber("0XABCD", true);
931 }
932
933 @Test
934 public void testLANG992() {
935 compareIsCreatableWithCreateNumber("0.0", true);
936 compareIsCreatableWithCreateNumber("0.4790", true);
937 }
938
939 @Test
940 public void testMaxByte() {
941 assertEquals((byte) 5, NumberUtils.max((byte) 5), "max(byte[]) failed for array length 1");
942 assertEquals((byte) 9, NumberUtils.max((byte) 6, (byte) 9), "max(byte[]) failed for array length 2");
943 assertEquals((byte) 10, NumberUtils.max((byte) -10, (byte) -5, (byte) 0, (byte) 5, (byte) 10),
944 "max(byte[]) failed for array length 5");
945 assertEquals((byte) 10, NumberUtils.max((byte) -10, (byte) -5, (byte) 0, (byte) 5, (byte) 10));
946 assertEquals((byte) 10, NumberUtils.max((byte) -5, (byte) 0, (byte) 10, (byte) 5, (byte) -10));
947 }
948
949 @Test
950 public void testMaxByte_emptyArray() {
951 assertThrows(IllegalArgumentException.class, NumberUtils::max);
952 }
953
954 @Test
955 public void testMaxByte_nullArray() {
956 assertThrows(NullPointerException.class, () -> NumberUtils.max((byte[]) null));
957 }
958
959 @Test
960 public void testMaxDouble() {
961 final double[] d = null;
962 assertThrows(NullPointerException.class, () -> NumberUtils.max(d), "No exception was thrown for null input.");
963
964 assertThrows(IllegalArgumentException.class, NumberUtils::max, "No exception was thrown for empty input.");
965
966 assertEquals(5.1f, NumberUtils.max(5.1f), "max(double[]) failed for array length 1");
967 assertEquals(9.2f, NumberUtils.max(6.3f, 9.2f), "max(double[]) failed for array length 2");
968 assertEquals(10.4f, NumberUtils.max(-10.5f, -5.6f, 0, 5.7f, 10.4f), "max(double[]) failed for float length 5");
969 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10), 0.0001);
970 assertEquals(10, NumberUtils.max(-5, 0, 10, 5, -10), 0.0001);
971 }
972
973 @Test
974 public void testMaxDouble_emptyArray() {
975 assertThrows(IllegalArgumentException.class, NumberUtils::max);
976 }
977
978 @Test
979 public void testMaxDouble_nullArray() {
980 assertThrows(NullPointerException.class, () -> NumberUtils.max((double[]) null));
981 }
982
983 @Test
984 public void testMaxFloat() {
985 assertEquals(5.1f, NumberUtils.max(5.1f), "max(float[]) failed for array length 1");
986 assertEquals(9.2f, NumberUtils.max(6.3f, 9.2f), "max(float[]) failed for array length 2");
987 assertEquals(10.4f, NumberUtils.max(-10.5f, -5.6f, 0, 5.7f, 10.4f), "max(float[]) failed for float length 5");
988 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10), 0.0001f);
989 assertEquals(10, NumberUtils.max(-5, 0, 10, 5, -10), 0.0001f);
990 }
991
992 @Test
993 public void testMaxFloat_emptyArray() {
994 assertThrows(IllegalArgumentException.class, NumberUtils::max);
995 }
996
997 @Test
998 public void testMaxFloat_nullArray() {
999 assertThrows(NullPointerException.class, () -> NumberUtils.max((float[]) null));
1000 }
1001
1002 @Test
1003 public void testMaximumByte() {
1004 final byte low = 123;
1005 final byte mid = 123 + 1;
1006 final byte high = 123 + 2;
1007 assertEquals(high, NumberUtils.max(low, mid, high), "maximum(byte, byte, byte) 1 failed");
1008 assertEquals(high, NumberUtils.max(mid, low, high), "maximum(byte, byte, byte) 2 failed");
1009 assertEquals(high, NumberUtils.max(mid, high, low), "maximum(byte, byte, byte) 3 failed");
1010 assertEquals(high, NumberUtils.max(high, mid, high), "maximum(byte, byte, byte) 4 failed");
1011 }
1012
1013 @Test
1014 public void testMaximumDouble() {
1015 final double low = 12.3;
1016 final double mid = 12.3 + 1;
1017 final double high = 12.3 + 2;
1018 assertEquals(high, NumberUtils.max(low, mid, high), 0.0001);
1019 assertEquals(high, NumberUtils.max(mid, low, high), 0.0001);
1020 assertEquals(high, NumberUtils.max(mid, high, low), 0.0001);
1021 assertEquals(mid, NumberUtils.max(low, mid, low), 0.0001);
1022 assertEquals(high, NumberUtils.max(high, mid, high), 0.0001);
1023 }
1024
1025 @Test
1026 public void testMaximumFloat() {
1027 final float low = 12.3f;
1028 final float mid = 12.3f + 1;
1029 final float high = 12.3f + 2;
1030 assertEquals(high, NumberUtils.max(low, mid, high), 0.0001f);
1031 assertEquals(high, NumberUtils.max(mid, low, high), 0.0001f);
1032 assertEquals(high, NumberUtils.max(mid, high, low), 0.0001f);
1033 assertEquals(mid, NumberUtils.max(low, mid, low), 0.0001f);
1034 assertEquals(high, NumberUtils.max(high, mid, high), 0.0001f);
1035 }
1036
1037 @Test
1038 public void testMaximumInt() {
1039 assertEquals(12345, NumberUtils.max(12345, 12345 - 1, 12345 - 2), "maximum(int, int, int) 1 failed");
1040 assertEquals(12345, NumberUtils.max(12345 - 1, 12345, 12345 - 2), "maximum(int, int, int) 2 failed");
1041 assertEquals(12345, NumberUtils.max(12345 - 1, 12345 - 2, 12345), "maximum(int, int, int) 3 failed");
1042 assertEquals(12345, NumberUtils.max(12345 - 1, 12345, 12345), "maximum(int, int, int) 4 failed");
1043 assertEquals(12345, NumberUtils.max(12345, 12345, 12345), "maximum(int, int, int) 5 failed");
1044 }
1045
1046 @Test
1047 public void testMaximumLong() {
1048 assertEquals(12345L, NumberUtils.max(12345L, 12345L - 1L, 12345L - 2L), "maximum(long, long, long) 1 failed");
1049 assertEquals(12345L, NumberUtils.max(12345L - 1L, 12345L, 12345L - 2L), "maximum(long, long, long) 2 failed");
1050 assertEquals(12345L, NumberUtils.max(12345L - 1L, 12345L - 2L, 12345L), "maximum(long, long, long) 3 failed");
1051 assertEquals(12345L, NumberUtils.max(12345L - 1L, 12345L, 12345L), "maximum(long, long, long) 4 failed");
1052 assertEquals(12345L, NumberUtils.max(12345L, 12345L, 12345L), "maximum(long, long, long) 5 failed");
1053 }
1054
1055 @Test
1056 public void testMaximumShort() {
1057 final short low = 1234;
1058 final short mid = 1234 + 1;
1059 final short high = 1234 + 2;
1060 assertEquals(high, NumberUtils.max(low, mid, high), "maximum(short, short, short) 1 failed");
1061 assertEquals(high, NumberUtils.max(mid, low, high), "maximum(short, short, short) 2 failed");
1062 assertEquals(high, NumberUtils.max(mid, high, low), "maximum(short, short, short) 3 failed");
1063 assertEquals(high, NumberUtils.max(high, mid, high), "maximum(short, short, short) 4 failed");
1064 }
1065
1066 @Test
1067 public void testMaxInt() {
1068 assertEquals(5, NumberUtils.max(5), "max(int[]) failed for array length 1");
1069 assertEquals(9, NumberUtils.max(6, 9), "max(int[]) failed for array length 2");
1070 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10), "max(int[]) failed for array length 5");
1071 assertEquals(10, NumberUtils.max(-10, -5, 0, 5, 10));
1072 assertEquals(10, NumberUtils.max(-5, 0, 10, 5, -10));
1073 }
1074
1075 @Test
1076 public void testMaxInt_emptyArray() {
1077 assertThrows(IllegalArgumentException.class, NumberUtils::max);
1078 }
1079
1080 @Test
1081 public void testMaxInt_nullArray() {
1082 assertThrows(NullPointerException.class, () -> NumberUtils.max((int[]) null));
1083 }
1084
1085 @Test
1086 public void testMaxLong() {
1087 assertEquals(5L, NumberUtils.max(5L), "max(long[]) failed for array length 1");
1088 assertEquals(9L, NumberUtils.max(6L, 9L), "max(long[]) failed for array length 2");
1089 assertEquals(10L, NumberUtils.max(-10L, -5L, 0L, 5L, 10L), "max(long[]) failed for array length 5");
1090 assertEquals(10L, NumberUtils.max(-10L, -5L, 0L, 5L, 10L));
1091 assertEquals(10L, NumberUtils.max(-5L, 0L, 10L, 5L, -10L));
1092 }
1093
1094 @Test
1095 public void testMaxLong_emptyArray() {
1096 assertThrows(IllegalArgumentException.class, NumberUtils::max);
1097 }
1098
1099 @Test
1100 public void testMaxLong_nullArray() {
1101 assertThrows(NullPointerException.class, () -> NumberUtils.max((long[]) null));
1102 }
1103
1104 @Test
1105 public void testMaxShort() {
1106 assertEquals((short) 5, NumberUtils.max((short) 5), "max(short[]) failed for array length 1");
1107 assertEquals((short) 9, NumberUtils.max((short) 6, (short) 9), "max(short[]) failed for array length 2");
1108 assertEquals((short) 10, NumberUtils.max((short) -10, (short) -5, (short) 0, (short) 5, (short) 10),
1109 "max(short[]) failed for array length 5");
1110 assertEquals((short) 10, NumberUtils.max((short) -10, (short) -5, (short) 0, (short) 5, (short) 10));
1111 assertEquals((short) 10, NumberUtils.max((short) -5, (short) 0, (short) 10, (short) 5, (short) -10));
1112 }
1113
1114 @Test
1115 public void testMaxShort_emptyArray() {
1116 assertThrows(IllegalArgumentException.class, NumberUtils::max);
1117 }
1118
1119 @Test
1120 public void testMaxShort_nullArray() {
1121 assertThrows(NullPointerException.class, () -> NumberUtils.max((short[]) null));
1122 }
1123
1124 @Test
1125 public void testMinByte() {
1126 assertEquals((byte) 5, NumberUtils.min((byte) 5), "min(byte[]) failed for array length 1");
1127 assertEquals((byte) 6, NumberUtils.min((byte) 6, (byte) 9), "min(byte[]) failed for array length 2");
1128
1129 assertEquals((byte) -10, NumberUtils.min((byte) -10, (byte) -5, (byte) 0, (byte) 5, (byte) 10));
1130 assertEquals((byte) -10, NumberUtils.min((byte) -5, (byte) 0, (byte) -10, (byte) 5, (byte) 10));
1131 }
1132
1133 @Test
1134 public void testMinByte_emptyArray() {
1135 assertThrows(IllegalArgumentException.class, NumberUtils::min);
1136 }
1137
1138 @Test
1139 public void testMinByte_nullArray() {
1140 assertThrows(NullPointerException.class, () -> NumberUtils.min((byte[]) null));
1141 }
1142
1143 @Test
1144 public void testMinDouble() {
1145 assertEquals(5.12, NumberUtils.min(5.12), "min(double[]) failed for array length 1");
1146 assertEquals(6.23, NumberUtils.min(6.23, 9.34), "min(double[]) failed for array length 2");
1147 assertEquals(-10.45, NumberUtils.min(-10.45, -5.56, 0, 5.67, 10.78), "min(double[]) failed for array length 5");
1148 assertEquals(-10, NumberUtils.min(-10, -5, 0, 5, 10), 0.0001);
1149 assertEquals(-10, NumberUtils.min(-5, 0, -10, 5, 10), 0.0001);
1150 }
1151
1152 @Test
1153 public void testMinDouble_emptyArray() {
1154 assertThrows(IllegalArgumentException.class, NumberUtils::min);
1155 }
1156
1157 @Test
1158 public void testMinDouble_nullArray() {
1159 assertThrows(NullPointerException.class, () -> NumberUtils.min((double[]) null));
1160 }
1161
1162 @Test
1163 public void testMinFloat() {
1164 assertEquals(5.9f, NumberUtils.min(5.9f), "min(float[]) failed for array length 1");
1165 assertEquals(6.8f, NumberUtils.min(6.8f, 9.7f), "min(float[]) failed for array length 2");
1166 assertEquals(-10.6f, NumberUtils.min(-10.6f, -5.5f, 0, 5.4f, 10.3f), "min(float[]) failed for array length 5");
1167 assertEquals(-10, NumberUtils.min(-10, -5, 0, 5, 10), 0.0001f);
1168 assertEquals(-10, NumberUtils.min(-5, 0, -10, 5, 10), 0.0001f);
1169 }
1170
1171 @Test
1172 public void testMinFloat_emptyArray() {
1173 assertThrows(IllegalArgumentException.class, NumberUtils::min);
1174 }
1175
1176 @Test
1177 public void testMinFloat_nullArray() {
1178 assertThrows(NullPointerException.class, () -> NumberUtils.min((float[]) null));
1179 }
1180
1181 @Test
1182 public void testMinimumByte() {
1183 final byte low = 123;
1184 final byte mid = 123 + 1;
1185 final byte high = 123 + 2;
1186 assertEquals(low, NumberUtils.min(low, mid, high), "minimum(byte, byte, byte) 1 failed");
1187 assertEquals(low, NumberUtils.min(mid, low, high), "minimum(byte, byte, byte) 2 failed");
1188 assertEquals(low, NumberUtils.min(mid, high, low), "minimum(byte, byte, byte) 3 failed");
1189 assertEquals(low, NumberUtils.min(low, mid, low), "minimum(byte, byte, byte) 4 failed");
1190 }
1191
1192 @Test
1193 public void testMinimumDouble() {
1194 final double low = 12.3;
1195 final double mid = 12.3 + 1;
1196 final double high = 12.3 + 2;
1197 assertEquals(low, NumberUtils.min(low, mid, high), 0.0001);
1198 assertEquals(low, NumberUtils.min(mid, low, high), 0.0001);
1199 assertEquals(low, NumberUtils.min(mid, high, low), 0.0001);
1200 assertEquals(low, NumberUtils.min(low, mid, low), 0.0001);
1201 assertEquals(mid, NumberUtils.min(high, mid, high), 0.0001);
1202 }
1203
1204 @Test
1205 public void testMinimumFloat() {
1206 final float low = 12.3f;
1207 final float mid = 12.3f + 1;
1208 final float high = 12.3f + 2;
1209 assertEquals(low, NumberUtils.min(low, mid, high), 0.0001f);
1210 assertEquals(low, NumberUtils.min(mid, low, high), 0.0001f);
1211 assertEquals(low, NumberUtils.min(mid, high, low), 0.0001f);
1212 assertEquals(low, NumberUtils.min(low, mid, low), 0.0001f);
1213 assertEquals(mid, NumberUtils.min(high, mid, high), 0.0001f);
1214 }
1215
1216 @Test
1217 public void testMinimumInt() {
1218 assertEquals(12345, NumberUtils.min(12345, 12345 + 1, 12345 + 2), "minimum(int, int, int) 1 failed");
1219 assertEquals(12345, NumberUtils.min(12345 + 1, 12345, 12345 + 2), "minimum(int, int, int) 2 failed");
1220 assertEquals(12345, NumberUtils.min(12345 + 1, 12345 + 2, 12345), "minimum(int, int, int) 3 failed");
1221 assertEquals(12345, NumberUtils.min(12345 + 1, 12345, 12345), "minimum(int, int, int) 4 failed");
1222 assertEquals(12345, NumberUtils.min(12345, 12345, 12345), "minimum(int, int, int) 5 failed");
1223 }
1224
1225 @Test
1226 public void testMinimumLong() {
1227 assertEquals(12345L, NumberUtils.min(12345L, 12345L + 1L, 12345L + 2L), "minimum(long, long, long) 1 failed");
1228 assertEquals(12345L, NumberUtils.min(12345L + 1L, 12345L, 12345 + 2L), "minimum(long, long, long) 2 failed");
1229 assertEquals(12345L, NumberUtils.min(12345L + 1L, 12345L + 2L, 12345L), "minimum(long, long, long) 3 failed");
1230 assertEquals(12345L, NumberUtils.min(12345L + 1L, 12345L, 12345L), "minimum(long, long, long) 4 failed");
1231 assertEquals(12345L, NumberUtils.min(12345L, 12345L, 12345L), "minimum(long, long, long) 5 failed");
1232 }
1233
1234 @Test
1235 public void testMinimumShort() {
1236 final short low = 1234;
1237 final short mid = 1234 + 1;
1238 final short high = 1234 + 2;
1239 assertEquals(low, NumberUtils.min(low, mid, high), "minimum(short, short, short) 1 failed");
1240 assertEquals(low, NumberUtils.min(mid, low, high), "minimum(short, short, short) 2 failed");
1241 assertEquals(low, NumberUtils.min(mid, high, low), "minimum(short, short, short) 3 failed");
1242 assertEquals(low, NumberUtils.min(low, mid, low), "minimum(short, short, short) 4 failed");
1243 }
1244
1245 @Test
1246 public void testMinInt() {
1247 assertEquals(5, NumberUtils.min(5), "min(int[]) failed for array length 1");
1248 assertEquals(6, NumberUtils.min(6, 9), "min(int[]) failed for array length 2");
1249
1250 assertEquals(-10, NumberUtils.min(-10, -5, 0, 5, 10));
1251 assertEquals(-10, NumberUtils.min(-5, 0, -10, 5, 10));
1252 }
1253
1254 @Test
1255 public void testMinInt_emptyArray() {
1256 assertThrows(IllegalArgumentException.class, NumberUtils::min);
1257 }
1258
1259 @Test
1260 public void testMinInt_nullArray() {
1261 assertThrows(NullPointerException.class, () -> NumberUtils.min((int[]) null));
1262 }
1263
1264 @Test
1265 public void testMinLong() {
1266 assertEquals(5L, NumberUtils.min(5L), "min(long[]) failed for array length 1");
1267 assertEquals(6L, NumberUtils.min(6L, 9L), "min(long[]) failed for array length 2");
1268
1269 assertEquals(-10L, NumberUtils.min(-10L, -5L, 0L, 5L, 10L));
1270 assertEquals(-10L, NumberUtils.min(-5L, 0L, -10L, 5L, 10L));
1271 }
1272
1273 @Test
1274 public void testMinLong_emptyArray() {
1275 assertThrows(IllegalArgumentException.class, NumberUtils::min);
1276 }
1277
1278 // min/max tests
1279 // ----------------------------------------------------------------------
1280 @Test
1281 public void testMinLong_nullArray() {
1282 assertThrows(NullPointerException.class, () -> NumberUtils.min((long[]) null));
1283 }
1284
1285 @Test
1286 public void testMinShort() {
1287 assertEquals((short) 5, NumberUtils.min((short) 5), "min(short[]) failed for array length 1");
1288 assertEquals((short) 6, NumberUtils.min((short) 6, (short) 9), "min(short[]) failed for array length 2");
1289
1290 assertEquals((short) -10, NumberUtils.min((short) -10, (short) -5, (short) 0, (short) 5, (short) 10));
1291 assertEquals((short) -10, NumberUtils.min((short) -5, (short) 0, (short) -10, (short) 5, (short) 10));
1292 }
1293
1294 @Test
1295 public void testMinShort_emptyArray() {
1296 assertThrows(IllegalArgumentException.class, NumberUtils::min);
1297 }
1298
1299 @Test
1300 public void testMinShort_nullArray() {
1301 assertThrows(NullPointerException.class, () -> NumberUtils.min((short[]) null));
1302 }
1303
1304 /**
1305 * Test for {(@link NumberUtils#createNumber(String)}
1306 */
1307 @Test
1308 public void testStringCreateNumberEnsureNoPrecisionLoss() {
1309 final String shouldBeFloat = "1.23";
1310 final String shouldBeDouble = "3.40282354e+38";
1311 final String shouldBeBigDecimal = "1.797693134862315759e+308";
1312 assertTrue(NumberUtils.createNumber(shouldBeFloat) instanceof Float);
1313 assertTrue(NumberUtils.createNumber(shouldBeDouble) instanceof Double);
1314 assertTrue(NumberUtils.createNumber(shouldBeBigDecimal) instanceof BigDecimal);
1315 // LANG-1060
1316 assertTrue(NumberUtils.createNumber("001.12") instanceof Float);
1317 assertTrue(NumberUtils.createNumber("-001.12") instanceof Float);
1318 assertTrue(NumberUtils.createNumber("+001.12") instanceof Float);
1319 assertTrue(NumberUtils.createNumber("003.40282354e+38") instanceof Double);
1320 assertTrue(NumberUtils.createNumber("-003.40282354e+38") instanceof Double);
1321 assertTrue(NumberUtils.createNumber("+003.40282354e+38") instanceof Double);
1322 assertTrue(NumberUtils.createNumber("0001.797693134862315759e+308") instanceof BigDecimal);
1323 assertTrue(NumberUtils.createNumber("-001.797693134862315759e+308") instanceof BigDecimal);
1324 assertTrue(NumberUtils.createNumber("+001.797693134862315759e+308") instanceof BigDecimal);
1325 //LANG-1613
1326 assertTrue(NumberUtils.createNumber(Double.toString(Double.MIN_NORMAL)) instanceof Double);
1327 assertTrue(NumberUtils.createNumber(Double.toString(Double.MIN_NORMAL) + "D") instanceof Double);
1328 assertTrue(NumberUtils.createNumber(Double.toString(Double.MIN_NORMAL) + "F") instanceof Double);
1329 assertTrue(NumberUtils.createNumber(Double.toString(Double.MIN_VALUE)) instanceof Double);
1330 assertTrue(NumberUtils.createNumber(Double.toString(Double.MIN_VALUE) + "D") instanceof Double);
1331 assertTrue(NumberUtils.createNumber(Double.toString(Double.MIN_VALUE) + "F") instanceof Double);
1332 assertTrue(NumberUtils.createNumber(Double.toString(Double.MAX_VALUE)) instanceof Double);
1333 assertTrue(NumberUtils.createNumber(Double.toString(Double.MAX_VALUE) + "D") instanceof Double);
1334 assertTrue(NumberUtils.createNumber(Double.toString(Double.MAX_VALUE) + "F") instanceof Double);
1335 assertTrue(NumberUtils.createNumber("4.9e-324D") instanceof Double);
1336 assertTrue(NumberUtils.createNumber("4.9e-324F") instanceof Double);
1337 }
1338
1339 /**
1340 * Test for {@link NumberUtils#toDouble(String)}.
1341 */
1342 @Test
1343 public void testStringToDoubleString() {
1344 assertEquals(NumberUtils.toDouble("-1.2345"), -1.2345d, "toDouble(String) 1 failed");
1345 assertEquals(1.2345d, NumberUtils.toDouble("1.2345"), "toDouble(String) 2 failed");
1346 assertEquals(0.0d, NumberUtils.toDouble("abc"), "toDouble(String) 3 failed");
1347 // LANG-1060
1348 assertEquals(NumberUtils.toDouble("-001.2345"), -1.2345d, "toDouble(String) 4 failed");
1349 assertEquals(1.2345d, NumberUtils.toDouble("+001.2345"), "toDouble(String) 5 failed");
1350 assertEquals(1.2345d, NumberUtils.toDouble("001.2345"), "toDouble(String) 6 failed");
1351 assertEquals(0d, NumberUtils.toDouble("000.00000"), "toDouble(String) 7 failed");
1352
1353 assertEquals(NumberUtils.toDouble(Double.MAX_VALUE + ""), Double.MAX_VALUE,
1354 "toDouble(Double.MAX_VALUE) failed");
1355 assertEquals(NumberUtils.toDouble(Double.MIN_VALUE + ""), Double.MIN_VALUE,
1356 "toDouble(Double.MIN_VALUE) failed");
1357 assertEquals(0.0d, NumberUtils.toDouble(""), "toDouble(empty) failed");
1358 assertEquals(0.0d, NumberUtils.toDouble((String) null), "toDouble(null) failed");
1359 }
1360
1361 /**
1362 * Test for {@link NumberUtils#toDouble(String, double)}.
1363 */
1364 @Test
1365 public void testStringToDoubleStringD() {
1366 assertEquals(1.2345d, NumberUtils.toDouble("1.2345", 5.1d), "toDouble(String, int) 1 failed");
1367 assertEquals(5.0d, NumberUtils.toDouble("a", 5.0d), "toDouble(String, int) 2 failed");
1368 // LANG-1060
1369 assertEquals(1.2345d, NumberUtils.toDouble("001.2345", 5.1d), "toDouble(String, int) 3 failed");
1370 assertEquals(NumberUtils.toDouble("-001.2345", 5.1d), -1.2345d, "toDouble(String, int) 4 failed");
1371 assertEquals(1.2345d, NumberUtils.toDouble("+001.2345", 5.1d), "toDouble(String, int) 5 failed");
1372 assertEquals(0d, NumberUtils.toDouble("000.00", 5.1d), "toDouble(String, int) 7 failed");
1373 }
1374
1375 /**
1376 * Test for {@link NumberUtils#toByte(String)}.
1377 */
1378 @Test
1379 public void testToByteString() {
1380 assertEquals(123, NumberUtils.toByte("123"), "toByte(String) 1 failed");
1381 assertEquals(0, NumberUtils.toByte("abc"), "toByte(String) 2 failed");
1382 assertEquals(0, NumberUtils.toByte(""), "toByte(empty) failed");
1383 assertEquals(0, NumberUtils.toByte(null), "toByte(null) failed");
1384 }
1385
1386 /**
1387 * Test for {@link NumberUtils#toByte(String, byte)}.
1388 */
1389 @Test
1390 public void testToByteStringI() {
1391 assertEquals(123, NumberUtils.toByte("123", (byte) 5), "toByte(String, byte) 1 failed");
1392 assertEquals(5, NumberUtils.toByte("12.3", (byte) 5), "toByte(String, byte) 2 failed");
1393 }
1394
1395 /**
1396 * Test for {@link NumberUtils#toFloat(String)}.
1397 */
1398 @Test
1399 public void testToFloatString() {
1400 assertEquals(NumberUtils.toFloat("-1.2345"), -1.2345f, "toFloat(String) 1 failed");
1401 assertEquals(1.2345f, NumberUtils.toFloat("1.2345"), "toFloat(String) 2 failed");
1402 assertEquals(0.0f, NumberUtils.toFloat("abc"), "toFloat(String) 3 failed");
1403 // LANG-1060
1404 assertEquals(NumberUtils.toFloat("-001.2345"), -1.2345f, "toFloat(String) 4 failed");
1405 assertEquals(1.2345f, NumberUtils.toFloat("+001.2345"), "toFloat(String) 5 failed");
1406 assertEquals(1.2345f, NumberUtils.toFloat("001.2345"), "toFloat(String) 6 failed");
1407 assertEquals(0f, NumberUtils.toFloat("000.00"), "toFloat(String) 7 failed");
1408
1409 assertEquals(NumberUtils.toFloat(Float.MAX_VALUE + ""), Float.MAX_VALUE, "toFloat(Float.MAX_VALUE) failed");
1410 assertEquals(NumberUtils.toFloat(Float.MIN_VALUE + ""), Float.MIN_VALUE, "toFloat(Float.MIN_VALUE) failed");
1411 assertEquals(0.0f, NumberUtils.toFloat(""), "toFloat(empty) failed");
1412 assertEquals(0.0f, NumberUtils.toFloat(null), "toFloat(null) failed");
1413 }
1414
1415 /**
1416 * Test for {@link NumberUtils#toFloat(String, float)}.
1417 */
1418 @Test
1419 public void testToFloatStringF() {
1420 assertEquals(1.2345f, NumberUtils.toFloat("1.2345", 5.1f), "toFloat(String, int) 1 failed");
1421 assertEquals(5.0f, NumberUtils.toFloat("a", 5.0f), "toFloat(String, int) 2 failed");
1422 // LANG-1060
1423 assertEquals(5.0f, NumberUtils.toFloat("-001Z.2345", 5.0f), "toFloat(String, int) 3 failed");
1424 assertEquals(5.0f, NumberUtils.toFloat("+001AB.2345", 5.0f), "toFloat(String, int) 4 failed");
1425 assertEquals(5.0f, NumberUtils.toFloat("001Z.2345", 5.0f), "toFloat(String, int) 5 failed");
1426 }
1427
1428 /**
1429 * Test for {@link NumberUtils#toInt(String)}.
1430 */
1431 @Test
1432 public void testToIntString() {
1433 assertEquals(12345, NumberUtils.toInt("12345"), "toInt(String) 1 failed");
1434 assertEquals(0, NumberUtils.toInt("abc"), "toInt(String) 2 failed");
1435 assertEquals(0, NumberUtils.toInt(""), "toInt(empty) failed");
1436 assertEquals(0, NumberUtils.toInt(null), "toInt(null) failed");
1437 }
1438
1439 /**
1440 * Test for {@link NumberUtils#toInt(String, int)}.
1441 */
1442 @Test
1443 public void testToIntStringI() {
1444 assertEquals(12345, NumberUtils.toInt("12345", 5), "toInt(String, int) 1 failed");
1445 assertEquals(5, NumberUtils.toInt("1234.5", 5), "toInt(String, int) 2 failed");
1446 }
1447
1448 /**
1449 * Test for {@link NumberUtils#toLong(String)}.
1450 */
1451 @Test
1452 public void testToLongString() {
1453 assertEquals(12345L, NumberUtils.toLong("12345"), "toLong(String) 1 failed");
1454 assertEquals(0L, NumberUtils.toLong("abc"), "toLong(String) 2 failed");
1455 assertEquals(0L, NumberUtils.toLong("1L"), "toLong(String) 3 failed");
1456 assertEquals(0L, NumberUtils.toLong("1l"), "toLong(String) 4 failed");
1457 assertEquals(NumberUtils.toLong(Long.MAX_VALUE + ""), Long.MAX_VALUE, "toLong(Long.MAX_VALUE) failed");
1458 assertEquals(NumberUtils.toLong(Long.MIN_VALUE + ""), Long.MIN_VALUE, "toLong(Long.MIN_VALUE) failed");
1459 assertEquals(0L, NumberUtils.toLong(""), "toLong(empty) failed");
1460 assertEquals(0L, NumberUtils.toLong(null), "toLong(null) failed");
1461 }
1462
1463 /**
1464 * Test for {@link NumberUtils#toLong(String, long)}.
1465 */
1466 @Test
1467 public void testToLongStringL() {
1468 assertEquals(12345L, NumberUtils.toLong("12345", 5L), "toLong(String, long) 1 failed");
1469 assertEquals(5L, NumberUtils.toLong("1234.5", 5L), "toLong(String, long) 2 failed");
1470 }
1471
1472 /**
1473 * Test for {@link NumberUtils#toScaledBigDecimal(BigDecimal)}.
1474 */
1475 @Test
1476 public void testToScaledBigDecimalBigDecimal() {
1477 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(123.456)), BigDecimal.valueOf(123.46),
1478 "toScaledBigDecimal(BigDecimal) 1 failed");
1479 // Test RoudingMode.HALF_EVEN default rounding.
1480 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.515)), BigDecimal.valueOf(23.52),
1481 "toScaledBigDecimal(BigDecimal) 2 failed");
1482 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.525)), BigDecimal.valueOf(23.52),
1483 "toScaledBigDecimal(BigDecimal) 3 failed");
1484 assertEquals("2352.00",
1485 NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.525)).multiply(BigDecimal.valueOf(100)).toString(),
1486 "toScaledBigDecimal(BigDecimal) 4 failed");
1487 assertEquals(NumberUtils.toScaledBigDecimal((BigDecimal) null), BigDecimal.ZERO,
1488 "toScaledBigDecimal(BigDecimal) 5 failed");
1489 }
1490
1491 /**
1492 * Test for {@link NumberUtils#toScaledBigDecimal(BigDecimal, int, RoundingMode)}.
1493 */
1494 @Test
1495 public void testToScaledBigDecimalBigDecimalIRM() {
1496 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(123.456), 1, RoundingMode.CEILING),
1497 BigDecimal.valueOf(123.5), "toScaledBigDecimal(BigDecimal, int, RoudingMode) 1 failed");
1498 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.5159), 3, RoundingMode.FLOOR),
1499 BigDecimal.valueOf(23.515), "toScaledBigDecimal(BigDecimal, int, RoudingMode) 2 failed");
1500 assertEquals(NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.525), 2, RoundingMode.HALF_UP),
1501 BigDecimal.valueOf(23.53), "toScaledBigDecimal(BigDecimal, int, RoudingMode) 3 failed");
1502 assertEquals("23521.0000",
1503 NumberUtils.toScaledBigDecimal(BigDecimal.valueOf(23.521), 4, RoundingMode.HALF_EVEN)
1504 .multiply(BigDecimal.valueOf(1000)).toString(),
1505 "toScaledBigDecimal(BigDecimal, int, RoudingMode) 4 failed");
1506 assertEquals(NumberUtils.toScaledBigDecimal((BigDecimal) null, 2, RoundingMode.HALF_UP), BigDecimal.ZERO,
1507 "toScaledBigDecimal(BigDecimal, int, RoudingMode) 5 failed");
1508 }
1509
1510 /**
1511 * Test for {@link NumberUtils#toScaledBigDecimal(Double)}.
1512 */
1513 @Test
1514 public void testToScaledBigDecimalDouble() {
1515 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(123.456d)), BigDecimal.valueOf(123.46),
1516 "toScaledBigDecimal(Double) 1 failed");
1517 // Test RoudingMode.HALF_EVEN default rounding.
1518 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(23.515d)), BigDecimal.valueOf(23.52),
1519 "toScaledBigDecimal(Double) 2 failed");
1520 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(23.525d)), BigDecimal.valueOf(23.52),
1521 "toScaledBigDecimal(Double) 3 failed");
1522 assertEquals("2352.00",
1523 NumberUtils.toScaledBigDecimal(Double.valueOf(23.525d)).multiply(BigDecimal.valueOf(100)).toString(),
1524 "toScaledBigDecimal(Double) 4 failed");
1525 assertEquals(NumberUtils.toScaledBigDecimal((Double) null), BigDecimal.ZERO,
1526 "toScaledBigDecimal(Double) 5 failed");
1527 }
1528
1529 /**
1530 * Test for {@link NumberUtils#toScaledBigDecimal(Double, int, RoundingMode)}.
1531 */
1532 @Test
1533 public void testToScaledBigDecimalDoubleIRM() {
1534 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(123.456d), 1, RoundingMode.CEILING),
1535 BigDecimal.valueOf(123.5), "toScaledBigDecimal(Double, int, RoudingMode) 1 failed");
1536 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(23.5159d), 3, RoundingMode.FLOOR),
1537 BigDecimal.valueOf(23.515), "toScaledBigDecimal(Double, int, RoudingMode) 2 failed");
1538 assertEquals(NumberUtils.toScaledBigDecimal(Double.valueOf(23.525d), 2, RoundingMode.HALF_UP),
1539 BigDecimal.valueOf(23.53), "toScaledBigDecimal(Double, int, RoudingMode) 3 failed");
1540 assertEquals("23521.0000",
1541 NumberUtils.toScaledBigDecimal(Double.valueOf(23.521d), 4, RoundingMode.HALF_EVEN)
1542 .multiply(BigDecimal.valueOf(1000)).toString(),
1543 "toScaledBigDecimal(Double, int, RoudingMode) 4 failed");
1544 assertEquals(NumberUtils.toScaledBigDecimal((Double) null, 2, RoundingMode.HALF_UP), BigDecimal.ZERO,
1545 "toScaledBigDecimal(Double, int, RoudingMode) 5 failed");
1546 }
1547
1548 /**
1549 * Test for {@link NumberUtils#toScaledBigDecimal(Float)}.
1550 */
1551 @Test
1552 public void testToScaledBigDecimalFloat() {
1553 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(123.456f)), BigDecimal.valueOf(123.46),
1554 "toScaledBigDecimal(Float) 1 failed");
1555 // Test RoudingMode.HALF_EVEN default rounding.
1556 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(23.515f)), BigDecimal.valueOf(23.51),
1557 "toScaledBigDecimal(Float) 2 failed");
1558 // Note. NumberUtils.toScaledBigDecimal(Float.valueOf(23.515f)).equals(BigDecimal.valueOf(23.51))
1559 // because of roundoff error. It is ok.
1560 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(23.525f)), BigDecimal.valueOf(23.52),
1561 "toScaledBigDecimal(Float) 3 failed");
1562 assertEquals("2352.00",
1563 NumberUtils.toScaledBigDecimal(Float.valueOf(23.525f)).multiply(BigDecimal.valueOf(100)).toString(),
1564 "toScaledBigDecimal(Float) 4 failed");
1565 assertEquals(NumberUtils.toScaledBigDecimal((Float) null), BigDecimal.ZERO,
1566 "toScaledBigDecimal(Float) 5 failed");
1567 }
1568
1569 /**
1570 * Test for {@link NumberUtils#toScaledBigDecimal(Float, int, RoundingMode)}.
1571 */
1572 @Test
1573 public void testToScaledBigDecimalFloatIRM() {
1574 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(123.456f), 1, RoundingMode.CEILING),
1575 BigDecimal.valueOf(123.5), "toScaledBigDecimal(Float, int, RoudingMode) 1 failed");
1576 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(23.5159f), 3, RoundingMode.FLOOR),
1577 BigDecimal.valueOf(23.515), "toScaledBigDecimal(Float, int, RoudingMode) 2 failed");
1578 // The following happens due to roundoff error. We're ok with this.
1579 assertEquals(NumberUtils.toScaledBigDecimal(Float.valueOf(23.525f), 2, RoundingMode.HALF_UP),
1580 BigDecimal.valueOf(23.52), "toScaledBigDecimal(Float, int, RoudingMode) 3 failed");
1581 assertEquals("23521.0000", NumberUtils.toScaledBigDecimal(Float.valueOf(23.521f), 4, RoundingMode.HALF_EVEN)
1582 .multiply(BigDecimal.valueOf(1000)).toString(), "toScaledBigDecimal(Float, int, RoudingMode) 4 failed");
1583 assertEquals(NumberUtils.toScaledBigDecimal((Float) null, 2, RoundingMode.HALF_UP), BigDecimal.ZERO,
1584 "toScaledBigDecimal(Float, int, RoudingMode) 5 failed");
1585 }
1586
1587 /**
1588 * Test for {@link NumberUtils#toScaledBigDecimal(Double)}.
1589 */
1590 @Test
1591 public void testToScaledBigDecimalString() {
1592 assertEquals(NumberUtils.toScaledBigDecimal("123.456"), BigDecimal.valueOf(123.46),
1593 "toScaledBigDecimal(String) 1 failed");
1594 // Test RoudingMode.HALF_EVEN default rounding.
1595 assertEquals(NumberUtils.toScaledBigDecimal("23.515"), BigDecimal.valueOf(23.52),
1596 "toScaledBigDecimal(String) 2 failed");
1597 assertEquals(NumberUtils.toScaledBigDecimal("23.525"), BigDecimal.valueOf(23.52),
1598 "toScaledBigDecimal(String) 3 failed");
1599 assertEquals("2352.00", NumberUtils.toScaledBigDecimal("23.525").multiply(BigDecimal.valueOf(100)).toString(),
1600 "toScaledBigDecimal(String) 4 failed");
1601 assertEquals(NumberUtils.toScaledBigDecimal((String) null), BigDecimal.ZERO,
1602 "toScaledBigDecimal(String) 5 failed");
1603 }
1604
1605 /**
1606 * Test for {@link NumberUtils#toScaledBigDecimal(Double, int, RoundingMode)}.
1607 */
1608 @Test
1609 public void testToScaledBigDecimalStringIRM() {
1610 assertEquals(NumberUtils.toScaledBigDecimal("123.456", 1, RoundingMode.CEILING), BigDecimal.valueOf(123.5),
1611 "toScaledBigDecimal(String, int, RoudingMode) 1 failed");
1612 assertEquals(NumberUtils.toScaledBigDecimal("23.5159", 3, RoundingMode.FLOOR), BigDecimal.valueOf(23.515),
1613 "toScaledBigDecimal(String, int, RoudingMode) 2 failed");
1614 assertEquals(NumberUtils.toScaledBigDecimal("23.525", 2, RoundingMode.HALF_UP), BigDecimal.valueOf(23.53),
1615 "toScaledBigDecimal(String, int, RoudingMode) 3 failed");
1616 assertEquals(
1617 "23521.0000", NumberUtils.toScaledBigDecimal("23.521", 4, RoundingMode.HALF_EVEN)
1618 .multiply(BigDecimal.valueOf(1000)).toString(),
1619 "toScaledBigDecimal(String, int, RoudingMode) 4 failed");
1620 assertEquals(NumberUtils.toScaledBigDecimal((String) null, 2, RoundingMode.HALF_UP), BigDecimal.ZERO,
1621 "toScaledBigDecimal(String, int, RoudingMode) 5 failed");
1622 }
1623
1624 /**
1625 * Test for {@link NumberUtils#toShort(String)}.
1626 */
1627 @Test
1628 public void testToShortString() {
1629 assertEquals(12345, NumberUtils.toShort("12345"), "toShort(String) 1 failed");
1630 assertEquals(0, NumberUtils.toShort("abc"), "toShort(String) 2 failed");
1631 assertEquals(0, NumberUtils.toShort(""), "toShort(empty) failed");
1632 assertEquals(0, NumberUtils.toShort(null), "toShort(null) failed");
1633 }
1634
1635 /**
1636 * Test for {@link NumberUtils#toShort(String, short)}.
1637 */
1638 @Test
1639 public void testToShortStringI() {
1640 assertEquals(12345, NumberUtils.toShort("12345", (short) 5), "toShort(String, short) 1 failed");
1641 assertEquals(5, NumberUtils.toShort("1234.5", (short) 5), "toShort(String, short) 2 failed");
15761642 }
15771643 }
4949 assertThrows(NullPointerException.class, () -> mutBool.compareTo(null));
5050 }
5151
52 @Test
53 public void testConstructorNull() {
54 assertThrows(NullPointerException.class, () -> new MutableBoolean(null));
55 }
56
5257 // ----------------------------------------------------------------
5358 @Test
5459 public void testConstructors() {
6065 assertTrue(new MutableBoolean(Boolean.TRUE).booleanValue());
6166 assertFalse(new MutableBoolean(Boolean.FALSE).booleanValue());
6267
63 }
64
65 @Test
66 public void testConstructorNull() {
67 assertThrows(NullPointerException.class, () -> new MutableBoolean(null));
6868 }
6969
7070 @Test
117117 }
118118
119119 @Test
120 public void testSetNull() {
121 final MutableBoolean mutBool = new MutableBoolean(false);
122 assertThrows(NullPointerException.class, () -> mutBool.setValue(null));
123 }
124
125 @Test
126120 public void testHashCode() {
127121 final MutableBoolean mutBoolA = new MutableBoolean(false);
128122 final MutableBoolean mutBoolB = new MutableBoolean(false);
136130 }
137131
138132 @Test
133 public void testSetNull() {
134 final MutableBoolean mutBool = new MutableBoolean(false);
135 assertThrows(NullPointerException.class, () -> mutBool.setValue(null));
136 }
137
138 @Test
139139 public void testToString() {
140140 assertEquals(Boolean.FALSE.toString(), new MutableBoolean(false).toString());
141141 assertEquals(Boolean.TRUE.toString(), new MutableBoolean(true).toString());
2828 */
2929 public class MutableByteTest {
3030
31 @Test
32 public void testAddAndGetValueObject() {
33 final MutableByte mutableByte = new MutableByte((byte) 0);
34 final byte result = mutableByte.addAndGet(Byte.valueOf((byte) 1));
35
36 assertEquals((byte) 1, result);
37 assertEquals((byte) 1, mutableByte.byteValue());
38 }
39
40 @Test
41 public void testAddAndGetValuePrimitive() {
42 final MutableByte mutableByte = new MutableByte((byte) 0);
43 final byte result = mutableByte.addAndGet((byte) 1);
44
45 assertEquals((byte) 1, result);
46 assertEquals((byte) 1, mutableByte.byteValue());
47 }
48
49 @Test
50 public void testAddValueObject() {
51 final MutableByte mutNum = new MutableByte((byte) 1);
52 mutNum.add(Integer.valueOf(1));
53
54 assertEquals((byte) 2, mutNum.byteValue());
55 }
56
57 @Test
58 public void testAddValuePrimitive() {
59 final MutableByte mutNum = new MutableByte((byte) 1);
60 mutNum.add((byte) 1);
61
62 assertEquals((byte) 2, mutNum.byteValue());
63 }
64
65 @Test
66 public void testCompareTo() {
67 final MutableByte mutNum = new MutableByte((byte) 0);
68
69 assertEquals((byte) 0, mutNum.compareTo(new MutableByte((byte) 0)));
70 assertEquals((byte) +1, mutNum.compareTo(new MutableByte((byte) -1)));
71 assertEquals((byte) -1, mutNum.compareTo(new MutableByte((byte) 1)));
72 }
73
74 @Test
75 public void testCompareToNull() {
76 final MutableByte mutNum = new MutableByte((byte) 0);
77 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
78 }
79
80 @Test
81 public void testConstructorNull() {
82 assertThrows(NullPointerException.class, () -> new MutableByte((Number) null));
83 }
84
3185 // ----------------------------------------------------------------
3286 @Test
3387 public void testConstructors() {
4397 }
4498
4599 @Test
46 public void testConstructorNull() {
47 assertThrows(NullPointerException.class, () -> new MutableByte((Number) null));
48 }
49
50 @Test
51 public void testGetSet() {
52 final MutableByte mutNum = new MutableByte((byte) 0);
53 assertEquals((byte) 0, new MutableByte().byteValue());
54 assertEquals(Byte.valueOf((byte) 0), new MutableByte().getValue());
55
56 mutNum.setValue((byte) 1);
57 assertEquals((byte) 1, mutNum.byteValue());
58 assertEquals(Byte.valueOf((byte) 1), mutNum.getValue());
59
60 mutNum.setValue(Byte.valueOf((byte) 2));
61 assertEquals((byte) 2, mutNum.byteValue());
62 assertEquals(Byte.valueOf((byte) 2), mutNum.getValue());
63
64 mutNum.setValue(new MutableByte((byte) 3));
65 assertEquals((byte) 3, mutNum.byteValue());
66 assertEquals(Byte.valueOf((byte) 3), mutNum.getValue());
67 }
68
69 @Test
70 public void testSetNull() {
71 final MutableByte mutNum = new MutableByte((byte) 0);
72 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
100 public void testDecrement() {
101 final MutableByte mutNum = new MutableByte((byte) 1);
102 mutNum.decrement();
103
104 assertEquals(0, mutNum.intValue());
105 assertEquals(0L, mutNum.longValue());
106 }
107
108 @Test
109 public void testDecrementAndGet() {
110 final MutableByte mutNum = new MutableByte((byte) 1);
111 final byte result = mutNum.decrementAndGet();
112
113 assertEquals(0, result);
114 assertEquals(0, mutNum.intValue());
115 assertEquals(0L, mutNum.longValue());
73116 }
74117
75118 @Test
91134 }
92135
93136 @Test
137 public void testGetAndAddValueObject() {
138 final MutableByte mutableByte = new MutableByte((byte) 0);
139 final byte result = mutableByte.getAndAdd(Byte.valueOf((byte) 1));
140
141 assertEquals((byte) 0, result);
142 assertEquals((byte) 1, mutableByte.byteValue());
143 }
144
145 @Test
146 public void testGetAndAddValuePrimitive() {
147 final MutableByte mutableByte = new MutableByte((byte) 0);
148 final byte result = mutableByte.getAndAdd((byte) 1);
149
150 assertEquals((byte) 0, result);
151 assertEquals((byte) 1, mutableByte.byteValue());
152 }
153
154 @Test
155 public void testGetAndDecrement() {
156 final MutableByte mutNum = new MutableByte((byte) 1);
157 final byte result = mutNum.getAndDecrement();
158
159 assertEquals(1, result);
160 assertEquals(0, mutNum.intValue());
161 assertEquals(0L, mutNum.longValue());
162 }
163
164 @Test
165 public void testGetAndIncrement() {
166 final MutableByte mutNum = new MutableByte((byte) 1);
167 final byte result = mutNum.getAndIncrement();
168
169 assertEquals(1, result);
170 assertEquals(2, mutNum.intValue());
171 assertEquals(2L, mutNum.longValue());
172 }
173
174 @Test
175 public void testGetSet() {
176 final MutableByte mutNum = new MutableByte((byte) 0);
177 assertEquals((byte) 0, new MutableByte().byteValue());
178 assertEquals(Byte.valueOf((byte) 0), new MutableByte().getValue());
179
180 mutNum.setValue((byte) 1);
181 assertEquals((byte) 1, mutNum.byteValue());
182 assertEquals(Byte.valueOf((byte) 1), mutNum.getValue());
183
184 mutNum.setValue(Byte.valueOf((byte) 2));
185 assertEquals((byte) 2, mutNum.byteValue());
186 assertEquals(Byte.valueOf((byte) 2), mutNum.getValue());
187
188 mutNum.setValue(new MutableByte((byte) 3));
189 assertEquals((byte) 3, mutNum.byteValue());
190 assertEquals(Byte.valueOf((byte) 3), mutNum.getValue());
191 }
192
193 @Test
94194 public void testHashCode() {
95195 final MutableByte mutNumA = new MutableByte((byte) 0);
96196 final MutableByte mutNumB = new MutableByte((byte) 0);
103203 }
104204
105205 @Test
106 public void testCompareTo() {
107 final MutableByte mutNum = new MutableByte((byte) 0);
108
109 assertEquals((byte) 0, mutNum.compareTo(new MutableByte((byte) 0)));
110 assertEquals((byte) +1, mutNum.compareTo(new MutableByte((byte) -1)));
111 assertEquals((byte) -1, mutNum.compareTo(new MutableByte((byte) 1)));
112 }
113
114 @Test
115 public void testCompareToNull() {
116 final MutableByte mutNum = new MutableByte((byte) 0);
117 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
206 public void testIncrement() {
207 final MutableByte mutNum = new MutableByte((byte) 1);
208 mutNum.increment();
209
210 assertEquals(2, mutNum.intValue());
211 assertEquals(2L, mutNum.longValue());
212 }
213
214 @Test
215 public void testIncrementAndGet() {
216 final MutableByte mutNum = new MutableByte((byte) 1);
217 final byte result = mutNum.incrementAndGet();
218
219 assertEquals(2, result);
220 assertEquals(2, mutNum.intValue());
221 assertEquals(2L, mutNum.longValue());
118222 }
119223
120224 @Test
129233 }
130234
131235 @Test
236 public void testSetNull() {
237 final MutableByte mutNum = new MutableByte((byte) 0);
238 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
239 }
240
241 @Test
242 public void testSubtractValueObject() {
243 final MutableByte mutNum = new MutableByte((byte) 1);
244 mutNum.subtract(Integer.valueOf(1));
245
246 assertEquals((byte) 0, mutNum.byteValue());
247 }
248
249 @Test
250 public void testSubtractValuePrimitive() {
251 final MutableByte mutNum = new MutableByte((byte) 1);
252 mutNum.subtract((byte) 1);
253
254 assertEquals((byte) 0, mutNum.byteValue());
255 }
256
257 @Test
132258 public void testToByte() {
133259 assertEquals(Byte.valueOf((byte) 0), new MutableByte((byte) 0).toByte());
134260 assertEquals(Byte.valueOf((byte) 123), new MutableByte((byte) 123).toByte());
135 }
136
137 @Test
138 public void testIncrement() {
139 final MutableByte mutNum = new MutableByte((byte) 1);
140 mutNum.increment();
141
142 assertEquals(2, mutNum.intValue());
143 assertEquals(2L, mutNum.longValue());
144 }
145
146 @Test
147 public void testIncrementAndGet() {
148 final MutableByte mutNum = new MutableByte((byte) 1);
149 final byte result = mutNum.incrementAndGet();
150
151 assertEquals(2, result);
152 assertEquals(2, mutNum.intValue());
153 assertEquals(2L, mutNum.longValue());
154 }
155
156 @Test
157 public void testGetAndIncrement() {
158 final MutableByte mutNum = new MutableByte((byte) 1);
159 final byte result = mutNum.getAndIncrement();
160
161 assertEquals(1, result);
162 assertEquals(2, mutNum.intValue());
163 assertEquals(2L, mutNum.longValue());
164 }
165
166 @Test
167 public void testDecrement() {
168 final MutableByte mutNum = new MutableByte((byte) 1);
169 mutNum.decrement();
170
171 assertEquals(0, mutNum.intValue());
172 assertEquals(0L, mutNum.longValue());
173 }
174
175 @Test
176 public void testDecrementAndGet() {
177 final MutableByte mutNum = new MutableByte((byte) 1);
178 final byte result = mutNum.decrementAndGet();
179
180 assertEquals(0, result);
181 assertEquals(0, mutNum.intValue());
182 assertEquals(0L, mutNum.longValue());
183 }
184
185 @Test
186 public void testGetAndDecrement() {
187 final MutableByte mutNum = new MutableByte((byte) 1);
188 final byte result = mutNum.getAndDecrement();
189
190 assertEquals(1, result);
191 assertEquals(0, mutNum.intValue());
192 assertEquals(0L, mutNum.longValue());
193 }
194
195 @Test
196 public void testAddValuePrimitive() {
197 final MutableByte mutNum = new MutableByte((byte) 1);
198 mutNum.add((byte) 1);
199
200 assertEquals((byte) 2, mutNum.byteValue());
201 }
202
203 @Test
204 public void testAddValueObject() {
205 final MutableByte mutNum = new MutableByte((byte) 1);
206 mutNum.add(Integer.valueOf(1));
207
208 assertEquals((byte) 2, mutNum.byteValue());
209 }
210
211 @Test
212 public void testGetAndAddValuePrimitive() {
213 final MutableByte mutableByte = new MutableByte((byte) 0);
214 final byte result = mutableByte.getAndAdd((byte) 1);
215
216 assertEquals((byte) 0, result);
217 assertEquals((byte) 1, mutableByte.byteValue());
218 }
219
220 @Test
221 public void testGetAndAddValueObject() {
222 final MutableByte mutableByte = new MutableByte((byte) 0);
223 final byte result = mutableByte.getAndAdd(Byte.valueOf((byte) 1));
224
225 assertEquals((byte) 0, result);
226 assertEquals((byte) 1, mutableByte.byteValue());
227 }
228
229 @Test
230 public void testAddAndGetValuePrimitive() {
231 final MutableByte mutableByte = new MutableByte((byte) 0);
232 final byte result = mutableByte.addAndGet((byte) 1);
233
234 assertEquals((byte) 1, result);
235 assertEquals((byte) 1, mutableByte.byteValue());
236 }
237
238 @Test
239 public void testAddAndGetValueObject() {
240 final MutableByte mutableByte = new MutableByte((byte) 0);
241 final byte result = mutableByte.addAndGet(Byte.valueOf((byte) 1));
242
243 assertEquals((byte) 1, result);
244 assertEquals((byte) 1, mutableByte.byteValue());
245 }
246
247 @Test
248 public void testSubtractValuePrimitive() {
249 final MutableByte mutNum = new MutableByte((byte) 1);
250 mutNum.subtract((byte) 1);
251
252 assertEquals((byte) 0, mutNum.byteValue());
253 }
254
255 @Test
256 public void testSubtractValueObject() {
257 final MutableByte mutNum = new MutableByte((byte) 1);
258 mutNum.subtract(Integer.valueOf(1));
259
260 assertEquals((byte) 0, mutNum.byteValue());
261261 }
262262
263263 @Test
2929 */
3030 public class MutableDoubleTest {
3131
32 @Test
33 public void testAddAndGetValueObject() {
34 final MutableDouble mutableDouble = new MutableDouble(7.5d);
35 final double result = mutableDouble.addAndGet(Double.valueOf(-2.5d));
36
37 assertEquals(5d, result, 0.01d);
38 assertEquals(5d, mutableDouble.doubleValue(), 0.01d);
39 }
40
41 @Test
42 public void testAddAndGetValuePrimitive() {
43 final MutableDouble mutableDouble = new MutableDouble(10.5d);
44 final double result = mutableDouble.addAndGet(-0.5d);
45
46 assertEquals(10d, result, 0.01d);
47 assertEquals(10d, mutableDouble.doubleValue(), 0.01d);
48 }
49
50 @Test
51 public void testAddValueObject() {
52 final MutableDouble mutNum = new MutableDouble(1);
53 mutNum.add(Double.valueOf(1.1d));
54
55 assertEquals(2.1d, mutNum.doubleValue(), 0.01d);
56 }
57
58 @Test
59 public void testAddValuePrimitive() {
60 final MutableDouble mutNum = new MutableDouble(1);
61 mutNum.add(1.1d);
62
63 assertEquals(2.1d, mutNum.doubleValue(), 0.01d);
64 }
65
66 @Test
67 public void testCompareTo() {
68 final MutableDouble mutNum = new MutableDouble(0d);
69
70 assertEquals(0, mutNum.compareTo(new MutableDouble(0d)));
71 assertEquals(+1, mutNum.compareTo(new MutableDouble(-1d)));
72 assertEquals(-1, mutNum.compareTo(new MutableDouble(1d)));
73 }
74
75 @Test
76 public void testCompareToNull() {
77 final MutableDouble mutNum = new MutableDouble(0d);
78 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
79 }
80
81 @Test
82 public void testConstructorNull() {
83 assertThrows(NullPointerException.class, () -> new MutableDouble((Number) null));
84 }
85
3286 // ----------------------------------------------------------------
3387 @Test
3488 public void testConstructors() {
4498 }
4599
46100 @Test
47 public void testConstructorNull() {
48 assertThrows(NullPointerException.class, () -> new MutableDouble((Number) null));
49 }
50
51 @Test
52 public void testGetSet() {
53 final MutableDouble mutNum = new MutableDouble(0d);
54 assertEquals(0d, new MutableDouble().doubleValue(), 0.0001d);
55 assertEquals(Double.valueOf(0), new MutableDouble().getValue());
56
57 mutNum.setValue(1);
58 assertEquals(1d, mutNum.doubleValue(), 0.0001d);
59 assertEquals(Double.valueOf(1d), mutNum.getValue());
60
61 mutNum.setValue(Double.valueOf(2d));
62 assertEquals(2d, mutNum.doubleValue(), 0.0001d);
63 assertEquals(Double.valueOf(2d), mutNum.getValue());
64
65 mutNum.setValue(new MutableDouble(3d));
66 assertEquals(3d, mutNum.doubleValue(), 0.0001d);
67 assertEquals(Double.valueOf(3d), mutNum.getValue());
68 }
69
70 @Test
71 public void testSetNull() {
72 final MutableDouble mutNum = new MutableDouble(0d);
73 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
74 }
75
76 @Test
77 public void testNanInfinite() {
78 MutableDouble mutNum = new MutableDouble(Double.NaN);
79 assertTrue(mutNum.isNaN());
80
81 mutNum = new MutableDouble(Double.POSITIVE_INFINITY);
82 assertTrue(mutNum.isInfinite());
83
84 mutNum = new MutableDouble(Double.NEGATIVE_INFINITY);
85 assertTrue(mutNum.isInfinite());
101 public void testDecrement() {
102 final MutableDouble mutNum = new MutableDouble(1);
103 mutNum.decrement();
104
105 assertEquals(0, mutNum.intValue());
106 assertEquals(0L, mutNum.longValue());
107 }
108
109 @Test
110 public void testDecrementAndGet() {
111 final MutableDouble mutNum = new MutableDouble(1d);
112 final double result = mutNum.decrementAndGet();
113
114 assertEquals(0d, result, 0.01d);
115 assertEquals(0, mutNum.intValue());
116 assertEquals(0L, mutNum.longValue());
86117 }
87118
88119 @Test
104135 }
105136
106137 @Test
138 public void testGetAndAddValueObject() {
139 final MutableDouble mutableDouble = new MutableDouble(0.5d);
140 final double result = mutableDouble.getAndAdd(Double.valueOf(2d));
141
142 assertEquals(0.5d, result, 0.01d);
143 assertEquals(2.5d, mutableDouble.doubleValue(), 0.01d);
144 }
145
146 @Test
147 public void testGetAndAddValuePrimitive() {
148 final MutableDouble mutableDouble = new MutableDouble(0.5d);
149 final double result = mutableDouble.getAndAdd(1d);
150
151 assertEquals(0.5d, result, 0.01d);
152 assertEquals(1.5d, mutableDouble.doubleValue(), 0.01d);
153 }
154
155 @Test
156 public void testGetAndDecrement() {
157 final MutableDouble mutNum = new MutableDouble(1d);
158 final double result = mutNum.getAndDecrement();
159
160 assertEquals(1d, result, 0.01d);
161 assertEquals(0, mutNum.intValue());
162 assertEquals(0L, mutNum.longValue());
163 }
164
165 @Test
166 public void testGetAndIncrement() {
167 final MutableDouble mutNum = new MutableDouble(1d);
168 final double result = mutNum.getAndIncrement();
169
170 assertEquals(1d, result, 0.01d);
171 assertEquals(2, mutNum.intValue());
172 assertEquals(2L, mutNum.longValue());
173 }
174
175 @Test
176 public void testGetSet() {
177 final MutableDouble mutNum = new MutableDouble(0d);
178 assertEquals(0d, new MutableDouble().doubleValue(), 0.0001d);
179 assertEquals(Double.valueOf(0), new MutableDouble().getValue());
180
181 mutNum.setValue(1);
182 assertEquals(1d, mutNum.doubleValue(), 0.0001d);
183 assertEquals(Double.valueOf(1d), mutNum.getValue());
184
185 mutNum.setValue(Double.valueOf(2d));
186 assertEquals(2d, mutNum.doubleValue(), 0.0001d);
187 assertEquals(Double.valueOf(2d), mutNum.getValue());
188
189 mutNum.setValue(new MutableDouble(3d));
190 assertEquals(3d, mutNum.doubleValue(), 0.0001d);
191 assertEquals(Double.valueOf(3d), mutNum.getValue());
192 }
193
194 @Test
107195 public void testHashCode() {
108196 final MutableDouble mutNumA = new MutableDouble(0d);
109197 final MutableDouble mutNumB = new MutableDouble(0d);
116204 }
117205
118206 @Test
119 public void testCompareTo() {
120 final MutableDouble mutNum = new MutableDouble(0d);
121
122 assertEquals(0, mutNum.compareTo(new MutableDouble(0d)));
123 assertEquals(+1, mutNum.compareTo(new MutableDouble(-1d)));
124 assertEquals(-1, mutNum.compareTo(new MutableDouble(1d)));
125 }
126
127 @Test
128 public void testCompareToNull() {
129 final MutableDouble mutNum = new MutableDouble(0d);
130 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
207 public void testIncrement() {
208 final MutableDouble mutNum = new MutableDouble(1);
209 mutNum.increment();
210
211 assertEquals(2, mutNum.intValue());
212 assertEquals(2L, mutNum.longValue());
213 }
214
215 @Test
216 public void testIncrementAndGet() {
217 final MutableDouble mutNum = new MutableDouble(1d);
218 final double result = mutNum.incrementAndGet();
219
220 assertEquals(2d, result, 0.01d);
221 assertEquals(2, mutNum.intValue());
222 assertEquals(2L, mutNum.longValue());
223 }
224
225 @Test
226 public void testNanInfinite() {
227 MutableDouble mutNum = new MutableDouble(Double.NaN);
228 assertTrue(mutNum.isNaN());
229
230 mutNum = new MutableDouble(Double.POSITIVE_INFINITY);
231 assertTrue(mutNum.isInfinite());
232
233 mutNum = new MutableDouble(Double.NEGATIVE_INFINITY);
234 assertTrue(mutNum.isInfinite());
131235 }
132236
133237 @Test
142246 }
143247
144248 @Test
249 public void testSetNull() {
250 final MutableDouble mutNum = new MutableDouble(0d);
251 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
252 }
253
254 @Test
255 public void testSubtractValueObject() {
256 final MutableDouble mutNum = new MutableDouble(1);
257 mutNum.subtract(Double.valueOf(0.9d));
258
259 assertEquals(0.1d, mutNum.doubleValue(), 0.01d);
260 }
261
262 @Test
263 public void testSubtractValuePrimitive() {
264 final MutableDouble mutNum = new MutableDouble(1);
265 mutNum.subtract(0.9d);
266
267 assertEquals(0.1d, mutNum.doubleValue(), 0.01d);
268 }
269
270 @Test
145271 public void testToDouble() {
146272 assertEquals(Double.valueOf(0d), new MutableDouble(0d).toDouble());
147273 assertEquals(Double.valueOf(12.3d), new MutableDouble(12.3d).toDouble());
148 }
149
150 @Test
151 public void testIncrement() {
152 final MutableDouble mutNum = new MutableDouble(1);
153 mutNum.increment();
154
155 assertEquals(2, mutNum.intValue());
156 assertEquals(2L, mutNum.longValue());
157 }
158
159 @Test
160 public void testIncrementAndGet() {
161 final MutableDouble mutNum = new MutableDouble(1d);
162 final double result = mutNum.incrementAndGet();
163
164 assertEquals(2d, result, 0.01d);
165 assertEquals(2, mutNum.intValue());
166 assertEquals(2L, mutNum.longValue());
167 }
168
169 @Test
170 public void testGetAndIncrement() {
171 final MutableDouble mutNum = new MutableDouble(1d);
172 final double result = mutNum.getAndIncrement();
173
174 assertEquals(1d, result, 0.01d);
175 assertEquals(2, mutNum.intValue());
176 assertEquals(2L, mutNum.longValue());
177 }
178
179 @Test
180 public void testDecrement() {
181 final MutableDouble mutNum = new MutableDouble(1);
182 mutNum.decrement();
183
184 assertEquals(0, mutNum.intValue());
185 assertEquals(0L, mutNum.longValue());
186 }
187
188 @Test
189 public void testDecrementAndGet() {
190 final MutableDouble mutNum = new MutableDouble(1d);
191 final double result = mutNum.decrementAndGet();
192
193 assertEquals(0d, result, 0.01d);
194 assertEquals(0, mutNum.intValue());
195 assertEquals(0L, mutNum.longValue());
196 }
197
198 @Test
199 public void testGetAndDecrement() {
200 final MutableDouble mutNum = new MutableDouble(1d);
201 final double result = mutNum.getAndDecrement();
202
203 assertEquals(1d, result, 0.01d);
204 assertEquals(0, mutNum.intValue());
205 assertEquals(0L, mutNum.longValue());
206 }
207
208 @Test
209 public void testAddValuePrimitive() {
210 final MutableDouble mutNum = new MutableDouble(1);
211 mutNum.add(1.1d);
212
213 assertEquals(2.1d, mutNum.doubleValue(), 0.01d);
214 }
215
216 @Test
217 public void testAddValueObject() {
218 final MutableDouble mutNum = new MutableDouble(1);
219 mutNum.add(Double.valueOf(1.1d));
220
221 assertEquals(2.1d, mutNum.doubleValue(), 0.01d);
222 }
223
224 @Test
225 public void testGetAndAddValuePrimitive() {
226 final MutableDouble mutableDouble = new MutableDouble(0.5d);
227 final double result = mutableDouble.getAndAdd(1d);
228
229 assertEquals(0.5d, result, 0.01d);
230 assertEquals(1.5d, mutableDouble.doubleValue(), 0.01d);
231 }
232
233 @Test
234 public void testGetAndAddValueObject() {
235 final MutableDouble mutableDouble = new MutableDouble(0.5d);
236 final double result = mutableDouble.getAndAdd(Double.valueOf(2d));
237
238 assertEquals(0.5d, result, 0.01d);
239 assertEquals(2.5d, mutableDouble.doubleValue(), 0.01d);
240 }
241
242 @Test
243 public void testAddAndGetValuePrimitive() {
244 final MutableDouble mutableDouble = new MutableDouble(10.5d);
245 final double result = mutableDouble.addAndGet(-0.5d);
246
247 assertEquals(10d, result, 0.01d);
248 assertEquals(10d, mutableDouble.doubleValue(), 0.01d);
249 }
250
251 @Test
252 public void testAddAndGetValueObject() {
253 final MutableDouble mutableDouble = new MutableDouble(7.5d);
254 final double result = mutableDouble.addAndGet(Double.valueOf(-2.5d));
255
256 assertEquals(5d, result, 0.01d);
257 assertEquals(5d, mutableDouble.doubleValue(), 0.01d);
258 }
259
260 @Test
261 public void testSubtractValuePrimitive() {
262 final MutableDouble mutNum = new MutableDouble(1);
263 mutNum.subtract(0.9d);
264
265 assertEquals(0.1d, mutNum.doubleValue(), 0.01d);
266 }
267
268 @Test
269 public void testSubtractValueObject() {
270 final MutableDouble mutNum = new MutableDouble(1);
271 mutNum.subtract(Double.valueOf(0.9d));
272
273 assertEquals(0.1d, mutNum.doubleValue(), 0.01d);
274274 }
275275
276276 @Test
2929 */
3030 public class MutableFloatTest {
3131
32 @Test
33 public void testAddAndGetValueObject() {
34 final MutableFloat mutableFloat = new MutableFloat(5f);
35 final float result = mutableFloat.addAndGet(Float.valueOf(2.5f));
36
37 assertEquals(7.5f, result, 0.01f);
38 assertEquals(7.5f, mutableFloat.floatValue(), 0.01f);
39 }
40
41 @Test
42 public void testAddAndGetValuePrimitive() {
43 final MutableFloat mutableFloat = new MutableFloat(0.5f);
44 final float result = mutableFloat.addAndGet(1f);
45
46 assertEquals(1.5f, result, 0.01f);
47 assertEquals(1.5f, mutableFloat.floatValue(), 0.01f);
48 }
49
50 @Test
51 public void testAddValueObject() {
52 final MutableFloat mutNum = new MutableFloat(1);
53 mutNum.add(Float.valueOf(1.1f));
54
55 assertEquals(2.1f, mutNum.floatValue(), 0.01f);
56 }
57
58 @Test
59 public void testAddValuePrimitive() {
60 final MutableFloat mutNum = new MutableFloat(1);
61 mutNum.add(1.1f);
62
63 assertEquals(2.1f, mutNum.floatValue(), 0.01f);
64 }
65
66 @Test
67 public void testCompareTo() {
68 final MutableFloat mutNum = new MutableFloat(0f);
69
70 assertEquals(0, mutNum.compareTo(new MutableFloat(0f)));
71 assertEquals(+1, mutNum.compareTo(new MutableFloat(-1f)));
72 assertEquals(-1, mutNum.compareTo(new MutableFloat(1f)));
73 }
74
75 @Test
76 public void testCompareToNull() {
77 final MutableFloat mutNum = new MutableFloat(0f);
78 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
79 }
80
81 @Test
82 public void testConstructorNull() {
83 assertThrows(NullPointerException.class, () -> new MutableFloat((Number) null));
84 }
85
3286 // ----------------------------------------------------------------
3387 @Test
3488 public void testConstructors() {
4498 }
4599
46100 @Test
47 public void testConstructorNull() {
48 assertThrows(NullPointerException.class, () -> new MutableFloat((Number) null));
49 }
50
51 @Test
52 public void testGetSet() {
53 final MutableFloat mutNum = new MutableFloat(0f);
54 assertEquals(0f, new MutableFloat().floatValue(), 0.0001f);
55 assertEquals(Float.valueOf(0), new MutableFloat().getValue());
56
57 mutNum.setValue(1);
58 assertEquals(1f, mutNum.floatValue(), 0.0001f);
59 assertEquals(Float.valueOf(1f), mutNum.getValue());
60
61 mutNum.setValue(Float.valueOf(2f));
62 assertEquals(2f, mutNum.floatValue(), 0.0001f);
63 assertEquals(Float.valueOf(2f), mutNum.getValue());
64
65 mutNum.setValue(new MutableFloat(3f));
66 assertEquals(3f, mutNum.floatValue(), 0.0001f);
67 assertEquals(Float.valueOf(3f), mutNum.getValue());
68 }
69
70 @Test
71 public void testSetNull() {
72 final MutableFloat mutNum = new MutableFloat(0f);
73 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
74 }
75
76 @Test
77 public void testNanInfinite() {
78 MutableFloat mutNum = new MutableFloat(Float.NaN);
79 assertTrue(mutNum.isNaN());
80
81 mutNum = new MutableFloat(Float.POSITIVE_INFINITY);
82 assertTrue(mutNum.isInfinite());
83
84 mutNum = new MutableFloat(Float.NEGATIVE_INFINITY);
85 assertTrue(mutNum.isInfinite());
101 public void testDecrement() {
102 final MutableFloat mutNum = new MutableFloat(1);
103 mutNum.decrement();
104
105 assertEquals(0, mutNum.intValue());
106 assertEquals(0L, mutNum.longValue());
107 }
108
109 @Test
110 public void testDecrementAndGet() {
111 final MutableFloat mutNum = new MutableFloat(1f);
112 final float result = mutNum.decrementAndGet();
113
114 assertEquals(0f, result, 0.01f);
115 assertEquals(0, mutNum.intValue());
116 assertEquals(0L, mutNum.longValue());
86117 }
87118
88119 @Test
104135 }
105136
106137 @Test
138 public void testGetAndAddValueObject() {
139 final MutableFloat mutableFloat = new MutableFloat(7.75f);
140 final float result = mutableFloat.getAndAdd(Float.valueOf(2.25f));
141
142 assertEquals(7.75f, result, 0.01f);
143 assertEquals(10f, mutableFloat.floatValue(), 0.01f);
144 }
145
146 @Test
147 public void testGetAndAddValuePrimitive() {
148 final MutableFloat mutableFloat = new MutableFloat(1.25f);
149 final float result = mutableFloat.getAndAdd(0.75f);
150
151 assertEquals(1.25f, result, 0.01f);
152 assertEquals(2f, mutableFloat.floatValue(), 0.01f);
153 }
154
155 @Test
156 public void testGetAndDecrement() {
157 final MutableFloat mutNum = new MutableFloat(1f);
158 final float result = mutNum.getAndDecrement();
159
160 assertEquals(1f, result, 0.01f);
161 assertEquals(0, mutNum.intValue());
162 assertEquals(0L, mutNum.longValue());
163 }
164
165 @Test
166 public void testGetAndIncrement() {
167 final MutableFloat mutNum = new MutableFloat(1f);
168 final float result = mutNum.getAndIncrement();
169
170 assertEquals(1f, result, 0.01f);
171 assertEquals(2, mutNum.intValue());
172 assertEquals(2L, mutNum.longValue());
173 }
174
175 @Test
176 public void testGetSet() {
177 final MutableFloat mutNum = new MutableFloat(0f);
178 assertEquals(0f, new MutableFloat().floatValue(), 0.0001f);
179 assertEquals(Float.valueOf(0), new MutableFloat().getValue());
180
181 mutNum.setValue(1);
182 assertEquals(1f, mutNum.floatValue(), 0.0001f);
183 assertEquals(Float.valueOf(1f), mutNum.getValue());
184
185 mutNum.setValue(Float.valueOf(2f));
186 assertEquals(2f, mutNum.floatValue(), 0.0001f);
187 assertEquals(Float.valueOf(2f), mutNum.getValue());
188
189 mutNum.setValue(new MutableFloat(3f));
190 assertEquals(3f, mutNum.floatValue(), 0.0001f);
191 assertEquals(Float.valueOf(3f), mutNum.getValue());
192 }
193
194 @Test
107195 public void testHashCode() {
108196 final MutableFloat mutNumA = new MutableFloat(0f);
109197 final MutableFloat mutNumB = new MutableFloat(0f);
116204 }
117205
118206 @Test
119 public void testCompareTo() {
120 final MutableFloat mutNum = new MutableFloat(0f);
121
122 assertEquals(0, mutNum.compareTo(new MutableFloat(0f)));
123 assertEquals(+1, mutNum.compareTo(new MutableFloat(-1f)));
124 assertEquals(-1, mutNum.compareTo(new MutableFloat(1f)));
125 }
126
127 @Test
128 public void testCompareToNull() {
129 final MutableFloat mutNum = new MutableFloat(0f);
130 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
207 public void testIncrement() {
208 final MutableFloat mutNum = new MutableFloat(1);
209 mutNum.increment();
210
211 assertEquals(2, mutNum.intValue());
212 assertEquals(2L, mutNum.longValue());
213 }
214
215 @Test
216 public void testIncrementAndGet() {
217 final MutableFloat mutNum = new MutableFloat(1f);
218 final float result = mutNum.incrementAndGet();
219
220 assertEquals(2f, result, 0.01f);
221 assertEquals(2, mutNum.intValue());
222 assertEquals(2L, mutNum.longValue());
223 }
224
225 @Test
226 public void testNanInfinite() {
227 MutableFloat mutNum = new MutableFloat(Float.NaN);
228 assertTrue(mutNum.isNaN());
229
230 mutNum = new MutableFloat(Float.POSITIVE_INFINITY);
231 assertTrue(mutNum.isInfinite());
232
233 mutNum = new MutableFloat(Float.NEGATIVE_INFINITY);
234 assertTrue(mutNum.isInfinite());
131235 }
132236
133237 @Test
143247 }
144248
145249 @Test
250 public void testSetNull() {
251 final MutableFloat mutNum = new MutableFloat(0f);
252 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
253 }
254
255 @Test
256 public void testSubtractValueObject() {
257 final MutableFloat mutNum = new MutableFloat(1);
258 mutNum.subtract(Float.valueOf(0.9f));
259
260 assertEquals(0.1f, mutNum.floatValue(), 0.01f);
261 }
262
263 @Test
264 public void testSubtractValuePrimitive() {
265 final MutableFloat mutNum = new MutableFloat(1);
266 mutNum.subtract(0.9f);
267
268 assertEquals(0.1f, mutNum.floatValue(), 0.01f);
269 }
270
271 @Test
146272 public void testToFloat() {
147273 assertEquals(Float.valueOf(0f), new MutableFloat(0f).toFloat());
148274 assertEquals(Float.valueOf(12.3f), new MutableFloat(12.3f).toFloat());
149 }
150
151 @Test
152 public void testIncrement() {
153 final MutableFloat mutNum = new MutableFloat(1);
154 mutNum.increment();
155
156 assertEquals(2, mutNum.intValue());
157 assertEquals(2L, mutNum.longValue());
158 }
159
160 @Test
161 public void testIncrementAndGet() {
162 final MutableFloat mutNum = new MutableFloat(1f);
163 final float result = mutNum.incrementAndGet();
164
165 assertEquals(2f, result, 0.01f);
166 assertEquals(2, mutNum.intValue());
167 assertEquals(2L, mutNum.longValue());
168 }
169
170 @Test
171 public void testGetAndIncrement() {
172 final MutableFloat mutNum = new MutableFloat(1f);
173 final float result = mutNum.getAndIncrement();
174
175 assertEquals(1f, result, 0.01f);
176 assertEquals(2, mutNum.intValue());
177 assertEquals(2L, mutNum.longValue());
178 }
179
180 @Test
181 public void testDecrement() {
182 final MutableFloat mutNum = new MutableFloat(1);
183 mutNum.decrement();
184
185 assertEquals(0, mutNum.intValue());
186 assertEquals(0L, mutNum.longValue());
187 }
188
189 @Test
190 public void testDecrementAndGet() {
191 final MutableFloat mutNum = new MutableFloat(1f);
192 final float result = mutNum.decrementAndGet();
193
194 assertEquals(0f, result, 0.01f);
195 assertEquals(0, mutNum.intValue());
196 assertEquals(0L, mutNum.longValue());
197 }
198
199 @Test
200 public void testGetAndDecrement() {
201 final MutableFloat mutNum = new MutableFloat(1f);
202 final float result = mutNum.getAndDecrement();
203
204 assertEquals(1f, result, 0.01f);
205 assertEquals(0, mutNum.intValue());
206 assertEquals(0L, mutNum.longValue());
207 }
208
209 @Test
210 public void testAddValuePrimitive() {
211 final MutableFloat mutNum = new MutableFloat(1);
212 mutNum.add(1.1f);
213
214 assertEquals(2.1f, mutNum.floatValue(), 0.01f);
215 }
216
217 @Test
218 public void testAddValueObject() {
219 final MutableFloat mutNum = new MutableFloat(1);
220 mutNum.add(Float.valueOf(1.1f));
221
222 assertEquals(2.1f, mutNum.floatValue(), 0.01f);
223 }
224
225 @Test
226 public void testGetAndAddValuePrimitive() {
227 final MutableFloat mutableFloat = new MutableFloat(1.25f);
228 final float result = mutableFloat.getAndAdd(0.75f);
229
230 assertEquals(1.25f, result, 0.01f);
231 assertEquals(2f, mutableFloat.floatValue(), 0.01f);
232 }
233
234 @Test
235 public void testGetAndAddValueObject() {
236 final MutableFloat mutableFloat = new MutableFloat(7.75f);
237 final float result = mutableFloat.getAndAdd(Float.valueOf(2.25f));
238
239 assertEquals(7.75f, result, 0.01f);
240 assertEquals(10f, mutableFloat.floatValue(), 0.01f);
241 }
242
243 @Test
244 public void testAddAndGetValuePrimitive() {
245 final MutableFloat mutableFloat = new MutableFloat(0.5f);
246 final float result = mutableFloat.addAndGet(1f);
247
248 assertEquals(1.5f, result, 0.01f);
249 assertEquals(1.5f, mutableFloat.floatValue(), 0.01f);
250 }
251
252 @Test
253 public void testAddAndGetValueObject() {
254 final MutableFloat mutableFloat = new MutableFloat(5f);
255 final float result = mutableFloat.addAndGet(Float.valueOf(2.5f));
256
257 assertEquals(7.5f, result, 0.01f);
258 assertEquals(7.5f, mutableFloat.floatValue(), 0.01f);
259 }
260
261 @Test
262 public void testSubtractValuePrimitive() {
263 final MutableFloat mutNum = new MutableFloat(1);
264 mutNum.subtract(0.9f);
265
266 assertEquals(0.1f, mutNum.floatValue(), 0.01f);
267 }
268
269 @Test
270 public void testSubtractValueObject() {
271 final MutableFloat mutNum = new MutableFloat(1);
272 mutNum.subtract(Float.valueOf(0.9f));
273
274 assertEquals(0.1f, mutNum.floatValue(), 0.01f);
275275 }
276276
277277 @Test
2828 */
2929 public class MutableIntTest {
3030
31 @Test
32 public void testAddAndGetValueObject() {
33 final MutableInt mutableInteger = new MutableInt(0);
34 final int result = mutableInteger.addAndGet(Integer.valueOf(1));
35
36 assertEquals(1, result);
37 assertEquals(1, mutableInteger.intValue());
38 }
39
40 @Test
41 public void testAddAndGetValuePrimitive() {
42 final MutableInt mutableInteger = new MutableInt(0);
43 final int result = mutableInteger.addAndGet(1);
44
45 assertEquals(1, result);
46 assertEquals(1, mutableInteger.intValue());
47 }
48
49 @Test
50 public void testAddValueObject() {
51 final MutableInt mutNum = new MutableInt(1);
52 mutNum.add(Integer.valueOf(1));
53
54 assertEquals(2, mutNum.intValue());
55 assertEquals(2L, mutNum.longValue());
56 }
57
58 @Test
59 public void testAddValuePrimitive() {
60 final MutableInt mutNum = new MutableInt(1);
61 mutNum.add(1);
62
63 assertEquals(2, mutNum.intValue());
64 assertEquals(2L, mutNum.longValue());
65 }
66
67 @Test
68 public void testCompareTo() {
69 final MutableInt mutNum = new MutableInt(0);
70
71 assertEquals(0, mutNum.compareTo(new MutableInt(0)));
72 assertEquals(+1, mutNum.compareTo(new MutableInt(-1)));
73 assertEquals(-1, mutNum.compareTo(new MutableInt(1)));
74 }
75
76 @Test
77 public void testCompareToNull() {
78 final MutableInt mutNum = new MutableInt(0);
79 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
80 }
81
82 @Test
83 public void testConstructorNull() {
84 assertThrows(NullPointerException.class, () -> new MutableInt((Number) null));
85 }
86
3187 // ----------------------------------------------------------------
3288 @Test
3389 public void testConstructors() {
4399 }
44100
45101 @Test
46 public void testConstructorNull() {
47 assertThrows(NullPointerException.class, () -> new MutableInt((Number) null));
48 }
49
50 @Test
51 public void testGetSet() {
52 final MutableInt mutNum = new MutableInt(0);
53 assertEquals(0, new MutableInt().intValue());
54 assertEquals(Integer.valueOf(0), new MutableInt().getValue());
55
56 mutNum.setValue(1);
57 assertEquals(1, mutNum.intValue());
58 assertEquals(Integer.valueOf(1), mutNum.getValue());
59
60 mutNum.setValue(Integer.valueOf(2));
61 assertEquals(2, mutNum.intValue());
62 assertEquals(Integer.valueOf(2), mutNum.getValue());
63
64 mutNum.setValue(new MutableLong(3));
65 assertEquals(3, mutNum.intValue());
66 assertEquals(Integer.valueOf(3), mutNum.getValue());
67 }
68
69 @Test
70 public void testSetNull() {
71 final MutableInt mutNum = new MutableInt(0);
72 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
102 public void testDecrement() {
103 final MutableInt mutNum = new MutableInt(1);
104 mutNum.decrement();
105
106 assertEquals(0, mutNum.intValue());
107 assertEquals(0L, mutNum.longValue());
108 }
109
110 @Test
111 public void testDecrementAndGet() {
112 final MutableInt mutNum = new MutableInt(1);
113 final int result = mutNum.decrementAndGet();
114
115 assertEquals(0, result);
116 assertEquals(0, mutNum.intValue());
117 assertEquals(0L, mutNum.longValue());
73118 }
74119
75120 @Test
98143 }
99144
100145 @Test
146 public void testGetAndAddValueObject() {
147 final MutableInt mutableInteger = new MutableInt(0);
148 final int result = mutableInteger.getAndAdd(Integer.valueOf(1));
149
150 assertEquals(0, result);
151 assertEquals(1, mutableInteger.intValue());
152 }
153
154 @Test
155 public void testGetAndAddValuePrimitive() {
156 final MutableInt mutableInteger = new MutableInt(0);
157 final int result = mutableInteger.getAndAdd(1);
158
159 assertEquals(0, result);
160 assertEquals(1, mutableInteger.intValue());
161 }
162
163 @Test
164 public void testGetAndDecrement() {
165 final MutableInt mutNum = new MutableInt(1);
166 final int result = mutNum.getAndDecrement();
167
168 assertEquals(1, result);
169 assertEquals(0, mutNum.intValue());
170 assertEquals(0L, mutNum.longValue());
171 }
172
173 @Test
174 public void testGetAndIncrement() {
175 final MutableInt mutNum = new MutableInt(1);
176 final int result = mutNum.getAndIncrement();
177
178 assertEquals(1, result);
179 assertEquals(2, mutNum.intValue());
180 assertEquals(2L, mutNum.longValue());
181 }
182
183 @Test
184 public void testGetSet() {
185 final MutableInt mutNum = new MutableInt(0);
186 assertEquals(0, new MutableInt().intValue());
187 assertEquals(Integer.valueOf(0), new MutableInt().getValue());
188
189 mutNum.setValue(1);
190 assertEquals(1, mutNum.intValue());
191 assertEquals(Integer.valueOf(1), mutNum.getValue());
192
193 mutNum.setValue(Integer.valueOf(2));
194 assertEquals(2, mutNum.intValue());
195 assertEquals(Integer.valueOf(2), mutNum.getValue());
196
197 mutNum.setValue(new MutableLong(3));
198 assertEquals(3, mutNum.intValue());
199 assertEquals(Integer.valueOf(3), mutNum.getValue());
200 }
201
202 @Test
101203 public void testHashCode() {
102204 final MutableInt mutNumA = new MutableInt(0);
103205 final MutableInt mutNumB = new MutableInt(0);
110212 }
111213
112214 @Test
113 public void testCompareTo() {
114 final MutableInt mutNum = new MutableInt(0);
115
116 assertEquals(0, mutNum.compareTo(new MutableInt(0)));
117 assertEquals(+1, mutNum.compareTo(new MutableInt(-1)));
118 assertEquals(-1, mutNum.compareTo(new MutableInt(1)));
119 }
120
121 @Test
122 public void testCompareToNull() {
123 final MutableInt mutNum = new MutableInt(0);
124 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
215 public void testIncrement() {
216 final MutableInt mutNum = new MutableInt(1);
217 mutNum.increment();
218
219 assertEquals(2, mutNum.intValue());
220 assertEquals(2L, mutNum.longValue());
221 }
222
223 @Test
224 public void testIncrementAndGet() {
225 final MutableInt mutNum = new MutableInt(1);
226 final int result = mutNum.incrementAndGet();
227
228 assertEquals(2, result);
229 assertEquals(2, mutNum.intValue());
230 assertEquals(2L, mutNum.longValue());
125231 }
126232
127233 @Test
135241 }
136242
137243 @Test
244 public void testSetNull() {
245 final MutableInt mutNum = new MutableInt(0);
246 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
247 }
248
249 @Test
250 public void testSubtractValueObject() {
251 final MutableInt mutNum = new MutableInt(1);
252 mutNum.subtract(Integer.valueOf(1));
253
254 assertEquals(0, mutNum.intValue());
255 assertEquals(0L, mutNum.longValue());
256 }
257
258 @Test
259 public void testSubtractValuePrimitive() {
260 final MutableInt mutNum = new MutableInt(1);
261 mutNum.subtract(1);
262
263 assertEquals(0, mutNum.intValue());
264 assertEquals(0L, mutNum.longValue());
265 }
266
267 @Test
138268 public void testToInteger() {
139269 assertEquals(Integer.valueOf(0), new MutableInt(0).toInteger());
140270 assertEquals(Integer.valueOf(123), new MutableInt(123).toInteger());
141 }
142
143 @Test
144 public void testIncrement() {
145 final MutableInt mutNum = new MutableInt(1);
146 mutNum.increment();
147
148 assertEquals(2, mutNum.intValue());
149 assertEquals(2L, mutNum.longValue());
150 }
151
152 @Test
153 public void testIncrementAndGet() {
154 final MutableInt mutNum = new MutableInt(1);
155 final int result = mutNum.incrementAndGet();
156
157 assertEquals(2, result);
158 assertEquals(2, mutNum.intValue());
159 assertEquals(2L, mutNum.longValue());
160 }
161
162 @Test
163 public void testGetAndIncrement() {
164 final MutableInt mutNum = new MutableInt(1);
165 final int result = mutNum.getAndIncrement();
166
167 assertEquals(1, result);
168 assertEquals(2, mutNum.intValue());
169 assertEquals(2L, mutNum.longValue());
170 }
171
172 @Test
173 public void testDecrement() {
174 final MutableInt mutNum = new MutableInt(1);
175 mutNum.decrement();
176
177 assertEquals(0, mutNum.intValue());
178 assertEquals(0L, mutNum.longValue());
179 }
180
181 @Test
182 public void testDecrementAndGet() {
183 final MutableInt mutNum = new MutableInt(1);
184 final int result = mutNum.decrementAndGet();
185
186 assertEquals(0, result);
187 assertEquals(0, mutNum.intValue());
188 assertEquals(0L, mutNum.longValue());
189 }
190
191 @Test
192 public void testGetAndDecrement() {
193 final MutableInt mutNum = new MutableInt(1);
194 final int result = mutNum.getAndDecrement();
195
196 assertEquals(1, result);
197 assertEquals(0, mutNum.intValue());
198 assertEquals(0L, mutNum.longValue());
199 }
200
201 @Test
202 public void testAddValuePrimitive() {
203 final MutableInt mutNum = new MutableInt(1);
204 mutNum.add(1);
205
206 assertEquals(2, mutNum.intValue());
207 assertEquals(2L, mutNum.longValue());
208 }
209
210 @Test
211 public void testAddValueObject() {
212 final MutableInt mutNum = new MutableInt(1);
213 mutNum.add(Integer.valueOf(1));
214
215 assertEquals(2, mutNum.intValue());
216 assertEquals(2L, mutNum.longValue());
217 }
218
219 @Test
220 public void testGetAndAddValuePrimitive() {
221 final MutableInt mutableInteger = new MutableInt(0);
222 final int result = mutableInteger.getAndAdd(1);
223
224 assertEquals(0, result);
225 assertEquals(1, mutableInteger.intValue());
226 }
227
228 @Test
229 public void testGetAndAddValueObject() {
230 final MutableInt mutableInteger = new MutableInt(0);
231 final int result = mutableInteger.getAndAdd(Integer.valueOf(1));
232
233 assertEquals(0, result);
234 assertEquals(1, mutableInteger.intValue());
235 }
236
237 @Test
238 public void testAddAndGetValuePrimitive() {
239 final MutableInt mutableInteger = new MutableInt(0);
240 final int result = mutableInteger.addAndGet(1);
241
242 assertEquals(1, result);
243 assertEquals(1, mutableInteger.intValue());
244 }
245
246 @Test
247 public void testAddAndGetValueObject() {
248 final MutableInt mutableInteger = new MutableInt(0);
249 final int result = mutableInteger.addAndGet(Integer.valueOf(1));
250
251 assertEquals(1, result);
252 assertEquals(1, mutableInteger.intValue());
253 }
254
255 @Test
256 public void testSubtractValuePrimitive() {
257 final MutableInt mutNum = new MutableInt(1);
258 mutNum.subtract(1);
259
260 assertEquals(0, mutNum.intValue());
261 assertEquals(0L, mutNum.longValue());
262 }
263
264 @Test
265 public void testSubtractValueObject() {
266 final MutableInt mutNum = new MutableInt(1);
267 mutNum.subtract(Integer.valueOf(1));
268
269 assertEquals(0, mutNum.intValue());
270 assertEquals(0L, mutNum.longValue());
271271 }
272272
273273 @Test
2828 */
2929 public class MutableLongTest {
3030
31 @Test
32 public void testAddAndGetValueObject() {
33 final MutableLong mutableLong = new MutableLong(0L);
34 final long result = mutableLong.addAndGet(Long.valueOf(1L));
35
36 assertEquals(1L, result);
37 assertEquals(1L, mutableLong.longValue());
38 }
39
40 @Test
41 public void testAddAndGetValuePrimitive() {
42 final MutableLong mutableLong = new MutableLong(0L);
43 final long result = mutableLong.addAndGet(1L);
44
45 assertEquals(1L, result);
46 assertEquals(1L, mutableLong.longValue());
47 }
48
49 @Test
50 public void testAddValueObject() {
51 final MutableLong mutNum = new MutableLong(1);
52 mutNum.add(Long.valueOf(1));
53
54 assertEquals(2, mutNum.intValue());
55 assertEquals(2L, mutNum.longValue());
56 }
57
58 @Test
59 public void testAddValuePrimitive() {
60 final MutableLong mutNum = new MutableLong(1);
61 mutNum.add(1);
62
63 assertEquals(2, mutNum.intValue());
64 assertEquals(2L, mutNum.longValue());
65 }
66
67 @Test
68 public void testCompareTo() {
69 final MutableLong mutNum = new MutableLong(0);
70
71 assertEquals(0, mutNum.compareTo(new MutableLong(0)));
72 assertEquals(+1, mutNum.compareTo(new MutableLong(-1)));
73 assertEquals(-1, mutNum.compareTo(new MutableLong(1)));
74 }
75
76 @Test
77 public void testCompareToNull() {
78 final MutableLong mutNum = new MutableLong(0);
79 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
80 }
81
82 @Test
83 public void testConstructorNull() {
84 assertThrows(NullPointerException.class, () -> new MutableLong((Number) null));
85 }
86
3187 // ----------------------------------------------------------------
3288 @Test
3389 public void testConstructors() {
4399 }
44100
45101 @Test
46 public void testConstructorNull() {
47 assertThrows(NullPointerException.class, () -> new MutableLong((Number) null));
48 }
49
50 @Test
51 public void testGetSet() {
52 final MutableLong mutNum = new MutableLong(0);
53 assertEquals(0, new MutableLong().longValue());
54 assertEquals(Long.valueOf(0), new MutableLong().getValue());
55
56 mutNum.setValue(1);
57 assertEquals(1, mutNum.longValue());
58 assertEquals(Long.valueOf(1), mutNum.getValue());
59
60 mutNum.setValue(Long.valueOf(2));
61 assertEquals(2, mutNum.longValue());
62 assertEquals(Long.valueOf(2), mutNum.getValue());
63
64 mutNum.setValue(new MutableLong(3));
65 assertEquals(3, mutNum.longValue());
66 assertEquals(Long.valueOf(3), mutNum.getValue());
67 }
68
69 @Test
70 public void testSetNull() {
71 final MutableLong mutNum = new MutableLong(0);
72 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
102 public void testDecrement() {
103 final MutableLong mutNum = new MutableLong(1);
104 mutNum.decrement();
105
106 assertEquals(0, mutNum.intValue());
107 assertEquals(0L, mutNum.longValue());
108 }
109
110 @Test
111 public void testDecrementAndGet() {
112 final MutableLong mutNum = new MutableLong(1L);
113 final long result = mutNum.decrementAndGet();
114
115 assertEquals(0, result);
116 assertEquals(0, mutNum.intValue());
117 assertEquals(0L, mutNum.longValue());
73118 }
74119
75120 @Test
91136 }
92137
93138 @Test
139 public void testGetAndAddValueObject() {
140 final MutableLong mutableLong = new MutableLong(0L);
141 final long result = mutableLong.getAndAdd(Long.valueOf(1L));
142
143 assertEquals(0L, result);
144 assertEquals(1L, mutableLong.longValue());
145 }
146
147 @Test
148 public void testGetAndAddValuePrimitive() {
149 final MutableLong mutableLong = new MutableLong(0L);
150 final long result = mutableLong.getAndAdd(1L);
151
152 assertEquals(0L, result);
153 assertEquals(1L, mutableLong.longValue());
154 }
155
156 @Test
157 public void testGetAndDecrement() {
158 final MutableLong mutNum = new MutableLong(1L);
159 final long result = mutNum.getAndDecrement();
160
161 assertEquals(1, result);
162 assertEquals(0, mutNum.intValue());
163 assertEquals(0L, mutNum.longValue());
164 }
165
166 @Test
167 public void testGetAndIncrement() {
168 final MutableLong mutNum = new MutableLong(1L);
169 final long result = mutNum.getAndIncrement();
170
171 assertEquals(1, result);
172 assertEquals(2, mutNum.intValue());
173 assertEquals(2L, mutNum.longValue());
174 }
175
176 @Test
177 public void testGetSet() {
178 final MutableLong mutNum = new MutableLong(0);
179 assertEquals(0, new MutableLong().longValue());
180 assertEquals(Long.valueOf(0), new MutableLong().getValue());
181
182 mutNum.setValue(1);
183 assertEquals(1, mutNum.longValue());
184 assertEquals(Long.valueOf(1), mutNum.getValue());
185
186 mutNum.setValue(Long.valueOf(2));
187 assertEquals(2, mutNum.longValue());
188 assertEquals(Long.valueOf(2), mutNum.getValue());
189
190 mutNum.setValue(new MutableLong(3));
191 assertEquals(3, mutNum.longValue());
192 assertEquals(Long.valueOf(3), mutNum.getValue());
193 }
194
195 @Test
94196 public void testHashCode() {
95197 final MutableLong mutNumA = new MutableLong(0);
96198 final MutableLong mutNumB = new MutableLong(0);
103205 }
104206
105207 @Test
106 public void testCompareTo() {
107 final MutableLong mutNum = new MutableLong(0);
108
109 assertEquals(0, mutNum.compareTo(new MutableLong(0)));
110 assertEquals(+1, mutNum.compareTo(new MutableLong(-1)));
111 assertEquals(-1, mutNum.compareTo(new MutableLong(1)));
112 }
113
114 @Test
115 public void testCompareToNull() {
116 final MutableLong mutNum = new MutableLong(0);
117 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
208 public void testIncrement() {
209 final MutableLong mutNum = new MutableLong(1);
210 mutNum.increment();
211
212 assertEquals(2, mutNum.intValue());
213 assertEquals(2L, mutNum.longValue());
214 }
215
216 @Test
217 public void testIncrementAndGet() {
218 final MutableLong mutNum = new MutableLong(1L);
219 final long result = mutNum.incrementAndGet();
220
221 assertEquals(2, result);
222 assertEquals(2, mutNum.intValue());
223 assertEquals(2L, mutNum.longValue());
118224 }
119225
120226 @Test
129235 }
130236
131237 @Test
238 public void testSetNull() {
239 final MutableLong mutNum = new MutableLong(0);
240 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
241 }
242
243 @Test
244 public void testSubtractValueObject() {
245 final MutableLong mutNum = new MutableLong(1);
246 mutNum.subtract(Long.valueOf(1));
247
248 assertEquals(0, mutNum.intValue());
249 assertEquals(0L, mutNum.longValue());
250 }
251
252 @Test
253 public void testSubtractValuePrimitive() {
254 final MutableLong mutNum = new MutableLong(1);
255 mutNum.subtract(1);
256
257 assertEquals(0, mutNum.intValue());
258 assertEquals(0L, mutNum.longValue());
259 }
260
261 @Test
132262 public void testToLong() {
133263 assertEquals(Long.valueOf(0L), new MutableLong(0L).toLong());
134264 assertEquals(Long.valueOf(123L), new MutableLong(123L).toLong());
135 }
136
137 @Test
138 public void testIncrement() {
139 final MutableLong mutNum = new MutableLong(1);
140 mutNum.increment();
141
142 assertEquals(2, mutNum.intValue());
143 assertEquals(2L, mutNum.longValue());
144 }
145
146 @Test
147 public void testIncrementAndGet() {
148 final MutableLong mutNum = new MutableLong(1L);
149 final long result = mutNum.incrementAndGet();
150
151 assertEquals(2, result);
152 assertEquals(2, mutNum.intValue());
153 assertEquals(2L, mutNum.longValue());
154 }
155
156 @Test
157 public void testGetAndIncrement() {
158 final MutableLong mutNum = new MutableLong(1L);
159 final long result = mutNum.getAndIncrement();
160
161 assertEquals(1, result);
162 assertEquals(2, mutNum.intValue());
163 assertEquals(2L, mutNum.longValue());
164 }
165
166 @Test
167 public void testDecrement() {
168 final MutableLong mutNum = new MutableLong(1);
169 mutNum.decrement();
170
171 assertEquals(0, mutNum.intValue());
172 assertEquals(0L, mutNum.longValue());
173 }
174
175 @Test
176 public void testDecrementAndGet() {
177 final MutableLong mutNum = new MutableLong(1L);
178 final long result = mutNum.decrementAndGet();
179
180 assertEquals(0, result);
181 assertEquals(0, mutNum.intValue());
182 assertEquals(0L, mutNum.longValue());
183 }
184
185 @Test
186 public void testGetAndDecrement() {
187 final MutableLong mutNum = new MutableLong(1L);
188 final long result = mutNum.getAndDecrement();
189
190 assertEquals(1, result);
191 assertEquals(0, mutNum.intValue());
192 assertEquals(0L, mutNum.longValue());
193 }
194
195 @Test
196 public void testAddValuePrimitive() {
197 final MutableLong mutNum = new MutableLong(1);
198 mutNum.add(1);
199
200 assertEquals(2, mutNum.intValue());
201 assertEquals(2L, mutNum.longValue());
202 }
203
204 @Test
205 public void testAddValueObject() {
206 final MutableLong mutNum = new MutableLong(1);
207 mutNum.add(Long.valueOf(1));
208
209 assertEquals(2, mutNum.intValue());
210 assertEquals(2L, mutNum.longValue());
211 }
212
213 @Test
214 public void testGetAndAddValuePrimitive() {
215 final MutableLong mutableLong = new MutableLong(0L);
216 final long result = mutableLong.getAndAdd(1L);
217
218 assertEquals(0L, result);
219 assertEquals(1L, mutableLong.longValue());
220 }
221
222 @Test
223 public void testGetAndAddValueObject() {
224 final MutableLong mutableLong = new MutableLong(0L);
225 final long result = mutableLong.getAndAdd(Long.valueOf(1L));
226
227 assertEquals(0L, result);
228 assertEquals(1L, mutableLong.longValue());
229 }
230
231 @Test
232 public void testAddAndGetValuePrimitive() {
233 final MutableLong mutableLong = new MutableLong(0L);
234 final long result = mutableLong.addAndGet(1L);
235
236 assertEquals(1L, result);
237 assertEquals(1L, mutableLong.longValue());
238 }
239
240 @Test
241 public void testAddAndGetValueObject() {
242 final MutableLong mutableLong = new MutableLong(0L);
243 final long result = mutableLong.addAndGet(Long.valueOf(1L));
244
245 assertEquals(1L, result);
246 assertEquals(1L, mutableLong.longValue());
247 }
248
249 @Test
250 public void testSubtractValuePrimitive() {
251 final MutableLong mutNum = new MutableLong(1);
252 mutNum.subtract(1);
253
254 assertEquals(0, mutNum.intValue());
255 assertEquals(0L, mutNum.longValue());
256 }
257
258 @Test
259 public void testSubtractValueObject() {
260 final MutableLong mutNum = new MutableLong(1);
261 mutNum.subtract(Long.valueOf(1));
262
263 assertEquals(0, mutNum.intValue());
264 assertEquals(0L, mutNum.longValue());
265265 }
266266
267267 @Test
4242 }
4343
4444 @Test
45 public void testGetSet() {
46 final MutableObject<String> mutNum = new MutableObject<>();
47 assertNull(new MutableObject<>().getValue());
48
49 mutNum.setValue("HELLO");
50 assertSame("HELLO", mutNum.getValue());
51
52 mutNum.setValue(null);
53 assertSame(null, mutNum.getValue());
54 }
55
56 @Test
5745 public void testEquals() {
5846 final MutableObject<String> mutNumA = new MutableObject<>("ALPHA");
5947 final MutableObject<String> mutNumB = new MutableObject<>("ALPHA");
7361 assertNotEquals(null, mutNumA);
7462 assertNotEquals(mutNumA, new Object());
7563 assertNotEquals("0", mutNumA);
64 }
65
66 @Test
67 public void testGetSet() {
68 final MutableObject<String> mutNum = new MutableObject<>();
69 assertNull(new MutableObject<>().getValue());
70
71 mutNum.setValue("HELLO");
72 assertSame("HELLO", mutNum.getValue());
73
74 mutNum.setValue(null);
75 assertSame(null, mutNum.getValue());
7676 }
7777
7878 @Test
2828 */
2929 public class MutableShortTest {
3030
31 @Test
32 public void testAddAndGetValueObject() {
33 final MutableShort mutableShort = new MutableShort((short) 0);
34 final short result = mutableShort.addAndGet(Short.valueOf((short) 1));
35
36 assertEquals((short) 1, result);
37 assertEquals((short) 1, mutableShort.shortValue());
38 }
39
40 @Test
41 public void testAddAndGetValuePrimitive() {
42 final MutableShort mutableShort = new MutableShort((short) 0);
43 final short result = mutableShort.addAndGet((short) 1);
44
45 assertEquals((short) 1, result);
46 assertEquals((short) 1, mutableShort.shortValue());
47 }
48
49 @Test
50 public void testAddValueObject() {
51 final MutableShort mutNum = new MutableShort((short) 1);
52 mutNum.add(Short.valueOf((short) 1));
53
54 assertEquals((short) 2, mutNum.shortValue());
55 }
56
57 @Test
58 public void testAddValuePrimitive() {
59 final MutableShort mutNum = new MutableShort((short) 1);
60 mutNum.add((short) 1);
61
62 assertEquals((short) 2, mutNum.shortValue());
63 }
64
65 @Test
66 public void testCompareTo() {
67 final MutableShort mutNum = new MutableShort((short) 0);
68
69 assertEquals((short) 0, mutNum.compareTo(new MutableShort((short) 0)));
70 assertEquals((short) +1, mutNum.compareTo(new MutableShort((short) -1)));
71 assertEquals((short) -1, mutNum.compareTo(new MutableShort((short) 1)));
72 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
73 }
74
3175 // ----------------------------------------------------------------
3276 @Test
3377 public void testConstructors() {
4488 }
4589
4690 @Test
47 public void testGetSet() {
48 final MutableShort mutNum = new MutableShort((short) 0);
49 assertEquals((short) 0, new MutableShort().shortValue());
50 assertEquals(Short.valueOf((short) 0), new MutableShort().getValue());
51
52 mutNum.setValue((short) 1);
53 assertEquals((short) 1, mutNum.shortValue());
54 assertEquals(Short.valueOf((short) 1), mutNum.getValue());
55
56 mutNum.setValue(Short.valueOf((short) 2));
57 assertEquals((short) 2, mutNum.shortValue());
58 assertEquals(Short.valueOf((short) 2), mutNum.getValue());
59
60 mutNum.setValue(new MutableShort((short) 3));
61 assertEquals((short) 3, mutNum.shortValue());
62 assertEquals(Short.valueOf((short) 3), mutNum.getValue());
63 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
91 public void testDecrement() {
92 final MutableShort mutNum = new MutableShort((short) 1);
93 mutNum.decrement();
94
95 assertEquals(0, mutNum.intValue());
96 assertEquals(0L, mutNum.longValue());
97 }
98
99 @Test
100 public void testDecrementAndGet() {
101 final MutableShort mutNum = new MutableShort((short) 1);
102 final short result = mutNum.decrementAndGet();
103
104 assertEquals(0, result);
105 assertEquals(0, mutNum.intValue());
106 assertEquals(0L, mutNum.longValue());
64107 }
65108
66109 @Test
82125 }
83126
84127 @Test
128 public void testGetAndAddValueObject() {
129 final MutableShort mutableShort = new MutableShort((short) 0);
130 final short result = mutableShort.getAndAdd(Short.valueOf((short) 1));
131
132 assertEquals((short) 0, result);
133 assertEquals((short) 1, mutableShort.shortValue());
134 }
135
136 @Test
137 public void testGetAndAddValuePrimitive() {
138 final MutableShort mutableShort = new MutableShort((short) 0);
139 final short result = mutableShort.getAndAdd((short) 1);
140
141 assertEquals((short) 0, result);
142 assertEquals((short) 1, mutableShort.shortValue());
143 }
144
145 @Test
146 public void testGetAndDecrement() {
147 final MutableShort mutNum = new MutableShort((short) 1);
148 final short result = mutNum.getAndDecrement();
149
150 assertEquals(1, result);
151 assertEquals(0, mutNum.intValue());
152 assertEquals(0L, mutNum.longValue());
153 }
154
155 @Test
156 public void testGetAndIncrement() {
157 final MutableShort mutNum = new MutableShort((short) 1);
158 final short result = mutNum.getAndIncrement();
159
160 assertEquals(1, result);
161 assertEquals(2, mutNum.intValue());
162 assertEquals(2L, mutNum.longValue());
163 }
164
165 @Test
166 public void testGetSet() {
167 final MutableShort mutNum = new MutableShort((short) 0);
168 assertEquals((short) 0, new MutableShort().shortValue());
169 assertEquals(Short.valueOf((short) 0), new MutableShort().getValue());
170
171 mutNum.setValue((short) 1);
172 assertEquals((short) 1, mutNum.shortValue());
173 assertEquals(Short.valueOf((short) 1), mutNum.getValue());
174
175 mutNum.setValue(Short.valueOf((short) 2));
176 assertEquals((short) 2, mutNum.shortValue());
177 assertEquals(Short.valueOf((short) 2), mutNum.getValue());
178
179 mutNum.setValue(new MutableShort((short) 3));
180 assertEquals((short) 3, mutNum.shortValue());
181 assertEquals(Short.valueOf((short) 3), mutNum.getValue());
182 assertThrows(NullPointerException.class, () -> mutNum.setValue(null));
183 }
184
185 @Test
85186 public void testHashCode() {
86187 final MutableShort mutNumA = new MutableShort((short) 0);
87188 final MutableShort mutNumB = new MutableShort((short) 0);
94195 }
95196
96197 @Test
97 public void testCompareTo() {
98 final MutableShort mutNum = new MutableShort((short) 0);
99
100 assertEquals((short) 0, mutNum.compareTo(new MutableShort((short) 0)));
101 assertEquals((short) +1, mutNum.compareTo(new MutableShort((short) -1)));
102 assertEquals((short) -1, mutNum.compareTo(new MutableShort((short) 1)));
103 assertThrows(NullPointerException.class, () -> mutNum.compareTo(null));
198 public void testIncrement() {
199 final MutableShort mutNum = new MutableShort((short) 1);
200 mutNum.increment();
201
202 assertEquals(2, mutNum.intValue());
203 assertEquals(2L, mutNum.longValue());
204 }
205
206 @Test
207 public void testIncrementAndGet() {
208 final MutableShort mutNum = new MutableShort((short) 1);
209 final short result = mutNum.incrementAndGet();
210
211 assertEquals(2, result);
212 assertEquals(2, mutNum.intValue());
213 assertEquals(2L, mutNum.longValue());
104214 }
105215
106216 @Test
115225 }
116226
117227 @Test
228 public void testSubtractValueObject() {
229 final MutableShort mutNum = new MutableShort((short) 1);
230 mutNum.subtract(Short.valueOf((short) 1));
231
232 assertEquals((short) 0, mutNum.shortValue());
233 }
234
235 @Test
236 public void testSubtractValuePrimitive() {
237 final MutableShort mutNum = new MutableShort((short) 1);
238 mutNum.subtract((short) 1);
239
240 assertEquals((short) 0, mutNum.shortValue());
241 }
242
243 @Test
118244 public void testToShort() {
119245 assertEquals(Short.valueOf((short) 0), new MutableShort((short) 0).toShort());
120246 assertEquals(Short.valueOf((short) 123), new MutableShort((short) 123).toShort());
121 }
122
123 @Test
124 public void testIncrement() {
125 final MutableShort mutNum = new MutableShort((short) 1);
126 mutNum.increment();
127
128 assertEquals(2, mutNum.intValue());
129 assertEquals(2L, mutNum.longValue());
130 }
131
132 @Test
133 public void testIncrementAndGet() {
134 final MutableShort mutNum = new MutableShort((short) 1);
135 final short result = mutNum.incrementAndGet();
136
137 assertEquals(2, result);
138 assertEquals(2, mutNum.intValue());
139 assertEquals(2L, mutNum.longValue());
140 }
141
142 @Test
143 public void testGetAndIncrement() {
144 final MutableShort mutNum = new MutableShort((short) 1);
145 final short result = mutNum.getAndIncrement();
146
147 assertEquals(1, result);
148 assertEquals(2, mutNum.intValue());
149 assertEquals(2L, mutNum.longValue());
150 }
151
152 @Test
153 public void testDecrement() {
154 final MutableShort mutNum = new MutableShort((short) 1);
155 mutNum.decrement();
156
157 assertEquals(0, mutNum.intValue());
158 assertEquals(0L, mutNum.longValue());
159 }
160
161 @Test
162 public void testDecrementAndGet() {
163 final MutableShort mutNum = new MutableShort((short) 1);
164 final short result = mutNum.decrementAndGet();
165
166 assertEquals(0, result);
167 assertEquals(0, mutNum.intValue());
168 assertEquals(0L, mutNum.longValue());
169 }
170
171 @Test
172 public void testGetAndDecrement() {
173 final MutableShort mutNum = new MutableShort((short) 1);
174 final short result = mutNum.getAndDecrement();
175
176 assertEquals(1, result);
177 assertEquals(0, mutNum.intValue());
178 assertEquals(0L, mutNum.longValue());
179 }
180
181 @Test
182 public void testAddValuePrimitive() {
183 final MutableShort mutNum = new MutableShort((short) 1);
184 mutNum.add((short) 1);
185
186 assertEquals((short) 2, mutNum.shortValue());
187 }
188
189 @Test
190 public void testAddValueObject() {
191 final MutableShort mutNum = new MutableShort((short) 1);
192 mutNum.add(Short.valueOf((short) 1));
193
194 assertEquals((short) 2, mutNum.shortValue());
195 }
196
197 @Test
198 public void testGetAndAddValuePrimitive() {
199 final MutableShort mutableShort = new MutableShort((short) 0);
200 final short result = mutableShort.getAndAdd((short) 1);
201
202 assertEquals((short) 0, result);
203 assertEquals((short) 1, mutableShort.shortValue());
204 }
205
206 @Test
207 public void testGetAndAddValueObject() {
208 final MutableShort mutableShort = new MutableShort((short) 0);
209 final short result = mutableShort.getAndAdd(Short.valueOf((short) 1));
210
211 assertEquals((short) 0, result);
212 assertEquals((short) 1, mutableShort.shortValue());
213 }
214
215 @Test
216 public void testAddAndGetValuePrimitive() {
217 final MutableShort mutableShort = new MutableShort((short) 0);
218 final short result = mutableShort.addAndGet((short) 1);
219
220 assertEquals((short) 1, result);
221 assertEquals((short) 1, mutableShort.shortValue());
222 }
223
224 @Test
225 public void testAddAndGetValueObject() {
226 final MutableShort mutableShort = new MutableShort((short) 0);
227 final short result = mutableShort.addAndGet(Short.valueOf((short) 1));
228
229 assertEquals((short) 1, result);
230 assertEquals((short) 1, mutableShort.shortValue());
231 }
232
233 @Test
234 public void testSubtractValuePrimitive() {
235 final MutableShort mutNum = new MutableShort((short) 1);
236 mutNum.subtract((short) 1);
237
238 assertEquals((short) 0, mutNum.shortValue());
239 }
240
241 @Test
242 public void testSubtractValueObject() {
243 final MutableShort mutNum = new MutableShort((short) 1);
244 mutNum.subtract(Short.valueOf((short) 1));
245
246 assertEquals((short) 0, mutNum.shortValue());
247247 }
248248
249249 @Test
3333 import java.util.HashSet;
3434 import java.util.List;
3535
36 import org.apache.commons.lang3.ArraySorter;
3637 import org.apache.commons.lang3.ArrayUtils;
3738 import org.apache.commons.lang3.JavaVersion;
3839 import org.apache.commons.lang3.SystemUtils;
40 import org.apache.commons.lang3.compare.ObjectToStringComparator;
3941 import org.apache.commons.lang3.reflect.testbed.Ambig;
4042 import org.apache.commons.lang3.reflect.testbed.Annotated;
4143 import org.apache.commons.lang3.reflect.testbed.Foo;
164166 @Test
165167 public void testGetAllFields() {
166168 assertArrayEquals(new Field[0], FieldUtils.getAllFields(Object.class));
167 final Field[] fieldsNumber = Number.class.getDeclaredFields();
168 assertArrayEquals(fieldsNumber, FieldUtils.getAllFields(Number.class));
169 final Field[] fieldsNumber = sort(Number.class.getDeclaredFields());
170 assertArrayEquals(fieldsNumber, sort(FieldUtils.getAllFields(Number.class)));
169171 final Field[] fieldsInteger = Integer.class.getDeclaredFields();
170 assertArrayEquals(ArrayUtils.addAll(fieldsInteger, fieldsNumber), FieldUtils.getAllFields(Integer.class));
172 assertArrayEquals(sort(ArrayUtils.addAll(fieldsInteger, fieldsNumber)), sort(FieldUtils.getAllFields(Integer.class)));
171173 final Field[] allFields = FieldUtils.getAllFields(PublicChild.class);
172174 // Under Jacoco,0.8.1 and Java 10, the field count is 7.
173175 int expected = 5;
177179 }
178180 }
179181 assertEquals(expected, allFields.length, Arrays.toString(allFields));
182 }
183
184 private Field[] sort(final Field[] fields) {
185 // Field does not implement Comparable, so we use a KISS solution here.
186 return ArraySorter.sort(fields, ObjectToStringComparator.INSTANCE);
180187 }
181188
182189 @Test
203210 @Test
204211 public void testGetFieldsWithAnnotation() throws NoSuchFieldException {
205212 assertArrayEquals(new Field[0], FieldUtils.getFieldsWithAnnotation(Object.class, Annotated.class));
206 final Field[] annotatedFields = new Field[]{
213 final Field[] annotatedFields = sort(new Field[] {
207214 FieldUtilsTest.class.getDeclaredField("publicChild"),
208 FieldUtilsTest.class.getDeclaredField("privatelyShadowedChild")
209 };
210 assertArrayEquals(annotatedFields, FieldUtils.getFieldsWithAnnotation(FieldUtilsTest.class, Annotated.class));
215 FieldUtilsTest.class.getDeclaredField("privatelyShadowedChild") });
216 assertArrayEquals(annotatedFields,
217 sort(FieldUtils.getFieldsWithAnnotation(FieldUtilsTest.class, Annotated.class)));
211218 }
212219
213220 @Test
2828 import static org.junit.jupiter.api.Assertions.assertThrows;
2929 import static org.junit.jupiter.api.Assertions.assertTrue;
3030
31 import java.awt.Color;
3132 import java.lang.reflect.Method;
3233 import java.lang.reflect.Type;
3334 import java.util.Arrays;
10171018
10181019 distanceMethod.setAccessible(false);
10191020 }
1021
1022 @Test
1023 public void testGetMatchingMethod() throws NoSuchMethodException {
1024 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod"),
1025 GetMatchingMethodClass.class.getMethod("testMethod"));
1026
1027 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod", Long.TYPE),
1028 GetMatchingMethodClass.class.getMethod("testMethod", Long.TYPE));
1029
1030 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod", Long.class),
1031 GetMatchingMethodClass.class.getMethod("testMethod", Long.class));
1032
1033 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod", (Class<?>) null),
1034 GetMatchingMethodClass.class.getMethod("testMethod", Long.class));
1035
1036 assertThrows(IllegalStateException.class,
1037 () -> MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod2", (Class<?>) null));
1038
1039 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", Long.TYPE, Long.class),
1040 GetMatchingMethodClass.class.getMethod("testMethod3", Long.TYPE, Long.class));
1041
1042 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", Long.class, Long.TYPE),
1043 GetMatchingMethodClass.class.getMethod("testMethod3", Long.class, Long.TYPE));
1044
1045 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", null, Long.TYPE),
1046 GetMatchingMethodClass.class.getMethod("testMethod3", Long.class, Long.TYPE));
1047
1048 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", Long.TYPE, null),
1049 GetMatchingMethodClass.class.getMethod("testMethod3", Long.TYPE, Long.class));
1050
1051 assertThrows(IllegalStateException.class,
1052 () -> MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod4", null, null));
1053 }
1054
1055 private static final class GetMatchingMethodClass {
1056 public void testMethod() {
1057 }
1058
1059 public void testMethod(final Long aLong) {
1060 }
1061
1062 public void testMethod(final long aLong) {
1063 }
1064
1065 public void testMethod2(final Long aLong) {
1066 }
1067
1068 public void testMethod2(final Color aColor) {
1069 }
1070
1071 public void testMethod2(final long aLong) {
1072 }
1073
1074 public void testMethod3(final long aLong, final Long anotherLong) {
1075 }
1076
1077 public void testMethod3(final Long aLong, final long anotherLong) {
1078 }
1079
1080 public void testMethod3(final Long aLong, final Long anotherLong) {
1081 }
1082
1083 public void testMethod4(final Long aLong, final Long anotherLong) {
1084 }
1085
1086 public void testMethod4(final Color aColor1, final Color aColor2) {
1087 }
1088 }
10201089 }
2121 import static org.junit.jupiter.api.Assertions.assertNull;
2222 import static org.junit.jupiter.api.Assertions.assertTrue;
2323
24 import java.awt.Insets;
2425 import java.io.Serializable;
26 import java.lang.reflect.Constructor;
2527 import java.lang.reflect.Field;
2628 import java.lang.reflect.GenericArrayType;
2729 import java.lang.reflect.Method;
3638 import java.util.HashMap;
3739 import java.util.List;
3840 import java.util.Map;
41 import java.util.Properties;
3942 import java.util.TreeSet;
4043
4144 import org.apache.commons.lang3.reflect.testbed.Foo;
4245 import org.apache.commons.lang3.reflect.testbed.GenericParent;
4346 import org.apache.commons.lang3.reflect.testbed.GenericTypeHolder;
4447 import org.apache.commons.lang3.reflect.testbed.StringParameterizedChild;
48 import org.junit.jupiter.api.Disabled;
4549 import org.junit.jupiter.api.Test;
50
51 class AAAClass extends AAClass<String> {
52 public class BBBClass extends BBClass<String> {
53 }
54 }
55
56 class AAClass<T> {
57
58 public class BBClass<S> {
59 }
60 }
61
62 @SuppressWarnings("rawtypes")
63 //raw types, where used, are used purposely
64 class AClass extends AAClass<String>.BBClass<Number> {
65
66 public interface AInterface<T> {
67 }
68
69 public class BClass<T> {
70 }
71
72 public class CClass<T> extends BClass {
73 }
74
75 public class DClass<T> extends CClass<T> {
76 }
77
78 public class EClass<T> extends DClass {
79 }
80
81 public class FClass extends EClass<String> {
82 }
83
84 public class GClass<T extends BClass<? extends T> & AInterface<AInterface<? super T>>> {
85 }
86
87 public BClass<Number> bClass;
88
89 public CClass<? extends String> cClass;
90
91 public DClass<String> dClass;
92
93 public EClass<String> eClass;
94
95 public FClass fClass;
96
97 public GClass gClass;
98
99 AClass(final AAClass<String> enclosingInstance) {
100 enclosingInstance.super();
101 }
102 }
103 @SuppressWarnings("rawtypes")
104 abstract class Test1<G> {
105 public abstract Object m0();
106 public abstract String[] m1();
107 public abstract <E> E[] m2();
108 public abstract <E> List<? extends E> m3();
109 public abstract <E extends Enum<E>> List<? extends Enum<E>> m4();
110 public abstract List<? extends Enum<?>> m5();
111 public abstract List<? super Enum<?>> m6();
112 public abstract List<?> m7();
113 public abstract Map<? extends Enum<?>, ? super Enum<?>> m8();
114 public abstract <K, V> Map<? extends K, ? super V[]> m9();
115 public abstract <K, V> Map<? extends K, V[]> m10();
116 public abstract <K, V> Map<? extends K, List<V[]>> m11();
117 public abstract List m12();
118 public abstract Map m13();
119 public abstract Properties m14();
120 public abstract G m15();
121 public abstract List<G> m16();
122 public abstract Enum m17();
123 }
46124
47125 /**
48126 * Test TypeUtils
51129 //raw types, where used, are used purposely
52130 public class TypeUtilsTest<B> {
53131
132 public interface And<K, V> extends This<Number, Number> {
133 }
134
135 public static class ClassWithSuperClassWithGenericType extends ArrayList<Object> {
136 private static final long serialVersionUID = 1L;
137
138 public static <U> Iterable<U> methodWithGenericReturnType() {
139 return null;
140 }
141 }
142
143 public class Other<T> implements This<String, T> {
144 }
145
146 public class Tester implements This<String, B> {
147 }
148
149 public class That<K, V> implements This<K, V> {
150 }
151
152 public class The<K, V> extends That<Number, Number> implements And<String, String> {
153 }
154
155 public class Thing<Q> extends Other<B> {
156 }
157
54158 public interface This<K, V> {
55159 }
56160
57 public class That<K, V> implements This<K, V> {
58 }
59
60 public interface And<K, V> extends This<Number, Number> {
61 }
62
63 public class The<K, V> extends That<Number, Number> implements And<String, String> {
64 }
65
66 public class Other<T> implements This<String, T> {
67 }
68
69 public class Thing<Q> extends Other<B> {
70 }
71
72 public class Tester implements This<String, B> {
161 public static Comparable<String> stringComparable;
162
163 public static Comparable<URI> uriComparable;
164
165 public static Comparable<Integer> intComparable;
166
167 public static Comparable<Long> longComparable;
168
169 public static Comparable<?> wildcardComparable;
170
171 public static URI uri;
172
173 public static List<String>[] stringListArray;
174
175 public static <G extends Comparable<G>> G stub() {
176 return null;
177 }
178
179 public static <G extends Comparable<? super G>> G stub2() {
180 return null;
181 }
182
183 public static <T extends Comparable<? extends T>> T stub3() {
184 return null;
73185 }
74186
75187 public This<String, String> dis;
92204
93205 public Comparable<? extends Integer>[] intWildcardComparable;
94206
95 public static Comparable<String> stringComparable;
96
97 public static Comparable<URI> uriComparable;
98
99 public static Comparable<Integer> intComparable;
100
101 public static Comparable<Long> longComparable;
102
103 public static Comparable<?> wildcardComparable;
104
105 public static URI uri;
106
107 public static List<String>[] stringListArray;
207 public Iterable<? extends Map<Integer, ? extends Collection<?>>> iterable;
208
209 public void delegateBooleanAssertion(final Type[] types, final int i2, final int i1, final boolean expected) {
210 final Type type1 = types[i1];
211 final Type type2 = types[i2];
212 final boolean isAssignable = TypeUtils.isAssignable(type2, type1);
213
214 if (expected) {
215 assertTrue(isAssignable,
216 "[" + i1 + ", " + i2 + "]: From "
217 + String.valueOf(type2) + " to "
218 + String.valueOf(type1));
219 } else {
220 assertFalse(isAssignable,
221 "[" + i1 + ", " + i2 + "]: From "
222 + String.valueOf(type2) + " to "
223 + String.valueOf(type1));
224 }
225 }
108226
109227 public void dummyMethod(final List list0, final List<Object> list1, final List<?> list2,
110228 final List<? super Object> list3, final List<String> list4, final List<? extends String> list5,
113231 final List<? super String>[] list13) {
114232 }
115233
234 @Test
235 public void testContainsTypeVariables() throws Exception {
236 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m0").getGenericReturnType()));
237 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m1").getGenericReturnType()));
238 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m2").getGenericReturnType()));
239 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m3").getGenericReturnType()));
240 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m4").getGenericReturnType()));
241 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m5").getGenericReturnType()));
242 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m6").getGenericReturnType()));
243 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m7").getGenericReturnType()));
244 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m8").getGenericReturnType()));
245 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m9").getGenericReturnType()));
246 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m10").getGenericReturnType()));
247 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m11").getGenericReturnType()));
248 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m12").getGenericReturnType()));
249 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m13").getGenericReturnType()));
250 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m14").getGenericReturnType()));
251 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m15").getGenericReturnType()));
252 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m16").getGenericReturnType()));
253 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m17").getGenericReturnType()));
254 }
255
256 @Test
257 public void testDetermineTypeVariableAssignments() throws SecurityException,
258 NoSuchFieldException {
259 final ParameterizedType iterableType = (ParameterizedType) getClass().getField("iterable")
260 .getGenericType();
261 final Map<TypeVariable<?>, Type> typeVarAssigns = TypeUtils.determineTypeArguments(TreeSet.class,
262 iterableType);
263 final TypeVariable<?> treeSetTypeVar = TreeSet.class.getTypeParameters()[0];
264 assertTrue(typeVarAssigns.containsKey(treeSetTypeVar));
265 assertEquals(iterableType.getActualTypeArguments()[0], typeVarAssigns
266 .get(treeSetTypeVar));
267 }
268
269 @Test
270 public void testGenericArrayType() throws Exception {
271 final Type expected = getClass().getField("intWildcardComparable").getGenericType();
272 final GenericArrayType actual =
273 TypeUtils.genericArrayType(TypeUtils.parameterize(Comparable.class, TypeUtils.wildcardType()
274 .withUpperBounds(Integer.class).build()));
275 assertTrue(TypeUtils.equals(expected, actual));
276 assertEquals("java.lang.Comparable<? extends java.lang.Integer>[]", actual.toString());
277 }
278
279 @Test
280 public void testGetArrayComponentType() throws Exception {
281 final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
282 List.class, List.class, List.class, List.class, List[].class, List[].class,
283 List[].class, List[].class, List[].class, List[].class, List[].class);
284
285 final Type[] types = method.getGenericParameterTypes();
286
287 assertNull(TypeUtils.getArrayComponentType(types[0]));
288 assertNull(TypeUtils.getArrayComponentType(types[1]));
289 assertNull(TypeUtils.getArrayComponentType(types[2]));
290 assertNull(TypeUtils.getArrayComponentType(types[3]));
291 assertNull(TypeUtils.getArrayComponentType(types[4]));
292 assertNull(TypeUtils.getArrayComponentType(types[5]));
293 assertNull(TypeUtils.getArrayComponentType(types[6]));
294 assertEquals(types[0], TypeUtils.getArrayComponentType(types[7]));
295 assertEquals(types[1], TypeUtils.getArrayComponentType(types[8]));
296 assertEquals(types[2], TypeUtils.getArrayComponentType(types[9]));
297 assertEquals(types[3], TypeUtils.getArrayComponentType(types[10]));
298 assertEquals(types[4], TypeUtils.getArrayComponentType(types[11]));
299 assertEquals(types[5], TypeUtils.getArrayComponentType(types[12]));
300 assertEquals(types[6], TypeUtils.getArrayComponentType(types[13]));
301 }
302
303 @Test
304 public void testGetPrimitiveArrayComponentType() {
305 assertEquals(boolean.class, TypeUtils.getArrayComponentType(boolean[].class));
306 assertEquals(byte.class, TypeUtils.getArrayComponentType(byte[].class));
307 assertEquals(short.class, TypeUtils.getArrayComponentType(short[].class));
308 assertEquals(int.class, TypeUtils.getArrayComponentType(int[].class));
309 assertEquals(char.class, TypeUtils.getArrayComponentType(char[].class));
310 assertEquals(long.class, TypeUtils.getArrayComponentType(long[].class));
311 assertEquals(float.class, TypeUtils.getArrayComponentType(float[].class));
312 assertEquals(double.class, TypeUtils.getArrayComponentType(double[].class));
313
314 assertNull(TypeUtils.getArrayComponentType(boolean.class));
315 assertNull(TypeUtils.getArrayComponentType(byte.class));
316 assertNull(TypeUtils.getArrayComponentType(short.class));
317 assertNull(TypeUtils.getArrayComponentType(int.class));
318 assertNull(TypeUtils.getArrayComponentType(char.class));
319 assertNull(TypeUtils.getArrayComponentType(long.class));
320 assertNull(TypeUtils.getArrayComponentType(float.class));
321 assertNull(TypeUtils.getArrayComponentType(double.class));
322 }
323
324 @Test
325 public void testGetRawType() throws SecurityException, NoSuchFieldException {
326 final Type stringParentFieldType = GenericTypeHolder.class.getDeclaredField("stringParent")
327 .getGenericType();
328 final Type integerParentFieldType = GenericTypeHolder.class.getDeclaredField("integerParent")
329 .getGenericType();
330 final Type foosFieldType = GenericTypeHolder.class.getDeclaredField("foos").getGenericType();
331 final Type genericParentT = GenericParent.class.getTypeParameters()[0];
332 assertEquals(GenericParent.class, TypeUtils.getRawType(stringParentFieldType, null));
333 assertEquals(GenericParent.class, TypeUtils.getRawType(integerParentFieldType,
334 null));
335 assertEquals(List.class, TypeUtils.getRawType(foosFieldType, null));
336 assertEquals(String.class, TypeUtils.getRawType(genericParentT,
337 StringParameterizedChild.class));
338 assertEquals(String.class, TypeUtils.getRawType(genericParentT,
339 stringParentFieldType));
340 assertEquals(Foo.class, TypeUtils.getRawType(Iterable.class.getTypeParameters()[0],
341 foosFieldType));
342 assertEquals(Foo.class, TypeUtils.getRawType(List.class.getTypeParameters()[0],
343 foosFieldType));
344 assertNull(TypeUtils.getRawType(genericParentT, GenericParent.class));
345 assertEquals(GenericParent[].class, TypeUtils.getRawType(GenericTypeHolder.class
346 .getDeclaredField("barParents").getGenericType(), null));
347 }
348
349 @Test
350 public void testGetTypeArguments() {
351 Map<TypeVariable<?>, Type> typeVarAssigns;
352 TypeVariable<?> treeSetTypeVar;
353 Type typeArg;
354
355 typeVarAssigns = TypeUtils.getTypeArguments(Integer.class, Comparable.class);
356 treeSetTypeVar = Comparable.class.getTypeParameters()[0];
357 assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
358 "Type var assigns for Comparable from Integer: " + typeVarAssigns);
359 typeArg = typeVarAssigns.get(treeSetTypeVar);
360 assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
361 "Type argument of Comparable from Integer: " + typeArg);
362
363 typeVarAssigns = TypeUtils.getTypeArguments(int.class, Comparable.class);
364 treeSetTypeVar = Comparable.class.getTypeParameters()[0];
365 assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
366 "Type var assigns for Comparable from int: " + typeVarAssigns);
367 typeArg = typeVarAssigns.get(treeSetTypeVar);
368 assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
369 "Type argument of Comparable from int: " + typeArg);
370
371 final Collection<Integer> col = Collections.emptyList();
372 typeVarAssigns = TypeUtils.getTypeArguments(List.class, Collection.class);
373 treeSetTypeVar = Comparable.class.getTypeParameters()[0];
374 assertFalse(typeVarAssigns.containsKey(treeSetTypeVar),
375 "Type var assigns for Collection from List: " + typeVarAssigns);
376
377 typeVarAssigns = TypeUtils.getTypeArguments(AAAClass.BBBClass.class, AAClass.BBClass.class);
378 assertEquals(2, typeVarAssigns.size());
379 assertEquals(String.class, typeVarAssigns.get(AAClass.class.getTypeParameters()[0]));
380 assertEquals(String.class, typeVarAssigns.get(AAClass.BBClass.class.getTypeParameters()[0]));
381
382 typeVarAssigns = TypeUtils.getTypeArguments(Other.class, This.class);
383 assertEquals(2, typeVarAssigns.size());
384 assertEquals(String.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
385 assertEquals(Other.class.getTypeParameters()[0], typeVarAssigns.get(This.class.getTypeParameters()[1]));
386
387 typeVarAssigns = TypeUtils.getTypeArguments(And.class, This.class);
388 assertEquals(2, typeVarAssigns.size());
389 assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
390 assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[1]));
391
392 typeVarAssigns = TypeUtils.getTypeArguments(Thing.class, Other.class);
393 assertEquals(2, typeVarAssigns.size());
394 assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(getClass().getTypeParameters()[0]));
395 assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(Other.class.getTypeParameters()[0]));
396 }
397
398 @Test
399 public void testIsArrayGenericTypes() throws Exception {
400 final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
401 List.class, List.class, List.class, List.class, List[].class, List[].class,
402 List[].class, List[].class, List[].class, List[].class, List[].class);
403
404 final Type[] types = method.getGenericParameterTypes();
405
406 assertFalse(TypeUtils.isArrayType(types[0]));
407 assertFalse(TypeUtils.isArrayType(types[1]));
408 assertFalse(TypeUtils.isArrayType(types[2]));
409 assertFalse(TypeUtils.isArrayType(types[3]));
410 assertFalse(TypeUtils.isArrayType(types[4]));
411 assertFalse(TypeUtils.isArrayType(types[5]));
412 assertFalse(TypeUtils.isArrayType(types[6]));
413 assertTrue(TypeUtils.isArrayType(types[7]));
414 assertTrue(TypeUtils.isArrayType(types[8]));
415 assertTrue(TypeUtils.isArrayType(types[9]));
416 assertTrue(TypeUtils.isArrayType(types[10]));
417 assertTrue(TypeUtils.isArrayType(types[11]));
418 assertTrue(TypeUtils.isArrayType(types[12]));
419 assertTrue(TypeUtils.isArrayType(types[13]));
420 }
421
422 @Test
423 public void testIsArrayTypeClasses() {
424 assertTrue(TypeUtils.isArrayType(boolean[].class));
425 assertTrue(TypeUtils.isArrayType(byte[].class));
426 assertTrue(TypeUtils.isArrayType(short[].class));
427 assertTrue(TypeUtils.isArrayType(int[].class));
428 assertTrue(TypeUtils.isArrayType(char[].class));
429 assertTrue(TypeUtils.isArrayType(long[].class));
430 assertTrue(TypeUtils.isArrayType(float[].class));
431 assertTrue(TypeUtils.isArrayType(double[].class));
432 assertTrue(TypeUtils.isArrayType(Object[].class));
433 assertTrue(TypeUtils.isArrayType(String[].class));
434
435 assertFalse(TypeUtils.isArrayType(boolean.class));
436 assertFalse(TypeUtils.isArrayType(byte.class));
437 assertFalse(TypeUtils.isArrayType(short.class));
438 assertFalse(TypeUtils.isArrayType(int.class));
439 assertFalse(TypeUtils.isArrayType(char.class));
440 assertFalse(TypeUtils.isArrayType(long.class));
441 assertFalse(TypeUtils.isArrayType(float.class));
442 assertFalse(TypeUtils.isArrayType(double.class));
443 assertFalse(TypeUtils.isArrayType(Object.class));
444 assertFalse(TypeUtils.isArrayType(String.class));
445 }
446
116447 @SuppressWarnings("boxing") // deliberately used here
117448 @Test
118449 public void testIsAssignable() throws SecurityException, NoSuchMethodException,
119450 NoSuchFieldException {
120451 List list0 = null;
121 List<Object> list1 = null;
122 List<?> list2 = null;
123 List<? super Object> list3 = null;
124 List<String> list4 = null;
125 List<? extends String> list5 = null;
126 List<? super String> list6 = null;
452 List<Object> list1;
453 List<?> list2;
454 List<? super Object> list3;
455 List<String> list4;
456 List<? extends String> list5;
457 List<? super String> list6;
127458 List[] list7 = null;
128 List<Object>[] list8 = null;
129 List<?>[] list9 = null;
130 List<? super Object>[] list10 = null;
131 List<String>[] list11 = null;
132 List<? extends String>[] list12 = null;
459 List<Object>[] list8;
460 List<?>[] list9;
461 List<? super Object>[] list10;
462 List<String>[] list11;
463 List<? extends String>[] list12;
133464 List<? super String>[] list13;
134465 final Class<?> clazz = getClass();
135466 final Method method = clazz.getMethod("dummyMethod", List.class, List.class, List.class,
370701 int in = 0;
371702 long lo = 0;
372703 final float fl = 0;
373 double du = 0;
704 double du;
374705 du = ch;
375706 assertTrue(TypeUtils.isAssignable(char.class, double.class));
376707 du = by;
451782 assertTrue(TypeUtils.isAssignable(fClassType, eClassType));
452783 }
453784
454 public void delegateBooleanAssertion(final Type[] types, final int i2, final int i1, final boolean expected) {
455 final Type type1 = types[i1];
456 final Type type2 = types[i2];
457 final boolean isAssignable = TypeUtils.isAssignable(type2, type1);
458
459 if (expected) {
460 assertTrue(isAssignable,
461 "[" + i1 + ", " + i2 + "]: From "
462 + String.valueOf(type2) + " to "
463 + String.valueOf(type1));
464 } else {
465 assertFalse(isAssignable,
466 "[" + i1 + ", " + i2 + "]: From "
467 + String.valueOf(type2) + " to "
468 + String.valueOf(type1));
469 }
785 private void testIsAssignable(final Class testUnassignableClass) {
786 final Class<Constructor> rawClass = Constructor.class;
787 final Class<Insets> typeArgClass = Insets.class;
788 // Builds a ParameterizedType for Constructor<Insets>
789 final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
790 assertEquals(rawClass, paramType.getRawType());
791 assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
792
793 assertFalse(testUnassignableClass.isAssignableFrom(paramType.getClass()));
794 assertFalse(paramType.getClass().isAssignableFrom(testUnassignableClass));
795
796 final GenericArrayType arrayType = TypeUtils.genericArrayType(paramType);
797 assertFalse(TypeUtils.isAssignable(arrayType, paramType),
798 () -> String.format("TypeUtils.isAssignable(%s, %s)", arrayType, paramType));
799 assertFalse(TypeUtils.isAssignable(paramType, arrayType),
800 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, arrayType));
801 }
802
803 @Test
804 public void testIsAssignableGenericArrayTypeToParameterizedType() {
805 final Class<Constructor> rawClass = Constructor.class;
806 final Class<Insets> typeArgClass = Insets.class;
807 // Builds a ParameterizedType for Constructor<Insets>
808 final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
809 assertEquals(rawClass, paramType.getRawType());
810 assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
811
812 assertFalse(GenericArrayType.class.isAssignableFrom(paramType.getClass()));
813 assertFalse(paramType.getClass().isAssignableFrom(GenericArrayType.class));
814
815 final GenericArrayType testType = TypeUtils.genericArrayType(paramType);
816 assertFalse(TypeUtils.isAssignable(paramType, testType),
817 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
818 assertFalse(TypeUtils.isAssignable(testType, paramType),
819 () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
820 }
821
822 @Test
823 @Disabled("TODO")
824 public void testIsAssignableGenericArrayTypeToWildercardType() {
825 final Class<Constructor> rawClass = Constructor.class;
826 final Class<Insets> typeArgClass = Insets.class;
827 // Builds a ParameterizedType for Constructor<Insets>
828 final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
829 assertEquals(rawClass, paramType.getRawType());
830 assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
831
832 assertFalse(WildcardType.class.isAssignableFrom(paramType.getClass()));
833 assertFalse(paramType.getClass().isAssignableFrom(WildcardType.class));
834
835 final WildcardType testType = TypeUtils.WILDCARD_ALL;
836 // TODO This test returns true unlike the test above.
837 // Is this a bug in this test or in the main code?
838 assertFalse(TypeUtils.isAssignable(paramType, testType),
839 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
840 assertFalse(TypeUtils.isAssignable(testType, paramType),
841 () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
842 }
843
844 @Test
845 public void testIsAssignableGenericArrayTypeToObject() {
846 final Class<Constructor> rawClass = Constructor.class;
847 final Class<Insets> typeArgClass = Insets.class;
848 // Builds a ParameterizedType for Constructor<Insets>
849 final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
850 assertEquals(rawClass, paramType.getRawType());
851 assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
852
853 assertTrue(Object.class.isAssignableFrom(paramType.getClass()));
854 assertFalse(paramType.getClass().isAssignableFrom(Object.class));
855
856 final Type testType = Object.class;
857 assertTrue(TypeUtils.isAssignable(paramType, testType),
858 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
859 assertFalse(TypeUtils.isAssignable(testType, paramType),
860 () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
470861 }
471862
472863 @SuppressWarnings("boxing") // boxing is deliberate here
481872 }
482873
483874 @Test
484 public void testGetTypeArguments() {
485 Map<TypeVariable<?>, Type> typeVarAssigns;
486 TypeVariable<?> treeSetTypeVar;
487 Type typeArg;
488
489 typeVarAssigns = TypeUtils.getTypeArguments(Integer.class, Comparable.class);
490 treeSetTypeVar = Comparable.class.getTypeParameters()[0];
491 assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
492 "Type var assigns for Comparable from Integer: " + typeVarAssigns);
493 typeArg = typeVarAssigns.get(treeSetTypeVar);
494 assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
495 "Type argument of Comparable from Integer: " + typeArg);
496
497 typeVarAssigns = TypeUtils.getTypeArguments(int.class, Comparable.class);
498 treeSetTypeVar = Comparable.class.getTypeParameters()[0];
499 assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
500 "Type var assigns for Comparable from int: " + typeVarAssigns);
501 typeArg = typeVarAssigns.get(treeSetTypeVar);
502 assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
503 "Type argument of Comparable from int: " + typeArg);
504
505 final Collection<Integer> col = Collections.emptyList();
506 typeVarAssigns = TypeUtils.getTypeArguments(List.class, Collection.class);
507 treeSetTypeVar = Comparable.class.getTypeParameters()[0];
508 assertFalse(typeVarAssigns.containsKey(treeSetTypeVar),
509 "Type var assigns for Collection from List: " + typeVarAssigns);
510
511 typeVarAssigns = TypeUtils.getTypeArguments(AAAClass.BBBClass.class, AAClass.BBClass.class);
512 assertEquals(2, typeVarAssigns.size());
513 assertEquals(String.class, typeVarAssigns.get(AAClass.class.getTypeParameters()[0]));
514 assertEquals(String.class, typeVarAssigns.get(AAClass.BBClass.class.getTypeParameters()[0]));
515
516 typeVarAssigns = TypeUtils.getTypeArguments(Other.class, This.class);
517 assertEquals(2, typeVarAssigns.size());
518 assertEquals(String.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
519 assertEquals(Other.class.getTypeParameters()[0], typeVarAssigns.get(This.class.getTypeParameters()[1]));
520
521 typeVarAssigns = TypeUtils.getTypeArguments(And.class, This.class);
522 assertEquals(2, typeVarAssigns.size());
523 assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
524 assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[1]));
525
526 typeVarAssigns = TypeUtils.getTypeArguments(Thing.class, Other.class);
527 assertEquals(2, typeVarAssigns.size());
528 assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(getClass().getTypeParameters()[0]));
529 assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(Other.class.getTypeParameters()[0]));
875 public void testLang1114() throws Exception {
876 final Type nonWildcardType = getClass().getDeclaredField("wildcardComparable").getGenericType();
877 final Type wildcardType = ((ParameterizedType) nonWildcardType).getActualTypeArguments()[0];
878
879 assertFalse(TypeUtils.equals(wildcardType, nonWildcardType));
880 assertFalse(TypeUtils.equals(nonWildcardType, wildcardType));
881 }
882
883 @Test
884 public void testLANG1190() throws Exception {
885 final Type fromType = ClassWithSuperClassWithGenericType.class.getDeclaredMethod("methodWithGenericReturnType").getGenericReturnType();
886 final Type failingToType = TypeUtils.wildcardType().withLowerBounds(ClassWithSuperClassWithGenericType.class).build();
887
888 assertTrue(TypeUtils.isAssignable(fromType, failingToType));
889 }
890
891 @Test
892 public void testLANG1348() throws Exception {
893 final Method method = Enum.class.getMethod("valueOf", Class.class, String.class);
894 assertEquals("T extends java.lang.Enum<T>", TypeUtils.toString(method.getGenericReturnType()));
895 }
896
897 @Test
898 public void testLang820() {
899 final Type[] typeArray = {String.class, String.class};
900 final Type[] expectedArray = {String.class};
901 assertArrayEquals(expectedArray, TypeUtils.normalizeUpperBounds(typeArray));
902 }
903
904 @Test
905 public void testLowerBoundedWildcardType() {
906 final WildcardType lowerBounded = TypeUtils.wildcardType().withLowerBounds(java.sql.Date.class).build();
907 assertEquals(String.format("? super %s", java.sql.Date.class.getName()), TypeUtils.toString(lowerBounded));
908 assertEquals(String.format("? super %s", java.sql.Date.class.getName()), lowerBounded.toString());
909
910 final TypeVariable<Class<Iterable>> iterableT0 = Iterable.class.getTypeParameters()[0];
911 final WildcardType lowerTypeVariable = TypeUtils.wildcardType().withLowerBounds(iterableT0).build();
912 assertEquals(String.format("? super %s", iterableT0.getName()), TypeUtils.toString(lowerTypeVariable));
913 assertEquals(String.format("? super %s", iterableT0.getName()), lowerTypeVariable.toString());
914 }
915
916 @Test
917 public void testParameterize() throws Exception {
918 final ParameterizedType stringComparableType = TypeUtils.parameterize(Comparable.class, String.class);
919 assertTrue(TypeUtils.equals(getClass().getField("stringComparable").getGenericType(),
920 stringComparableType));
921 assertEquals("java.lang.Comparable<java.lang.String>", stringComparableType.toString());
922 }
923
924 @Test
925 public void testParameterizeNarrowerTypeArray() {
926 final TypeVariable<?>[] variables = ArrayList.class.getTypeParameters();
927 final ParameterizedType parameterizedType = TypeUtils.parameterize(ArrayList.class, variables);
928 final Map<TypeVariable<?>, Type> mapping = Collections.<TypeVariable<?>, Type>singletonMap(variables[0], String.class);
929 final Type unrolled = TypeUtils.unrollVariables(mapping, parameterizedType);
930 assertEquals(TypeUtils.parameterize(ArrayList.class, String.class), unrolled);
931 }
932
933 @Test
934 public void testParameterizeWithOwner() throws Exception {
935 final Type owner = TypeUtils.parameterize(TypeUtilsTest.class, String.class);
936 final ParameterizedType dat2Type = TypeUtils.parameterizeWithOwner(owner, That.class, String.class, String.class);
937 assertTrue(TypeUtils.equals(getClass().getField("dat2").getGenericType(), dat2Type));
938 }
939
940 @Test
941 public void testToLongString() {
942 assertEquals(getClass().getName() + ":B", TypeUtils.toLongString(getClass().getTypeParameters()[0]));
943 }
944
945 @Test
946 public void testToStringLang1311() {
947 assertEquals("int[]", TypeUtils.toString(int[].class));
948 assertEquals("java.lang.Integer[]", TypeUtils.toString(Integer[].class));
949 final Field stringListField = FieldUtils.getDeclaredField(getClass(), "stringListArray");
950 assertEquals("java.util.List<java.lang.String>[]", TypeUtils.toString(stringListField.getGenericType()));
530951 }
531952
532953 @Test
545966 }
546967
547968 @Test
548 public void testDetermineTypeVariableAssignments() throws SecurityException,
549 NoSuchFieldException {
550 final ParameterizedType iterableType = (ParameterizedType) getClass().getField("iterable")
551 .getGenericType();
552 final Map<TypeVariable<?>, Type> typeVarAssigns = TypeUtils.determineTypeArguments(TreeSet.class,
553 iterableType);
554 final TypeVariable<?> treeSetTypeVar = TreeSet.class.getTypeParameters()[0];
555 assertTrue(typeVarAssigns.containsKey(treeSetTypeVar));
556 assertEquals(iterableType.getActualTypeArguments()[0], typeVarAssigns
557 .get(treeSetTypeVar));
558 }
559
560 @Test
561 public void testGetRawType() throws SecurityException, NoSuchFieldException {
562 final Type stringParentFieldType = GenericTypeHolder.class.getDeclaredField("stringParent")
563 .getGenericType();
564 final Type integerParentFieldType = GenericTypeHolder.class.getDeclaredField("integerParent")
565 .getGenericType();
566 final Type foosFieldType = GenericTypeHolder.class.getDeclaredField("foos").getGenericType();
567 final Type genericParentT = GenericParent.class.getTypeParameters()[0];
568 assertEquals(GenericParent.class, TypeUtils.getRawType(stringParentFieldType, null));
569 assertEquals(GenericParent.class, TypeUtils.getRawType(integerParentFieldType,
570 null));
571 assertEquals(List.class, TypeUtils.getRawType(foosFieldType, null));
572 assertEquals(String.class, TypeUtils.getRawType(genericParentT,
573 StringParameterizedChild.class));
574 assertEquals(String.class, TypeUtils.getRawType(genericParentT,
575 stringParentFieldType));
576 assertEquals(Foo.class, TypeUtils.getRawType(Iterable.class.getTypeParameters()[0],
577 foosFieldType));
578 assertEquals(Foo.class, TypeUtils.getRawType(List.class.getTypeParameters()[0],
579 foosFieldType));
580 assertNull(TypeUtils.getRawType(genericParentT, GenericParent.class));
581 assertEquals(GenericParent[].class, TypeUtils.getRawType(GenericTypeHolder.class
582 .getDeclaredField("barParents").getGenericType(), null));
583 }
584
585 @Test
586 public void testIsArrayTypeClasses() {
587 assertTrue(TypeUtils.isArrayType(boolean[].class));
588 assertTrue(TypeUtils.isArrayType(byte[].class));
589 assertTrue(TypeUtils.isArrayType(short[].class));
590 assertTrue(TypeUtils.isArrayType(int[].class));
591 assertTrue(TypeUtils.isArrayType(char[].class));
592 assertTrue(TypeUtils.isArrayType(long[].class));
593 assertTrue(TypeUtils.isArrayType(float[].class));
594 assertTrue(TypeUtils.isArrayType(double[].class));
595 assertTrue(TypeUtils.isArrayType(Object[].class));
596 assertTrue(TypeUtils.isArrayType(String[].class));
597
598 assertFalse(TypeUtils.isArrayType(boolean.class));
599 assertFalse(TypeUtils.isArrayType(byte.class));
600 assertFalse(TypeUtils.isArrayType(short.class));
601 assertFalse(TypeUtils.isArrayType(int.class));
602 assertFalse(TypeUtils.isArrayType(char.class));
603 assertFalse(TypeUtils.isArrayType(long.class));
604 assertFalse(TypeUtils.isArrayType(float.class));
605 assertFalse(TypeUtils.isArrayType(double.class));
606 assertFalse(TypeUtils.isArrayType(Object.class));
607 assertFalse(TypeUtils.isArrayType(String.class));
608 }
609
610 @Test
611 public void testIsArrayGenericTypes() throws Exception {
612 final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
613 List.class, List.class, List.class, List.class, List[].class, List[].class,
614 List[].class, List[].class, List[].class, List[].class, List[].class);
615
616 final Type[] types = method.getGenericParameterTypes();
617
618 assertFalse(TypeUtils.isArrayType(types[0]));
619 assertFalse(TypeUtils.isArrayType(types[1]));
620 assertFalse(TypeUtils.isArrayType(types[2]));
621 assertFalse(TypeUtils.isArrayType(types[3]));
622 assertFalse(TypeUtils.isArrayType(types[4]));
623 assertFalse(TypeUtils.isArrayType(types[5]));
624 assertFalse(TypeUtils.isArrayType(types[6]));
625 assertTrue(TypeUtils.isArrayType(types[7]));
626 assertTrue(TypeUtils.isArrayType(types[8]));
627 assertTrue(TypeUtils.isArrayType(types[9]));
628 assertTrue(TypeUtils.isArrayType(types[10]));
629 assertTrue(TypeUtils.isArrayType(types[11]));
630 assertTrue(TypeUtils.isArrayType(types[12]));
631 assertTrue(TypeUtils.isArrayType(types[13]));
632 }
633
634 @Test
635 public void testGetPrimitiveArrayComponentType() {
636 assertEquals(boolean.class, TypeUtils.getArrayComponentType(boolean[].class));
637 assertEquals(byte.class, TypeUtils.getArrayComponentType(byte[].class));
638 assertEquals(short.class, TypeUtils.getArrayComponentType(short[].class));
639 assertEquals(int.class, TypeUtils.getArrayComponentType(int[].class));
640 assertEquals(char.class, TypeUtils.getArrayComponentType(char[].class));
641 assertEquals(long.class, TypeUtils.getArrayComponentType(long[].class));
642 assertEquals(float.class, TypeUtils.getArrayComponentType(float[].class));
643 assertEquals(double.class, TypeUtils.getArrayComponentType(double[].class));
644
645 assertNull(TypeUtils.getArrayComponentType(boolean.class));
646 assertNull(TypeUtils.getArrayComponentType(byte.class));
647 assertNull(TypeUtils.getArrayComponentType(short.class));
648 assertNull(TypeUtils.getArrayComponentType(int.class));
649 assertNull(TypeUtils.getArrayComponentType(char.class));
650 assertNull(TypeUtils.getArrayComponentType(long.class));
651 assertNull(TypeUtils.getArrayComponentType(float.class));
652 assertNull(TypeUtils.getArrayComponentType(double.class));
653 }
654
655 @Test
656 public void testGetArrayComponentType() throws Exception {
657 final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
658 List.class, List.class, List.class, List.class, List[].class, List[].class,
659 List[].class, List[].class, List[].class, List[].class, List[].class);
660
661 final Type[] types = method.getGenericParameterTypes();
662
663 assertNull(TypeUtils.getArrayComponentType(types[0]));
664 assertNull(TypeUtils.getArrayComponentType(types[1]));
665 assertNull(TypeUtils.getArrayComponentType(types[2]));
666 assertNull(TypeUtils.getArrayComponentType(types[3]));
667 assertNull(TypeUtils.getArrayComponentType(types[4]));
668 assertNull(TypeUtils.getArrayComponentType(types[5]));
669 assertNull(TypeUtils.getArrayComponentType(types[6]));
670 assertEquals(types[0], TypeUtils.getArrayComponentType(types[7]));
671 assertEquals(types[1], TypeUtils.getArrayComponentType(types[8]));
672 assertEquals(types[2], TypeUtils.getArrayComponentType(types[9]));
673 assertEquals(types[3], TypeUtils.getArrayComponentType(types[10]));
674 assertEquals(types[4], TypeUtils.getArrayComponentType(types[11]));
675 assertEquals(types[5], TypeUtils.getArrayComponentType(types[12]));
676 assertEquals(types[6], TypeUtils.getArrayComponentType(types[13]));
677 }
678
679 @Test
680 public void testLang820() {
681 final Type[] typeArray = {String.class, String.class};
682 final Type[] expectedArray = {String.class};
683 assertArrayEquals(expectedArray, TypeUtils.normalizeUpperBounds(typeArray));
684 }
685
686 @Test
687 public void testParameterize() throws Exception {
688 final ParameterizedType stringComparableType = TypeUtils.parameterize(Comparable.class, String.class);
689 assertTrue(TypeUtils.equals(getClass().getField("stringComparable").getGenericType(),
690 stringComparableType));
691 assertEquals("java.lang.Comparable<java.lang.String>", stringComparableType.toString());
692 }
693
694 @Test
695 public void testParameterizeNarrowerTypeArray() {
696 final TypeVariable<?>[] variables = ArrayList.class.getTypeParameters();
697 final ParameterizedType parameterizedType = TypeUtils.parameterize(ArrayList.class, variables);
698 final Map<TypeVariable<?>, Type> mapping = Collections.<TypeVariable<?>, Type>singletonMap(variables[0], String.class);
699 final Type unrolled = TypeUtils.unrollVariables(mapping, parameterizedType);
700 assertEquals(TypeUtils.parameterize(ArrayList.class, String.class), unrolled);
701 }
702
703 @Test
704 public void testParameterizeWithOwner() throws Exception {
705 final Type owner = TypeUtils.parameterize(TypeUtilsTest.class, String.class);
706 final ParameterizedType dat2Type = TypeUtils.parameterizeWithOwner(owner, That.class, String.class, String.class);
707 assertTrue(TypeUtils.equals(getClass().getField("dat2").getGenericType(), dat2Type));
969 public void testUnboundedWildcardType() {
970 final WildcardType unbounded = TypeUtils.wildcardType().withLowerBounds((Type) null).withUpperBounds().build();
971 assertTrue(TypeUtils.equals(TypeUtils.WILDCARD_ALL, unbounded));
972 assertArrayEquals(new Type[] { Object.class }, TypeUtils.getImplicitUpperBounds(unbounded));
973 assertArrayEquals(new Type[] { null }, TypeUtils.getImplicitLowerBounds(unbounded));
974 assertEquals("?", TypeUtils.toString(unbounded));
975 assertEquals("?", unbounded.toString());
708976 }
709977
710978 @Test
718986 }
719987
720988 @Test
721 public void testUnboundedWildcardType() {
722 final WildcardType unbounded = TypeUtils.wildcardType().withLowerBounds((Type) null).withUpperBounds().build();
723 assertTrue(TypeUtils.equals(TypeUtils.WILDCARD_ALL, unbounded));
724 assertArrayEquals(new Type[] { Object.class }, TypeUtils.getImplicitUpperBounds(unbounded));
725 assertArrayEquals(new Type[] { null }, TypeUtils.getImplicitLowerBounds(unbounded));
726 assertEquals("?", TypeUtils.toString(unbounded));
727 assertEquals("?", unbounded.toString());
728 }
729
730 @Test
731 public void testLowerBoundedWildcardType() {
732 final WildcardType lowerBounded = TypeUtils.wildcardType().withLowerBounds(java.sql.Date.class).build();
733 assertEquals(String.format("? super %s", java.sql.Date.class.getName()), TypeUtils.toString(lowerBounded));
734 assertEquals(String.format("? super %s", java.sql.Date.class.getName()), lowerBounded.toString());
735
736 final TypeVariable<Class<Iterable>> iterableT0 = Iterable.class.getTypeParameters()[0];
737 final WildcardType lowerTypeVariable = TypeUtils.wildcardType().withLowerBounds(iterableT0).build();
738 assertEquals(String.format("? super %s", iterableT0.getName()), TypeUtils.toString(lowerTypeVariable));
739 assertEquals(String.format("? super %s", iterableT0.getName()), lowerTypeVariable.toString());
740 }
741
742 @Test
743 public void testLang1114() throws Exception {
744 final Type nonWildcardType = getClass().getDeclaredField("wildcardComparable").getGenericType();
745 final Type wildcardType = ((ParameterizedType) nonWildcardType).getActualTypeArguments()[0];
746
747 assertFalse(TypeUtils.equals(wildcardType, nonWildcardType));
748 assertFalse(TypeUtils.equals(nonWildcardType, wildcardType));
749 }
750
751 @Test
752 public void testGenericArrayType() throws Exception {
753 final Type expected = getClass().getField("intWildcardComparable").getGenericType();
754 final GenericArrayType actual =
755 TypeUtils.genericArrayType(TypeUtils.parameterize(Comparable.class, TypeUtils.wildcardType()
756 .withUpperBounds(Integer.class).build()));
757 assertTrue(TypeUtils.equals(expected, actual));
758 assertEquals("java.lang.Comparable<? extends java.lang.Integer>[]", actual.toString());
759 }
760
761 @Test
762 public void testToStringLang1311() {
763 assertEquals("int[]", TypeUtils.toString(int[].class));
764 assertEquals("java.lang.Integer[]", TypeUtils.toString(Integer[].class));
765 final Field stringListField = FieldUtils.getDeclaredField(getClass(), "stringListArray");
766 assertEquals("java.util.List<java.lang.String>[]", TypeUtils.toString(stringListField.getGenericType()));
767 }
768
769 @Test
770 public void testToLongString() {
771 assertEquals(getClass().getName() + ":B", TypeUtils.toLongString(getClass().getTypeParameters()[0]));
772 }
773
774 @Test
775989 public void testWrap() {
776990 final Type t = getClass().getTypeParameters()[0];
777991 assertTrue(TypeUtils.equals(t, TypeUtils.wrap(t).getType()));
778992
779993 assertEquals(String.class, TypeUtils.wrap(String.class).getType());
780994 }
781
782 public static class ClassWithSuperClassWithGenericType extends ArrayList<Object> {
783 private static final long serialVersionUID = 1L;
784
785 public static <U> Iterable<U> methodWithGenericReturnType() {
786 return null;
787 }
788 }
789
790 @Test
791 public void testLANG1190() throws Exception {
792 final Type fromType = ClassWithSuperClassWithGenericType.class.getDeclaredMethod("methodWithGenericReturnType").getGenericReturnType();
793 final Type failingToType = TypeUtils.wildcardType().withLowerBounds(ClassWithSuperClassWithGenericType.class).build();
794
795 assertTrue(TypeUtils.isAssignable(fromType, failingToType));
796 }
797
798 @Test
799 public void testLANG1348() throws Exception {
800 final Method method = Enum.class.getMethod("valueOf", Class.class, String.class);
801 assertEquals("T extends java.lang.Enum<T>", TypeUtils.toString(method.getGenericReturnType()));
802 }
803
804 public Iterable<? extends Map<Integer, ? extends Collection<?>>> iterable;
805
806 public static <G extends Comparable<G>> G stub() {
807 return null;
808 }
809
810 public static <G extends Comparable<? super G>> G stub2() {
811 return null;
812 }
813
814 public static <T extends Comparable<? extends T>> T stub3() {
815 return null;
816 }
817995 }
818
819 class AAClass<T> {
820
821 public class BBClass<S> {
822 }
823 }
824
825 class AAAClass extends AAClass<String> {
826 public class BBBClass extends BBClass<String> {
827 }
828 }
829
830 @SuppressWarnings("rawtypes")
831 //raw types, where used, are used purposely
832 class AClass extends AAClass<String>.BBClass<Number> {
833
834 AClass(final AAClass<String> enclosingInstance) {
835 enclosingInstance.super();
836 }
837
838 public class BClass<T> {
839 }
840
841 public class CClass<T> extends BClass {
842 }
843
844 public class DClass<T> extends CClass<T> {
845 }
846
847 public class EClass<T> extends DClass {
848 }
849
850 public class FClass extends EClass<String> {
851 }
852
853 public class GClass<T extends BClass<? extends T> & AInterface<AInterface<? super T>>> {
854 }
855
856 public BClass<Number> bClass;
857
858 public CClass<? extends String> cClass;
859
860 public DClass<String> dClass;
861
862 public EClass<String> eClass;
863
864 public FClass fClass;
865
866 public GClass gClass;
867
868 public interface AInterface<T> {
869 }
870 }
5454
5555 protected <T extends Throwable> FailablePredicate<Integer, T> asIntPredicate(final T pThrowable) {
5656 return i -> {
57 if (i.intValue() == 5) {
58 if (pThrowable != null) {
59 throw pThrowable;
60 }
57 if (i.intValue() == 5 && pThrowable != null) {
58 throw pThrowable;
6159 }
6260 return i % 2 == 0;
6361 };
206206 @Test
207207 public void testBuiltInChoiceFormat() {
208208 final Object[] values = new Number[] {Integer.valueOf(1), Double.valueOf("2.2"), Double.valueOf("1234.5")};
209 String choicePattern = null;
209 String choicePattern;
210210 final Locale[] availableLocales = NumberFormat.getAvailableLocales();
211211
212212 choicePattern = "{0,choice,1#One|2#Two|3#Many {0,number}}";
295295 final String pattern = "Pattern: {0,testfmt}";
296296 final ExtendedMessageFormat emf = new ExtendedMessageFormat(pattern, Locale.US, fmtRegistry);
297297
298 ExtendedMessageFormat other = null;
298 ExtendedMessageFormat other;
299299
300300 // Same object
301301 assertEquals(emf, emf, "same, equals()");
5555 String expected = "Test \u0030 not test";
5656
5757 String result = neu.translate(input);
58 assertEquals(expected, result, "Failed to support unfinished entities (i.e. missing semi-colon)");
58 assertEquals(expected, result, "Failed to support unfinished entities (i.e. missing semicolon)");
5959
6060 // ignore it
6161 neu = new NumericEntityUnescaper();
6363 expected = input;
6464
6565 result = neu.translate(input);
66 assertEquals(expected, result, "Failed to ignore unfinished entities (i.e. missing semi-colon)");
66 assertEquals(expected, result, "Failed to ignore unfinished entities (i.e. missing semicolon)");
6767
6868 // fail it
6969 final NumericEntityUnescaper failingNeu =
2525 public class CalendarUtilsTest {
2626
2727 @Test
28 public void testGetYear() {
29 assertEquals(Calendar.getInstance().get(Calendar.YEAR), CalendarUtils.INSTANCE.getYear());
28 public void testGetDayOfMonth() {
29 assertEquals(Calendar.getInstance().get(Calendar.DAY_OF_MONTH), CalendarUtils.INSTANCE.getDayOfMonth());
3030 }
3131
3232 @Test
3535 }
3636
3737 @Test
38 public void testGetDayOfMonth() {
39 assertEquals(Calendar.getInstance().get(Calendar.DAY_OF_MONTH), CalendarUtils.INSTANCE.getDayOfMonth());
38 public void testGetYear() {
39 assertEquals(Calendar.getInstance().get(Calendar.YEAR), CalendarUtils.INSTANCE.getYear());
4040 }
4141
4242 }
3737 */
3838 @SuppressWarnings("deprecation") // tests lots of deprecated items
3939 public class DateFormatUtilsTest {
40 private void assertFormats(final String expectedValue, final String pattern, final TimeZone timeZone, final Calendar cal) {
41 assertEquals(expectedValue, DateFormatUtils.format(cal.getTime(), pattern, timeZone));
42 assertEquals(expectedValue, DateFormatUtils.format(cal.getTime().getTime(), pattern, timeZone));
43 assertEquals(expectedValue, DateFormatUtils.format(cal, pattern, timeZone));
44 }
45
46 private Calendar createFebruaryTestDate(final TimeZone timeZone) {
47 final Calendar cal = Calendar.getInstance(timeZone);
48 cal.set(2002, Calendar.FEBRUARY, 23, 9, 11, 12);
49 return cal;
50 }
51
52 private Calendar createJuneTestDate(final TimeZone timeZone) {
53 final Calendar cal = Calendar.getInstance(timeZone);
54 cal.set(2003, Calendar.JUNE, 8, 10, 11, 12);
55 return cal;
56 }
57
4058 //-----------------------------------------------------------------------
4159 @Test
4260 public void testConstructor() {
4664 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
4765 assertTrue(Modifier.isPublic(DateFormatUtils.class.getModifiers()));
4866 assertFalse(Modifier.isFinal(DateFormatUtils.class.getModifiers()));
67 }
68
69 @Test
70 public void testDateISO() {
71 testGmtMinus3("2002-02-23", DateFormatUtils.ISO_DATE_FORMAT.getPattern());
72 testGmtMinus3("2002-02-23-03:00", DateFormatUtils.ISO_DATE_TIME_ZONE_FORMAT.getPattern());
73 testUTC("2002-02-23Z", DateFormatUtils.ISO_DATE_TIME_ZONE_FORMAT.getPattern());
74 }
75
76 @Test
77 public void testDateTimeISO() {
78 testGmtMinus3("2002-02-23T09:11:12", DateFormatUtils.ISO_DATETIME_FORMAT.getPattern());
79 testGmtMinus3("2002-02-23T09:11:12-03:00", DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern());
80 testUTC("2002-02-23T09:11:12Z", DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern());
4981 }
5082
5183 //-----------------------------------------------------------------------
109141 assertEquals ("2005-01-01T12:00:00", DateFormatUtils.formatUTC(c.getTime().getTime(), DateFormatUtils.ISO_DATETIME_FORMAT.getPattern(), Locale.US));
110142 }
111143
112 private void assertFormats(final String expectedValue, final String pattern, final TimeZone timeZone, final Calendar cal) {
113 assertEquals(expectedValue, DateFormatUtils.format(cal.getTime(), pattern, timeZone));
114 assertEquals(expectedValue, DateFormatUtils.format(cal.getTime().getTime(), pattern, timeZone));
115 assertEquals(expectedValue, DateFormatUtils.format(cal, pattern, timeZone));
116 }
117
118 private Calendar createFebruaryTestDate(final TimeZone timeZone) {
119 final Calendar cal = Calendar.getInstance(timeZone);
120 cal.set(2002, Calendar.FEBRUARY, 23, 9, 11, 12);
121 return cal;
122 }
123
124 private Calendar createJuneTestDate(final TimeZone timeZone) {
125 final Calendar cal = Calendar.getInstance(timeZone);
126 cal.set(2003, Calendar.JUNE, 8, 10, 11, 12);
127 return cal;
128 }
129
130144 private void testGmtMinus3(final String expectedValue, final String pattern) {
131145 final TimeZone timeZone = TimeZone.getTimeZone("GMT-3");
132146 assertFormats(expectedValue, pattern, timeZone, createFebruaryTestDate(timeZone));
133 }
134
135 private void testUTC(final String expectedValue, final String pattern) {
136 final TimeZone timeZone = FastTimeZone.getGmtTimeZone();
137 assertFormats(expectedValue, pattern, timeZone, createFebruaryTestDate(timeZone));
138 }
139
140 @Test
141 public void testDateTimeISO() {
142 testGmtMinus3("2002-02-23T09:11:12", DateFormatUtils.ISO_DATETIME_FORMAT.getPattern());
143 testGmtMinus3("2002-02-23T09:11:12-03:00", DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern());
144 testUTC("2002-02-23T09:11:12Z", DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern());
145 }
146
147 @Test
148 public void testDateISO() {
149 testGmtMinus3("2002-02-23", DateFormatUtils.ISO_DATE_FORMAT.getPattern());
150 testGmtMinus3("2002-02-23-03:00", DateFormatUtils.ISO_DATE_TIME_ZONE_FORMAT.getPattern());
151 testUTC("2002-02-23Z", DateFormatUtils.ISO_DATE_TIME_ZONE_FORMAT.getPattern());
152 }
153
154 @Test
155 public void testTimeISO() {
156 testGmtMinus3("T09:11:12", DateFormatUtils.ISO_TIME_FORMAT.getPattern());
157 testGmtMinus3("T09:11:12-03:00", DateFormatUtils.ISO_TIME_TIME_ZONE_FORMAT.getPattern());
158 testUTC("T09:11:12Z", DateFormatUtils.ISO_TIME_TIME_ZONE_FORMAT.getPattern());
159 }
160
161 @Test
162 public void testTimeNoTISO() {
163 testGmtMinus3("09:11:12", DateFormatUtils.ISO_TIME_NO_T_FORMAT.getPattern());
164 testGmtMinus3("09:11:12-03:00", DateFormatUtils.ISO_TIME_NO_T_TIME_ZONE_FORMAT.getPattern());
165 testUTC("09:11:12Z", DateFormatUtils.ISO_TIME_NO_T_TIME_ZONE_FORMAT.getPattern());
166 }
167
168 @DefaultLocale(language = "en")
169 @Test
170 public void testSMTP() {
171 TimeZone timeZone = TimeZone.getTimeZone("GMT-3");
172 Calendar june = createJuneTestDate(timeZone);
173
174 assertFormats("Sun, 08 Jun 2003 10:11:12 -0300", DateFormatUtils.SMTP_DATETIME_FORMAT.getPattern(),
175 timeZone, june);
176
177 timeZone = FastTimeZone.getGmtTimeZone();
178 june = createJuneTestDate(timeZone);
179 assertFormats("Sun, 08 Jun 2003 10:11:12 +0000", DateFormatUtils.SMTP_DATETIME_FORMAT.getPattern(),
180 timeZone, june);
181147 }
182148
183149 @Test
237203 assertEquals("2009-10-16T07:42:16+01:00", value, "calendar");
238204 }
239205 }
206
207 @DefaultLocale(language = "en")
208 @Test
209 public void testSMTP() {
210 TimeZone timeZone = TimeZone.getTimeZone("GMT-3");
211 Calendar june = createJuneTestDate(timeZone);
212
213 assertFormats("Sun, 08 Jun 2003 10:11:12 -0300", DateFormatUtils.SMTP_DATETIME_FORMAT.getPattern(),
214 timeZone, june);
215
216 timeZone = FastTimeZone.getGmtTimeZone();
217 june = createJuneTestDate(timeZone);
218 assertFormats("Sun, 08 Jun 2003 10:11:12 +0000", DateFormatUtils.SMTP_DATETIME_FORMAT.getPattern(),
219 timeZone, june);
220 }
221
222 @Test
223 public void testTimeISO() {
224 testGmtMinus3("T09:11:12", DateFormatUtils.ISO_TIME_FORMAT.getPattern());
225 testGmtMinus3("T09:11:12-03:00", DateFormatUtils.ISO_TIME_TIME_ZONE_FORMAT.getPattern());
226 testUTC("T09:11:12Z", DateFormatUtils.ISO_TIME_TIME_ZONE_FORMAT.getPattern());
227 }
228
229 @Test
230 public void testTimeNoTISO() {
231 testGmtMinus3("09:11:12", DateFormatUtils.ISO_TIME_NO_T_FORMAT.getPattern());
232 testGmtMinus3("09:11:12-03:00", DateFormatUtils.ISO_TIME_NO_T_TIME_ZONE_FORMAT.getPattern());
233 testUTC("09:11:12Z", DateFormatUtils.ISO_TIME_NO_T_TIME_ZONE_FORMAT.getPattern());
234 }
235
236 private void testUTC(final String expectedValue, final String pattern) {
237 final TimeZone timeZone = FastTimeZone.getGmtTimeZone();
238 assertFormats(expectedValue, pattern, timeZone, createFebruaryTestDate(timeZone));
239 }
240240 }
4646 }
4747
4848 @Test
49 public void testNullDate() {
50 assertThrows(
51 NullPointerException.class,
52 () -> DateUtils.getFragmentInMilliseconds((Date) null, Calendar.MILLISECOND));
53
54 assertThrows(
55 NullPointerException.class,
56 () -> DateUtils.getFragmentInSeconds((Date) null, Calendar.MILLISECOND));
57
58 assertThrows(
59 NullPointerException.class,
60 () -> DateUtils.getFragmentInMinutes((Date) null, Calendar.MILLISECOND));
61
62 assertThrows(
63 NullPointerException.class,
64 () -> DateUtils.getFragmentInHours((Date) null, Calendar.MILLISECOND));
65
66 assertThrows(
67 NullPointerException.class,
68 () -> DateUtils.getFragmentInDays((Date) null, Calendar.MILLISECOND));
69 }
70
71 @Test
72 public void testNullCalendar() {
73 assertThrows(
74 IllegalArgumentException.class,
75 () -> DateUtils.getFragmentInMilliseconds((Calendar) null, Calendar.MILLISECOND));
76
77 assertThrows(
78 IllegalArgumentException.class,
79 () -> DateUtils.getFragmentInSeconds((Calendar) null, Calendar.MILLISECOND));
80
81 assertThrows(
82 IllegalArgumentException.class,
83 () -> DateUtils.getFragmentInMinutes((Calendar) null, Calendar.MILLISECOND));
84
85 assertThrows(
86 IllegalArgumentException.class,
87 () -> DateUtils.getFragmentInHours((Calendar) null, Calendar.MILLISECOND));
88
89 assertThrows(
90 IllegalArgumentException.class,
91 () -> DateUtils.getFragmentInDays((Calendar) null, Calendar.MILLISECOND));
49 public void testDateFragmentInLargerUnitWithCalendar() {
50 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.DATE));
51 }
52
53 @Test
54 public void testDateFragmentInLargerUnitWithDate() {
55 assertEquals(0, DateUtils.getFragmentInDays(aDate, Calendar.DATE));
56 }
57
58 @Test
59 public void testDayOfYearFragmentInLargerUnitWithCalendar() {
60 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.DAY_OF_YEAR));
61 }
62
63 @Test
64 public void testDayOfYearFragmentInLargerUnitWithDate() {
65 assertEquals(0, DateUtils.getFragmentInDays(aDate, Calendar.DAY_OF_YEAR));
66 }
67
68 @Test
69 public void testDaysOfMonthWithCalendar() {
70 final long testResult = DateUtils.getFragmentInDays(aCalendar, Calendar.MONTH);
71 assertEquals(days, testResult);
72 }
73
74 @Test
75 public void testDaysOfMonthWithDate() {
76 final long testResult = DateUtils.getFragmentInDays(aDate, Calendar.MONTH);
77 final Calendar cal = Calendar.getInstance();
78 cal.setTime(aDate);
79 assertEquals(cal.get(Calendar.DAY_OF_MONTH), testResult);
80 }
81
82 @Test
83 public void testDaysOfYearWithCalendar() {
84 final long testResult = DateUtils.getFragmentInDays(aCalendar, Calendar.YEAR);
85 assertEquals(aCalendar.get(Calendar.DAY_OF_YEAR), testResult);
86 }
87
88 @Test
89 public void testDaysOfYearWithDate() {
90 final long testResult = DateUtils.getFragmentInDays(aDate, Calendar.YEAR);
91 final Calendar cal = Calendar.getInstance();
92 cal.setTime(aDate);
93 assertEquals(cal.get(Calendar.DAY_OF_YEAR), testResult);
94 }
95
96 @Test
97 public void testHourOfDayFragmentInLargerUnitWithCalendar() {
98 assertEquals(0, DateUtils.getFragmentInHours(aCalendar, Calendar.HOUR_OF_DAY));
99 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.HOUR_OF_DAY));
100 }
101
102 @Test
103 public void testHourOfDayFragmentInLargerUnitWithDate() {
104 assertEquals(0, DateUtils.getFragmentInHours(aDate, Calendar.HOUR_OF_DAY));
105 assertEquals(0, DateUtils.getFragmentInDays(aDate, Calendar.HOUR_OF_DAY));
106 }
107
108 @Test
109 public void testHoursOfDayWithCalendar() {
110 long testResult = DateUtils.getFragmentInHours(aCalendar, Calendar.DATE);
111 final long expectedValue = hours;
112 assertEquals(expectedValue, testResult);
113 testResult = DateUtils.getFragmentInHours(aCalendar, Calendar.DAY_OF_YEAR);
114 assertEquals(expectedValue, testResult);
115 }
116
117 @Test
118 public void testHoursOfDayWithDate() {
119 long testResult = DateUtils.getFragmentInHours(aDate, Calendar.DATE);
120 final long expectedValue = hours;
121 assertEquals(expectedValue, testResult);
122 testResult = DateUtils.getFragmentInHours(aDate, Calendar.DAY_OF_YEAR);
123 assertEquals(expectedValue, testResult);
124 }
125
126 @Test
127 public void testHoursOfMonthWithCalendar() {
128 final long testResult = DateUtils.getFragmentInHours(aCalendar, Calendar.MONTH);
129 assertEquals( hours +(((days - 1) * DateUtils.MILLIS_PER_DAY))
130 / DateUtils.MILLIS_PER_HOUR,
131 testResult);
132 }
133
134 @Test
135 public void testHoursOfMonthWithDate() {
136 final long testResult = DateUtils.getFragmentInHours(aDate, Calendar.MONTH);
137 assertEquals(hours + (((days - 1) * DateUtils.MILLIS_PER_DAY))
138 / DateUtils.MILLIS_PER_HOUR,
139 testResult);
140 }
141
142 @Test
143 public void testHoursOfYearWithCalendar() {
144 final long testResult = DateUtils.getFragmentInHours(aCalendar, Calendar.YEAR);
145 assertEquals( hours +(((aCalendar.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY))
146 / DateUtils.MILLIS_PER_HOUR,
147 testResult);
148 }
149
150 @Test
151 public void testHoursOfYearWithDate() {
152 final long testResult = DateUtils.getFragmentInHours(aDate, Calendar.YEAR);
153 final Calendar cal = Calendar.getInstance();
154 cal.setTime(aDate);
155 assertEquals(hours + (((cal.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY))
156 / DateUtils.MILLIS_PER_HOUR,
157 testResult);
158 }
159
160 //Calendar.SECOND as useful fragment
161
162 @Test
163 public void testInvalidFragmentWithCalendar() {
164 assertThrows(IllegalArgumentException.class, () -> DateUtils.getFragmentInMilliseconds(aCalendar, 0));
165 assertThrows(IllegalArgumentException.class, () -> DateUtils.getFragmentInSeconds(aCalendar, 0));
166 assertThrows(IllegalArgumentException.class, () -> DateUtils.getFragmentInMinutes(aCalendar, 0));
167 assertThrows(IllegalArgumentException.class, () -> DateUtils.getFragmentInHours(aCalendar, 0));
168 assertThrows(IllegalArgumentException.class, () -> DateUtils.getFragmentInDays(aCalendar, 0));
92169 }
93170
94171 @Test
100177 assertThrows(IllegalArgumentException.class, () -> DateUtils.getFragmentInDays(aDate, 0));
101178 }
102179
103 @Test
104 public void testInvalidFragmentWithCalendar() {
105 assertThrows(IllegalArgumentException.class, () -> DateUtils.getFragmentInMilliseconds(aCalendar, 0));
106 assertThrows(IllegalArgumentException.class, () -> DateUtils.getFragmentInSeconds(aCalendar, 0));
107 assertThrows(IllegalArgumentException.class, () -> DateUtils.getFragmentInMinutes(aCalendar, 0));
108 assertThrows(IllegalArgumentException.class, () -> DateUtils.getFragmentInHours(aCalendar, 0));
109 assertThrows(IllegalArgumentException.class, () -> DateUtils.getFragmentInDays(aCalendar, 0));
180 //Calendar.MINUTE as useful fragment
181
182 @Test
183 public void testMillisecondFragmentInLargerUnitWithCalendar() {
184 assertEquals(0, DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.MILLISECOND));
185 assertEquals(0, DateUtils.getFragmentInSeconds(aCalendar, Calendar.MILLISECOND));
186 assertEquals(0, DateUtils.getFragmentInMinutes(aCalendar, Calendar.MILLISECOND));
187 assertEquals(0, DateUtils.getFragmentInHours(aCalendar, Calendar.MILLISECOND));
188 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.MILLISECOND));
110189 }
111190
112191 @Test
119198 }
120199
121200 @Test
122 public void testMillisecondFragmentInLargerUnitWithCalendar() {
123 assertEquals(0, DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.MILLISECOND));
124 assertEquals(0, DateUtils.getFragmentInSeconds(aCalendar, Calendar.MILLISECOND));
125 assertEquals(0, DateUtils.getFragmentInMinutes(aCalendar, Calendar.MILLISECOND));
126 assertEquals(0, DateUtils.getFragmentInHours(aCalendar, Calendar.MILLISECOND));
127 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.MILLISECOND));
128 }
129
130 @Test
131 public void testSecondFragmentInLargerUnitWithDate() {
132 assertEquals(0, DateUtils.getFragmentInSeconds(aDate, Calendar.SECOND));
133 assertEquals(0, DateUtils.getFragmentInMinutes(aDate, Calendar.SECOND));
134 assertEquals(0, DateUtils.getFragmentInHours(aDate, Calendar.SECOND));
135 assertEquals(0, DateUtils.getFragmentInDays(aDate, Calendar.SECOND));
136 }
137
138 @Test
139 public void testSecondFragmentInLargerUnitWithCalendar() {
140 assertEquals(0, DateUtils.getFragmentInSeconds(aCalendar, Calendar.SECOND));
141 assertEquals(0, DateUtils.getFragmentInMinutes(aCalendar, Calendar.SECOND));
142 assertEquals(0, DateUtils.getFragmentInHours(aCalendar, Calendar.SECOND));
143 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.SECOND));
144 }
145
146 @Test
147 public void testMinuteFragmentInLargerUnitWithDate() {
148 assertEquals(0, DateUtils.getFragmentInMinutes(aDate, Calendar.MINUTE));
149 assertEquals(0, DateUtils.getFragmentInHours(aDate, Calendar.MINUTE));
150 assertEquals(0, DateUtils.getFragmentInDays(aDate, Calendar.MINUTE));
151 }
152
153 @Test
154 public void testMinuteFragmentInLargerUnitWithCalendar() {
155 assertEquals(0, DateUtils.getFragmentInMinutes(aCalendar, Calendar.MINUTE));
156 assertEquals(0, DateUtils.getFragmentInHours(aCalendar, Calendar.MINUTE));
157 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.MINUTE));
158 }
159
160 @Test
161 public void testHourOfDayFragmentInLargerUnitWithDate() {
162 assertEquals(0, DateUtils.getFragmentInHours(aDate, Calendar.HOUR_OF_DAY));
163 assertEquals(0, DateUtils.getFragmentInDays(aDate, Calendar.HOUR_OF_DAY));
164 }
165
166 @Test
167 public void testHourOfDayFragmentInLargerUnitWithCalendar() {
168 assertEquals(0, DateUtils.getFragmentInHours(aCalendar, Calendar.HOUR_OF_DAY));
169 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.HOUR_OF_DAY));
170 }
171
172 @Test
173 public void testDayOfYearFragmentInLargerUnitWithDate() {
174 assertEquals(0, DateUtils.getFragmentInDays(aDate, Calendar.DAY_OF_YEAR));
175 }
176
177 @Test
178 public void testDayOfYearFragmentInLargerUnitWithCalendar() {
179 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.DAY_OF_YEAR));
180 }
181
182 @Test
183 public void testDateFragmentInLargerUnitWithDate() {
184 assertEquals(0, DateUtils.getFragmentInDays(aDate, Calendar.DATE));
185 }
186
187 @Test
188 public void testDateFragmentInLargerUnitWithCalendar() {
189 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.DATE));
190 }
191
192 //Calendar.SECOND as useful fragment
193
194 @Test
195 public void testMillisecondsOfSecondWithDate() {
196 final long testResult = DateUtils.getFragmentInMilliseconds(aDate, Calendar.SECOND);
197 assertEquals(millis, testResult);
198 }
199
200 @Test
201 public void testMillisecondsOfSecondWithCalendar() {
202 final long testResult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.SECOND);
203 assertEquals(millis, testResult);
204 assertEquals(aCalendar.get(Calendar.MILLISECOND), testResult);
205 }
206
207 //Calendar.MINUTE as useful fragment
201 public void testMillisecondsOfDayWithCalendar() {
202 long testresult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.DATE);
203 final long expectedValue = millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE) + (hours * DateUtils.MILLIS_PER_HOUR);
204 assertEquals(expectedValue, testresult);
205 testresult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.DAY_OF_YEAR);
206 assertEquals(expectedValue, testresult);
207 }
208
209 //Calendar.DATE and Calendar.DAY_OF_YEAR as useful fragment
210 @Test
211 public void testMillisecondsOfDayWithDate() {
212 long testresult = DateUtils.getFragmentInMilliseconds(aDate, Calendar.DATE);
213 final long expectedValue = millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE) + (hours * DateUtils.MILLIS_PER_HOUR);
214 assertEquals(expectedValue, testresult);
215 testresult = DateUtils.getFragmentInMilliseconds(aDate, Calendar.DAY_OF_YEAR);
216 assertEquals(expectedValue, testresult);
217 }
218
219 //Calendar.HOUR_OF_DAY as useful fragment
220
221 @Test
222 public void testMillisecondsOfHourWithCalendar() {
223 final long testResult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.HOUR_OF_DAY);
224 assertEquals(millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE), testResult);
225 }
226
227 @Test
228 public void testMillisecondsOfHourWithDate() {
229 final long testResult = DateUtils.getFragmentInMilliseconds(aDate, Calendar.HOUR_OF_DAY);
230 assertEquals(millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE), testResult);
231 }
232
233 @Test
234 public void testMillisecondsOfMinuteWithCalender() {
235 final long testResult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.MINUTE);
236 assertEquals(millis + (seconds * DateUtils.MILLIS_PER_SECOND), testResult);
237 }
208238
209239 @Test
210240 public void testMillisecondsOfMinuteWithDate() {
211241 final long testResult = DateUtils.getFragmentInMilliseconds(aDate, Calendar.MINUTE);
212242 assertEquals(millis + (seconds * DateUtils.MILLIS_PER_SECOND), testResult);
213 }
214
215 @Test
216 public void testMillisecondsOfMinuteWithCalender() {
217 final long testResult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.MINUTE);
218 assertEquals(millis + (seconds * DateUtils.MILLIS_PER_SECOND), testResult);
219 }
220
221 @Test
222 public void testSecondsofMinuteWithDate() {
223 final long testResult = DateUtils.getFragmentInSeconds(aDate, Calendar.MINUTE);
224 assertEquals(seconds, testResult);
225 }
226
227 @Test
228 public void testSecondsofMinuteWithCalendar() {
229 final long testResult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.MINUTE);
230 assertEquals(seconds, testResult);
231 assertEquals(aCalendar.get(Calendar.SECOND), testResult);
232 }
233
234 //Calendar.HOUR_OF_DAY as useful fragment
235
236 @Test
237 public void testMillisecondsOfHourWithDate() {
238 final long testResult = DateUtils.getFragmentInMilliseconds(aDate, Calendar.HOUR_OF_DAY);
239 assertEquals(millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE), testResult);
240 }
241
242 @Test
243 public void testMillisecondsOfHourWithCalendar() {
244 final long testResult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.HOUR_OF_DAY);
245 assertEquals(millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE), testResult);
246 }
247
248 @Test
249 public void testSecondsofHourWithDate() {
250 final long testResult = DateUtils.getFragmentInSeconds(aDate, Calendar.HOUR_OF_DAY);
251 assertEquals(
252 seconds
253 + (minutes
254 * DateUtils.MILLIS_PER_MINUTE / DateUtils.MILLIS_PER_SECOND),
255 testResult);
256 }
257
258 @Test
259 public void testSecondsofHourWithCalendar() {
260 final long testResult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.HOUR_OF_DAY);
261 assertEquals(
262 seconds
263 + (minutes
264 * DateUtils.MILLIS_PER_MINUTE / DateUtils.MILLIS_PER_SECOND),
265 testResult);
266 }
267
268 @Test
269 public void testMinutesOfHourWithDate() {
270 final long testResult = DateUtils.getFragmentInMinutes(aDate, Calendar.HOUR_OF_DAY);
271 assertEquals(minutes, testResult);
272 }
273
274 @Test
275 public void testMinutesOfHourWithCalendar() {
276 final long testResult = DateUtils.getFragmentInMinutes(aCalendar, Calendar.HOUR_OF_DAY);
277 assertEquals(minutes, testResult);
278 }
279
280 //Calendar.DATE and Calendar.DAY_OF_YEAR as useful fragment
281 @Test
282 public void testMillisecondsOfDayWithDate() {
283 long testresult = DateUtils.getFragmentInMilliseconds(aDate, Calendar.DATE);
284 final long expectedValue = millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE) + (hours * DateUtils.MILLIS_PER_HOUR);
285 assertEquals(expectedValue, testresult);
286 testresult = DateUtils.getFragmentInMilliseconds(aDate, Calendar.DAY_OF_YEAR);
287 assertEquals(expectedValue, testresult);
288 }
289
290 @Test
291 public void testMillisecondsOfDayWithCalendar() {
292 long testresult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.DATE);
293 final long expectedValue = millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE) + (hours * DateUtils.MILLIS_PER_HOUR);
294 assertEquals(expectedValue, testresult);
295 testresult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.DAY_OF_YEAR);
296 assertEquals(expectedValue, testresult);
297 }
298
299 @Test
300 public void testSecondsOfDayWithDate() {
301 long testresult = DateUtils.getFragmentInSeconds(aDate, Calendar.DATE);
302 final long expectedValue = seconds + ((minutes * DateUtils.MILLIS_PER_MINUTE) + (hours * DateUtils.MILLIS_PER_HOUR))/ DateUtils.MILLIS_PER_SECOND;
303 assertEquals(expectedValue, testresult);
304 testresult = DateUtils.getFragmentInSeconds(aDate, Calendar.DAY_OF_YEAR);
305 assertEquals(expectedValue, testresult);
306 }
307
308 @Test
309 public void testSecondsOfDayWithCalendar() {
310 long testresult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.DATE);
311 final long expectedValue = seconds + ((minutes * DateUtils.MILLIS_PER_MINUTE) + (hours * DateUtils.MILLIS_PER_HOUR))/ DateUtils.MILLIS_PER_SECOND;
312 assertEquals(expectedValue, testresult);
313 testresult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.DAY_OF_YEAR);
314 assertEquals(expectedValue, testresult);
315 }
316
317 @Test
318 public void testMinutesOfDayWithDate() {
319 long testResult = DateUtils.getFragmentInMinutes(aDate, Calendar.DATE);
320 final long expectedValue = minutes + ((hours * DateUtils.MILLIS_PER_HOUR))/ DateUtils.MILLIS_PER_MINUTE;
321 assertEquals(expectedValue, testResult);
322 testResult = DateUtils.getFragmentInMinutes(aDate, Calendar.DAY_OF_YEAR);
323 assertEquals(expectedValue, testResult);
324 }
325
326 @Test
327 public void testMinutesOfDayWithCalendar() {
328 long testResult = DateUtils.getFragmentInMinutes(aCalendar, Calendar.DATE);
329 final long expectedValue = minutes + ((hours * DateUtils.MILLIS_PER_HOUR))/ DateUtils.MILLIS_PER_MINUTE;
330 assertEquals(expectedValue, testResult);
331 testResult = DateUtils.getFragmentInMinutes(aCalendar, Calendar.DAY_OF_YEAR);
332 assertEquals(expectedValue, testResult);
333 }
334
335 @Test
336 public void testHoursOfDayWithDate() {
337 long testResult = DateUtils.getFragmentInHours(aDate, Calendar.DATE);
338 final long expectedValue = hours;
339 assertEquals(expectedValue, testResult);
340 testResult = DateUtils.getFragmentInHours(aDate, Calendar.DAY_OF_YEAR);
341 assertEquals(expectedValue, testResult);
342 }
343
344 @Test
345 public void testHoursOfDayWithCalendar() {
346 long testResult = DateUtils.getFragmentInHours(aCalendar, Calendar.DATE);
347 final long expectedValue = hours;
348 assertEquals(expectedValue, testResult);
349 testResult = DateUtils.getFragmentInHours(aCalendar, Calendar.DAY_OF_YEAR);
350 assertEquals(expectedValue, testResult);
351 }
352
353
354 //Calendar.MONTH as useful fragment
355 @Test
356 public void testMillisecondsOfMonthWithDate() {
357 final long testResult = DateUtils.getFragmentInMilliseconds(aDate, Calendar.MONTH);
358 assertEquals(millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE)
359 + (hours * DateUtils.MILLIS_PER_HOUR) + ((days - 1) * DateUtils.MILLIS_PER_DAY),
360 testResult);
361243 }
362244
363245 @Test
368250 testResult);
369251 }
370252
371 @Test
372 public void testSecondsOfMonthWithDate() {
373 final long testResult = DateUtils.getFragmentInSeconds(aDate, Calendar.MONTH);
374 assertEquals(
375 seconds
376 + ((minutes * DateUtils.MILLIS_PER_MINUTE)
377 + (hours * DateUtils.MILLIS_PER_HOUR) + ((days - 1) * DateUtils.MILLIS_PER_DAY))
378 / DateUtils.MILLIS_PER_SECOND,
379 testResult);
380 }
381
382 @Test
383 public void testSecondsOfMonthWithCalendar() {
384 final long testResult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.MONTH);
385 assertEquals(
386 seconds
387 + ((minutes * DateUtils.MILLIS_PER_MINUTE)
388 + (hours * DateUtils.MILLIS_PER_HOUR) + ((days - 1) * DateUtils.MILLIS_PER_DAY))
389 / DateUtils.MILLIS_PER_SECOND,
390 testResult);
391 }
392
393 @Test
394 public void testMinutesOfMonthWithDate() {
395 final long testResult = DateUtils.getFragmentInMinutes(aDate, Calendar.MONTH);
396 assertEquals(minutes
397 + ((hours * DateUtils.MILLIS_PER_HOUR) + ((days - 1) * DateUtils.MILLIS_PER_DAY))
398 / DateUtils.MILLIS_PER_MINUTE,
399 testResult);
400 }
401
402 @Test
403 public void testMinutesOfMonthWithCalendar() {
404 final long testResult = DateUtils.getFragmentInMinutes(aCalendar, Calendar.MONTH);
405 assertEquals( minutes +((hours * DateUtils.MILLIS_PER_HOUR) + ((days - 1) * DateUtils.MILLIS_PER_DAY))
406 / DateUtils.MILLIS_PER_MINUTE,
407 testResult);
408 }
409
410 @Test
411 public void testHoursOfMonthWithDate() {
412 final long testResult = DateUtils.getFragmentInHours(aDate, Calendar.MONTH);
413 assertEquals(hours + (((days - 1) * DateUtils.MILLIS_PER_DAY))
414 / DateUtils.MILLIS_PER_HOUR,
415 testResult);
416 }
417
418 @Test
419 public void testHoursOfMonthWithCalendar() {
420 final long testResult = DateUtils.getFragmentInHours(aCalendar, Calendar.MONTH);
421 assertEquals( hours +(((days - 1) * DateUtils.MILLIS_PER_DAY))
422 / DateUtils.MILLIS_PER_HOUR,
423 testResult);
253 //Calendar.MONTH as useful fragment
254 @Test
255 public void testMillisecondsOfMonthWithDate() {
256 final long testResult = DateUtils.getFragmentInMilliseconds(aDate, Calendar.MONTH);
257 assertEquals(millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE)
258 + (hours * DateUtils.MILLIS_PER_HOUR) + ((days - 1) * DateUtils.MILLIS_PER_DAY),
259 testResult);
260 }
261
262 @Test
263 public void testMillisecondsOfSecondWithCalendar() {
264 final long testResult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.SECOND);
265 assertEquals(millis, testResult);
266 assertEquals(aCalendar.get(Calendar.MILLISECOND), testResult);
267 }
268
269 @Test
270 public void testMillisecondsOfSecondWithDate() {
271 final long testResult = DateUtils.getFragmentInMilliseconds(aDate, Calendar.SECOND);
272 assertEquals(millis, testResult);
273 }
274
275 @Test
276 public void testMillisecondsOfYearWithCalendar() {
277 final long testResult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.YEAR);
278 assertEquals(millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE)
279 + (hours * DateUtils.MILLIS_PER_HOUR) + ((aCalendar.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY),
280 testResult);
424281 }
425282
426283 //Calendar.YEAR as useful fragment
435292 }
436293
437294 @Test
438 public void testMillisecondsOfYearWithCalendar() {
439 final long testResult = DateUtils.getFragmentInMilliseconds(aCalendar, Calendar.YEAR);
440 assertEquals(millis + (seconds * DateUtils.MILLIS_PER_SECOND) + (minutes * DateUtils.MILLIS_PER_MINUTE)
441 + (hours * DateUtils.MILLIS_PER_HOUR) + ((aCalendar.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY),
442 testResult);
443 }
444
445 @Test
446 public void testSecondsOfYearWithDate() {
447 final long testResult = DateUtils.getFragmentInSeconds(aDate, Calendar.YEAR);
448 final Calendar cal = Calendar.getInstance();
449 cal.setTime(aDate);
450 assertEquals(
451 seconds
452 + ((minutes * DateUtils.MILLIS_PER_MINUTE)
453 + (hours * DateUtils.MILLIS_PER_HOUR) + ((cal.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY))
454 / DateUtils.MILLIS_PER_SECOND,
455 testResult);
456 }
457
458 @Test
459 public void testSecondsOfYearWithCalendar() {
460 final long testResult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.YEAR);
461 assertEquals(
462 seconds
463 + ((minutes * DateUtils.MILLIS_PER_MINUTE)
464 + (hours * DateUtils.MILLIS_PER_HOUR) + ((aCalendar.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY))
465 / DateUtils.MILLIS_PER_SECOND,
295 public void testMinuteFragmentInLargerUnitWithCalendar() {
296 assertEquals(0, DateUtils.getFragmentInMinutes(aCalendar, Calendar.MINUTE));
297 assertEquals(0, DateUtils.getFragmentInHours(aCalendar, Calendar.MINUTE));
298 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.MINUTE));
299 }
300
301 @Test
302 public void testMinuteFragmentInLargerUnitWithDate() {
303 assertEquals(0, DateUtils.getFragmentInMinutes(aDate, Calendar.MINUTE));
304 assertEquals(0, DateUtils.getFragmentInHours(aDate, Calendar.MINUTE));
305 assertEquals(0, DateUtils.getFragmentInDays(aDate, Calendar.MINUTE));
306 }
307
308 @Test
309 public void testMinutesOfDayWithCalendar() {
310 long testResult = DateUtils.getFragmentInMinutes(aCalendar, Calendar.DATE);
311 final long expectedValue = minutes + ((hours * DateUtils.MILLIS_PER_HOUR))/ DateUtils.MILLIS_PER_MINUTE;
312 assertEquals(expectedValue, testResult);
313 testResult = DateUtils.getFragmentInMinutes(aCalendar, Calendar.DAY_OF_YEAR);
314 assertEquals(expectedValue, testResult);
315 }
316
317 @Test
318 public void testMinutesOfDayWithDate() {
319 long testResult = DateUtils.getFragmentInMinutes(aDate, Calendar.DATE);
320 final long expectedValue = minutes + ((hours * DateUtils.MILLIS_PER_HOUR))/ DateUtils.MILLIS_PER_MINUTE;
321 assertEquals(expectedValue, testResult);
322 testResult = DateUtils.getFragmentInMinutes(aDate, Calendar.DAY_OF_YEAR);
323 assertEquals(expectedValue, testResult);
324 }
325
326
327 @Test
328 public void testMinutesOfHourWithCalendar() {
329 final long testResult = DateUtils.getFragmentInMinutes(aCalendar, Calendar.HOUR_OF_DAY);
330 assertEquals(minutes, testResult);
331 }
332
333 @Test
334 public void testMinutesOfHourWithDate() {
335 final long testResult = DateUtils.getFragmentInMinutes(aDate, Calendar.HOUR_OF_DAY);
336 assertEquals(minutes, testResult);
337 }
338
339 @Test
340 public void testMinutesOfMonthWithCalendar() {
341 final long testResult = DateUtils.getFragmentInMinutes(aCalendar, Calendar.MONTH);
342 assertEquals( minutes +((hours * DateUtils.MILLIS_PER_HOUR) + ((days - 1) * DateUtils.MILLIS_PER_DAY))
343 / DateUtils.MILLIS_PER_MINUTE,
344 testResult);
345 }
346
347 @Test
348 public void testMinutesOfMonthWithDate() {
349 final long testResult = DateUtils.getFragmentInMinutes(aDate, Calendar.MONTH);
350 assertEquals(minutes
351 + ((hours * DateUtils.MILLIS_PER_HOUR) + ((days - 1) * DateUtils.MILLIS_PER_DAY))
352 / DateUtils.MILLIS_PER_MINUTE,
353 testResult);
354 }
355
356 @Test
357 public void testMinutesOfYearWithCalendar() {
358 final long testResult = DateUtils.getFragmentInMinutes(aCalendar, Calendar.YEAR);
359 assertEquals( minutes +((hours * DateUtils.MILLIS_PER_HOUR) + ((aCalendar.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY))
360 / DateUtils.MILLIS_PER_MINUTE,
466361 testResult);
467362 }
468363
473368 cal.setTime(aDate);
474369 assertEquals(minutes
475370 + ((hours * DateUtils.MILLIS_PER_HOUR) + ((cal.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY))
476 / DateUtils.MILLIS_PER_MINUTE,
477 testResult);
478 }
479
480 @Test
481 public void testMinutesOfYearWithCalendar() {
482 final long testResult = DateUtils.getFragmentInMinutes(aCalendar, Calendar.YEAR);
483 assertEquals( minutes +((hours * DateUtils.MILLIS_PER_HOUR) + ((aCalendar.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY))
484371 / DateUtils.MILLIS_PER_MINUTE,
485372 testResult);
486373 }
499386 }
500387
501388 @Test
502 public void testHoursOfYearWithDate() {
503 final long testResult = DateUtils.getFragmentInHours(aDate, Calendar.YEAR);
389 public void testNullCalendar() {
390 assertThrows(
391 IllegalArgumentException.class,
392 () -> DateUtils.getFragmentInMilliseconds((Calendar) null, Calendar.MILLISECOND));
393
394 assertThrows(
395 IllegalArgumentException.class,
396 () -> DateUtils.getFragmentInSeconds((Calendar) null, Calendar.MILLISECOND));
397
398 assertThrows(
399 IllegalArgumentException.class,
400 () -> DateUtils.getFragmentInMinutes((Calendar) null, Calendar.MILLISECOND));
401
402 assertThrows(
403 IllegalArgumentException.class,
404 () -> DateUtils.getFragmentInHours((Calendar) null, Calendar.MILLISECOND));
405
406 assertThrows(
407 IllegalArgumentException.class,
408 () -> DateUtils.getFragmentInDays((Calendar) null, Calendar.MILLISECOND));
409 }
410
411 @Test
412 public void testNullDate() {
413 assertThrows(
414 NullPointerException.class,
415 () -> DateUtils.getFragmentInMilliseconds((Date) null, Calendar.MILLISECOND));
416
417 assertThrows(
418 NullPointerException.class,
419 () -> DateUtils.getFragmentInSeconds((Date) null, Calendar.MILLISECOND));
420
421 assertThrows(
422 NullPointerException.class,
423 () -> DateUtils.getFragmentInMinutes((Date) null, Calendar.MILLISECOND));
424
425 assertThrows(
426 NullPointerException.class,
427 () -> DateUtils.getFragmentInHours((Date) null, Calendar.MILLISECOND));
428
429 assertThrows(
430 NullPointerException.class,
431 () -> DateUtils.getFragmentInDays((Date) null, Calendar.MILLISECOND));
432 }
433
434 @Test
435 public void testSecondFragmentInLargerUnitWithCalendar() {
436 assertEquals(0, DateUtils.getFragmentInSeconds(aCalendar, Calendar.SECOND));
437 assertEquals(0, DateUtils.getFragmentInMinutes(aCalendar, Calendar.SECOND));
438 assertEquals(0, DateUtils.getFragmentInHours(aCalendar, Calendar.SECOND));
439 assertEquals(0, DateUtils.getFragmentInDays(aCalendar, Calendar.SECOND));
440 }
441
442 @Test
443 public void testSecondFragmentInLargerUnitWithDate() {
444 assertEquals(0, DateUtils.getFragmentInSeconds(aDate, Calendar.SECOND));
445 assertEquals(0, DateUtils.getFragmentInMinutes(aDate, Calendar.SECOND));
446 assertEquals(0, DateUtils.getFragmentInHours(aDate, Calendar.SECOND));
447 assertEquals(0, DateUtils.getFragmentInDays(aDate, Calendar.SECOND));
448 }
449
450 @Test
451 public void testSecondsOfDayWithCalendar() {
452 long testresult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.DATE);
453 final long expectedValue = seconds + ((minutes * DateUtils.MILLIS_PER_MINUTE) + (hours * DateUtils.MILLIS_PER_HOUR))/ DateUtils.MILLIS_PER_SECOND;
454 assertEquals(expectedValue, testresult);
455 testresult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.DAY_OF_YEAR);
456 assertEquals(expectedValue, testresult);
457 }
458
459 @Test
460 public void testSecondsOfDayWithDate() {
461 long testresult = DateUtils.getFragmentInSeconds(aDate, Calendar.DATE);
462 final long expectedValue = seconds + ((minutes * DateUtils.MILLIS_PER_MINUTE) + (hours * DateUtils.MILLIS_PER_HOUR))/ DateUtils.MILLIS_PER_SECOND;
463 assertEquals(expectedValue, testresult);
464 testresult = DateUtils.getFragmentInSeconds(aDate, Calendar.DAY_OF_YEAR);
465 assertEquals(expectedValue, testresult);
466 }
467
468 @Test
469 public void testSecondsofHourWithCalendar() {
470 final long testResult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.HOUR_OF_DAY);
471 assertEquals(
472 seconds
473 + (minutes
474 * DateUtils.MILLIS_PER_MINUTE / DateUtils.MILLIS_PER_SECOND),
475 testResult);
476 }
477
478 @Test
479 public void testSecondsofHourWithDate() {
480 final long testResult = DateUtils.getFragmentInSeconds(aDate, Calendar.HOUR_OF_DAY);
481 assertEquals(
482 seconds
483 + (minutes
484 * DateUtils.MILLIS_PER_MINUTE / DateUtils.MILLIS_PER_SECOND),
485 testResult);
486 }
487
488 @Test
489 public void testSecondsofMinuteWithCalendar() {
490 final long testResult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.MINUTE);
491 assertEquals(seconds, testResult);
492 assertEquals(aCalendar.get(Calendar.SECOND), testResult);
493 }
494
495 @Test
496 public void testSecondsofMinuteWithDate() {
497 final long testResult = DateUtils.getFragmentInSeconds(aDate, Calendar.MINUTE);
498 assertEquals(seconds, testResult);
499 }
500
501 @Test
502 public void testSecondsOfMonthWithCalendar() {
503 final long testResult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.MONTH);
504 assertEquals(
505 seconds
506 + ((minutes * DateUtils.MILLIS_PER_MINUTE)
507 + (hours * DateUtils.MILLIS_PER_HOUR) + ((days - 1) * DateUtils.MILLIS_PER_DAY))
508 / DateUtils.MILLIS_PER_SECOND,
509 testResult);
510 }
511
512 @Test
513 public void testSecondsOfMonthWithDate() {
514 final long testResult = DateUtils.getFragmentInSeconds(aDate, Calendar.MONTH);
515 assertEquals(
516 seconds
517 + ((minutes * DateUtils.MILLIS_PER_MINUTE)
518 + (hours * DateUtils.MILLIS_PER_HOUR) + ((days - 1) * DateUtils.MILLIS_PER_DAY))
519 / DateUtils.MILLIS_PER_SECOND,
520 testResult);
521 }
522
523 @Test
524 public void testSecondsOfYearWithCalendar() {
525 final long testResult = DateUtils.getFragmentInSeconds(aCalendar, Calendar.YEAR);
526 assertEquals(
527 seconds
528 + ((minutes * DateUtils.MILLIS_PER_MINUTE)
529 + (hours * DateUtils.MILLIS_PER_HOUR) + ((aCalendar.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY))
530 / DateUtils.MILLIS_PER_SECOND,
531 testResult);
532 }
533
534 @Test
535 public void testSecondsOfYearWithDate() {
536 final long testResult = DateUtils.getFragmentInSeconds(aDate, Calendar.YEAR);
504537 final Calendar cal = Calendar.getInstance();
505538 cal.setTime(aDate);
506 assertEquals(hours + (((cal.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY))
507 / DateUtils.MILLIS_PER_HOUR,
508 testResult);
509 }
510
511 @Test
512 public void testHoursOfYearWithCalendar() {
513 final long testResult = DateUtils.getFragmentInHours(aCalendar, Calendar.YEAR);
514 assertEquals( hours +(((aCalendar.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY))
515 / DateUtils.MILLIS_PER_HOUR,
516 testResult);
517 }
518
519 @Test
520 public void testDaysOfMonthWithCalendar() {
521 final long testResult = DateUtils.getFragmentInDays(aCalendar, Calendar.MONTH);
522 assertEquals(days, testResult);
523 }
524
525 @Test
526 public void testDaysOfMonthWithDate() {
527 final long testResult = DateUtils.getFragmentInDays(aDate, Calendar.MONTH);
528 final Calendar cal = Calendar.getInstance();
529 cal.setTime(aDate);
530 assertEquals(cal.get(Calendar.DAY_OF_MONTH), testResult);
531 }
532
533 @Test
534 public void testDaysOfYearWithCalendar() {
535 final long testResult = DateUtils.getFragmentInDays(aCalendar, Calendar.YEAR);
536 assertEquals(aCalendar.get(Calendar.DAY_OF_YEAR), testResult);
537 }
538
539 @Test
540 public void testDaysOfYearWithDate() {
541 final long testResult = DateUtils.getFragmentInDays(aDate, Calendar.YEAR);
542 final Calendar cal = Calendar.getInstance();
543 cal.setTime(aDate);
544 assertEquals(cal.get(Calendar.DAY_OF_YEAR), testResult);
539 assertEquals(
540 seconds
541 + ((minutes * DateUtils.MILLIS_PER_MINUTE)
542 + (hours * DateUtils.MILLIS_PER_HOUR) + ((cal.get(Calendar.DAY_OF_YEAR) - 1) * DateUtils.MILLIS_PER_DAY))
543 / DateUtils.MILLIS_PER_SECOND,
544 testResult);
545545 }
546546 }
5757 FastDateFormat fdf = DateFormatUtils.ISO_DATETIME_FORMAT;
5858
5959
60 @BeforeEach
61 public void setUp() throws Exception {
62
63 dateTimeParser = new SimpleDateFormat("MMM dd, yyyy H:mm:ss.SSS", Locale.ENGLISH);
64
65 targetYearDate = dateTimeParser.parse("January 1, 2007 0:00:00.000");
66 targetDateDate = targetDayOfMonthDate = dateTimeParser.parse("June 1, 2008 0:00:00.000");
67 targetAmDate = dateTimeParser.parse("June 1, 2008 0:00:00.000");
68 targetPmDate = dateTimeParser.parse("June 1, 2008 12:00:00.000");
69 targetHourDate = dateTimeParser.parse("June 1, 2008 8:00:00.000");
70 targetHourOfDayDate = dateTimeParser.parse("June 1, 2008 8:00:00.000");
71 targetMinuteDate = dateTimeParser.parse("June 1, 2008 8:15:00.000");
72 targetSecondDate = dateTimeParser.parse("June 1, 2008 8:15:14.000");
73 targetMilliSecondDate = dateTimeParser.parse("June 1, 2008 8:15:14.231");
74
75 januaryOneDate = dateTimeParser.parse("January 1, 2008 0:00:00.000");
76 januaryOneCalendar = Calendar.getInstance();
77 januaryOneCalendar.setTime(januaryOneDate);
78 }
79
80 /**
81 * Tests DateUtils.round()-method with Calendar.Year
82 *
83 * @throws Exception so we don't have to catch it
84 * @since 3.0
85 */
86 @Test
87 public void testRoundYear() throws Exception {
88 final int calendarField = Calendar.YEAR;
89 final Date roundedUpDate = dateTimeParser.parse("January 1, 2008 0:00:00.000");
90 final Date roundedDownDate = targetYearDate;
91 final Date lastRoundedDownDate = dateTimeParser.parse("June 30, 2007 23:59:59.999");
92 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
93 }
94
95 /**
96 * Tests DateUtils.round()-method with Calendar.MONTH
97 * Includes rounding months with 28, 29, 30 and 31 days
98 * Includes rounding to January 1
99 *
100 * @throws Exception so we don't have to catch it
101 * @since 3.0
102 */
103 @Test
104 public void testRoundMonth() throws Exception {
105 final int calendarField = Calendar.MONTH;
106 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
107 Date minDate, maxDate;
108
109 //month with 28 days
110 roundedUpDate = dateTimeParser.parse("March 1, 2007 0:00:00.000");
111 roundedDownDate = dateTimeParser.parse("February 1, 2007 0:00:00.000");
112 lastRoundedDownDate = dateTimeParser.parse("February 14, 2007 23:59:59.999");
113 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
114
115 //month with 29 days
116 roundedUpDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
117 roundedDownDate = dateTimeParser.parse("February 1, 2008 0:00:00.000");
118 lastRoundedDownDate = dateTimeParser.parse("February 15, 2008 23:59:59.999");
119 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
120
121 //month with 30 days
122 roundedUpDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
123 roundedDownDate = dateTimeParser.parse("April 1, 2008 0:00:00.000");
124 lastRoundedDownDate = dateTimeParser.parse("April 15, 2008 23:59:59.999");
125 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
126
127 //month with 31 days
128 roundedUpDate = dateTimeParser.parse("June 1, 2008 0:00:00.000");
129 roundedDownDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
130 lastRoundedDownDate = dateTimeParser.parse("May 16, 2008 23:59:59.999");
131 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
132
133 //round to January 1
134 minDate = dateTimeParser.parse("December 17, 2007 00:00:00.000");
135 maxDate = dateTimeParser.parse("January 16, 2008 23:59:59.999");
136 roundToJanuaryFirst(minDate, maxDate, calendarField);
137 }
138
139 /**
140 * Tests DateUtils.round()-method with DateUtils.SEMI_MONTH
141 * Includes rounding months with 28, 29, 30 and 31 days, each with first and second half
142 * Includes rounding to January 1
143 *
144 * @throws Exception so we don't have to catch it
145 * @since 3.0
146 */
147 @Test
148 public void testRoundSemiMonth() throws Exception {
149 final int calendarField = DateUtils.SEMI_MONTH;
150 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
151 Date minDate, maxDate;
152
153 //month with 28 days (1)
154 roundedUpDate = dateTimeParser.parse("February 16, 2007 0:00:00.000");
155 roundedDownDate = dateTimeParser.parse("February 1, 2007 0:00:00.000");
156 lastRoundedDownDate = dateTimeParser.parse("February 8, 2007 23:59:59.999");
157 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
158
159 //month with 28 days (2)
160 roundedUpDate = dateTimeParser.parse("March 1, 2007 0:00:00.000");
161 roundedDownDate = dateTimeParser.parse("February 16, 2007 0:00:00.000");
162 lastRoundedDownDate = dateTimeParser.parse("February 23, 2007 23:59:59.999");
163 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
164
165 //month with 29 days (1)
166 roundedUpDate = dateTimeParser.parse("February 16, 2008 0:00:00.000");
167 roundedDownDate = dateTimeParser.parse("February 1, 2008 0:00:00.000");
168 lastRoundedDownDate = dateTimeParser.parse("February 8, 2008 23:59:59.999");
169 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
170
171 //month with 29 days (2)
172 roundedUpDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
173 roundedDownDate = dateTimeParser.parse("February 16, 2008 0:00:00.000");
174 lastRoundedDownDate = dateTimeParser.parse("February 23, 2008 23:59:59.999");
175 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
176
177 //month with 30 days (1)
178 roundedUpDate = dateTimeParser.parse("April 16, 2008 0:00:00.000");
179 roundedDownDate = dateTimeParser.parse("April 1, 2008 0:00:00.000");
180 lastRoundedDownDate = dateTimeParser.parse("April 8, 2008 23:59:59.999");
181 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
182
183 //month with 30 days (2)
184 roundedUpDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
185 roundedDownDate = dateTimeParser.parse("April 16, 2008 0:00:00.000");
186 lastRoundedDownDate = dateTimeParser.parse("April 23, 2008 23:59:59.999");
187 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
188
189 //month with 31 days (1)
190 roundedUpDate = dateTimeParser.parse("May 16, 2008 0:00:00.000");
191 roundedDownDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
192 lastRoundedDownDate = dateTimeParser.parse("May 8, 2008 23:59:59.999");
193 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
194
195 //month with 31 days (2)
196 roundedUpDate = dateTimeParser.parse("June 1, 2008 0:00:00.000");
197 roundedDownDate = dateTimeParser.parse("May 16, 2008 0:00:00.000");
198 lastRoundedDownDate = dateTimeParser.parse("May 23, 2008 23:59:59.999");
199 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
200
201 //round to January 1
202 minDate = dateTimeParser.parse("December 24, 2007 00:00:00.000");
203 maxDate = dateTimeParser.parse("January 8, 2008 23:59:59.999");
204 roundToJanuaryFirst(minDate, maxDate, calendarField);
205 }
206
207 /**
208 * Tests DateUtils.round()-method with Calendar.DATE
209 * Includes rounding the extremes of one day
210 * Includes rounding to January 1
211 *
212 * @throws Exception so we don't have to catch it
213 * @since 3.0
214 */
215 @Test
216 public void testRoundDate() throws Exception {
217 final int calendarField = Calendar.DATE;
218 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
219 Date minDate, maxDate;
220
221 roundedUpDate = dateTimeParser.parse("June 2, 2008 0:00:00.000");
222 roundedDownDate = targetDateDate;
223 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 11:59:59.999");
224 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
225
226 //round to January 1
227 minDate = dateTimeParser.parse("December 31, 2007 12:00:00.000");
228 maxDate = dateTimeParser.parse("January 1, 2008 11:59:59.999");
229 roundToJanuaryFirst(minDate, maxDate, calendarField);
230 }
231
232 /**
233 * Tests DateUtils.round()-method with Calendar.DAY_OF_MONTH
234 * Includes rounding the extremes of one day
235 * Includes rounding to January 1
236 *
237 * @throws Exception so we don't have to catch it
238 * @since 3.0
239 */
240 @Test
241 public void testRoundDayOfMonth() throws Exception {
242 final int calendarField = Calendar.DAY_OF_MONTH;
243 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
244 Date minDate, maxDate;
245
246 roundedUpDate = dateTimeParser.parse("June 2, 2008 0:00:00.000");
247 roundedDownDate = targetDayOfMonthDate;
248 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 11:59:59.999");
249 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
250
251 //round to January 1
252 minDate = dateTimeParser.parse("December 31, 2007 12:00:00.000");
253 maxDate = dateTimeParser.parse("January 1, 2008 11:59:59.999");
254 roundToJanuaryFirst(minDate, maxDate, calendarField);
255 }
256
257 /**
258 * Tests DateUtils.round()-method with Calendar.AM_PM
259 * Includes rounding the extremes of both AM and PM of one day
260 * Includes rounding to January 1
261 *
262 * @throws Exception so we don't have to catch it
263 * @since 3.0
264 */
265 @Test
266 public void testRoundAmPm() throws Exception {
267 final int calendarField = Calendar.AM_PM;
268 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
269 Date minDate, maxDate;
270
271 //AM
272 roundedUpDate = dateTimeParser.parse("June 1, 2008 12:00:00.000");
273 roundedDownDate = targetAmDate;
274 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 5:59:59.999");
275 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
276
277 //PM
278 roundedUpDate = dateTimeParser.parse("June 2, 2008 0:00:00.000");
279 roundedDownDate = targetPmDate;
280 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 17:59:59.999");
281 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
282
283 //round to January 1
284 minDate = dateTimeParser.parse("December 31, 2007 18:00:00.000");
285 maxDate = dateTimeParser.parse("January 1, 2008 5:59:59.999");
286 roundToJanuaryFirst(minDate, maxDate, calendarField);
287 }
288
289 /**
290 * Tests DateUtils.round()-method with Calendar.HOUR_OF_DAY
291 * Includes rounding the extremes of one hour
292 * Includes rounding to January 1
293 *
294 * @throws Exception so we don't have to catch it
295 * @since 3.0
296 */
297 @Test
298 public void testRoundHourOfDay() throws Exception {
299 final int calendarField = Calendar.HOUR_OF_DAY;
300 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
301 Date minDate, maxDate;
302
303 roundedUpDate = dateTimeParser.parse("June 1, 2008 9:00:00.000");
304 roundedDownDate = targetHourOfDayDate;
305 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:29:59.999");
306 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
307
308 //round to January 1
309 minDate = dateTimeParser.parse("December 31, 2007 23:30:00.000");
310 maxDate = dateTimeParser.parse("January 1, 2008 0:29:59.999");
311 roundToJanuaryFirst(minDate, maxDate, calendarField);
312 }
313
314 /**
315 * Tests DateUtils.round()-method with Calendar.HOUR
316 * Includes rounding the extremes of one hour
317 * Includes rounding to January 1
318 *
319 * @throws Exception so we don't have to catch it
320 * @since 3.0
321 */
322 @Test
323 public void testRoundHour() throws Exception {
324 final int calendarField = Calendar.HOUR;
325 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
326 Date minDate, maxDate;
327
328 roundedUpDate = dateTimeParser.parse("June 1, 2008 9:00:00.000");
329 roundedDownDate = targetHourDate;
330 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:29:59.999");
331 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
332
333 //round to January 1
334 minDate = dateTimeParser.parse("December 31, 2007 23:30:00.000");
335 maxDate = dateTimeParser.parse("January 1, 2008 0:29:59.999");
336 roundToJanuaryFirst(minDate, maxDate, calendarField);
337 }
338
339 /**
340 * Tests DateUtils.round()-method with Calendar.MINUTE
341 * Includes rounding the extremes of one minute
342 * Includes rounding to January 1
343 *
344 * @throws Exception so we don't have to catch it
345 * @since 3.0
346 */
347 @Test
348 public void testRoundMinute() throws Exception {
349 final int calendarField = Calendar.MINUTE;
350 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
351 Date minDate, maxDate;
352
353 roundedUpDate = dateTimeParser.parse("June 1, 2008 8:16:00.000");
354 roundedDownDate = targetMinuteDate;
355 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:15:29.999");
356 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
357
358 //round to January 1
359 minDate = dateTimeParser.parse("December 31, 2007 23:59:30.000");
360 maxDate = dateTimeParser.parse("January 1, 2008 0:00:29.999");
361 roundToJanuaryFirst(minDate, maxDate, calendarField);
362 }
363
364 /**
365 * Tests DateUtils.round()-method with Calendar.SECOND
366 * Includes rounding the extremes of one second
367 * Includes rounding to January 1
368 *
369 * @throws Exception so we don't have to catch it
370 * @since 3.0
371 */
372 @Test
373 public void testRoundSecond() throws Exception {
374 final int calendarField = Calendar.SECOND;
375 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
376 Date minDate, maxDate;
377
378 roundedUpDate = dateTimeParser.parse("June 1, 2008 8:15:15.000");
379 roundedDownDate = targetSecondDate;
380 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:15:14.499");
381 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
382
383 //round to January 1
384 minDate = dateTimeParser.parse("December 31, 2007 23:59:59.500");
385 maxDate = dateTimeParser.parse("January 1, 2008 0:00:00.499");
386 roundToJanuaryFirst(minDate, maxDate, calendarField);
387 }
388
389 /**
390 * Tests DateUtils.round()-method with Calendar.MILLISECOND
391 * Includes rounding the extremes of one second
392 * Includes rounding to January 1
393 *
394 * @throws Exception so we don't have to catch it
395 * @since 3.0
396 */
397 @Test
398 public void testRoundMilliSecond() throws Exception {
399 final int calendarField = Calendar.MILLISECOND;
400 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
401 Date minDate, maxDate;
402
403 roundedDownDate = lastRoundedDownDate = targetMilliSecondDate;
404 roundedUpDate = dateTimeParser.parse("June 1, 2008 8:15:14.232");
405 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
406
407 //round to January 1
408 minDate = maxDate = januaryOneDate;
409 roundToJanuaryFirst(minDate, maxDate, calendarField);
410 }
411
412 /**
413 * Test DateUtils.truncate()-method with Calendar.YEAR
414 *
415 * @throws Exception so we don't have to catch it
416 * @since 3.0
417 */
418 @Test
419 public void testTruncateYear() throws Exception {
420 final int calendarField = Calendar.YEAR;
421 final Date lastTruncateDate = dateTimeParser.parse("December 31, 2007 23:59:59.999");
422 baseTruncateTest(targetYearDate, lastTruncateDate, calendarField);
423 }
424
425 /**
426 * Test DateUtils.truncate()-method with Calendar.MONTH
427 *
428 * @throws Exception so we don't have to catch it
429 * @since 3.0
430 */
431 @Test
432 public void testTruncateMonth() throws Exception {
433 final int calendarField = Calendar.MONTH;
434 final Date truncatedDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
435 final Date lastTruncateDate = dateTimeParser.parse("March 31, 2008 23:59:59.999");
436 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
437 }
438
439 /**
440 * Test DateUtils.truncate()-method with DateUtils.SEMI_MONTH
441 * Includes truncating months with 28, 29, 30 and 31 days, each with first and second half
442 *
443 * @throws Exception so we don't have to catch it
444 * @since 3.0
445 */
446 @Test
447 public void testTruncateSemiMonth() throws Exception {
448 final int calendarField = DateUtils.SEMI_MONTH;
449 Date truncatedDate, lastTruncateDate;
450
451 //month with 28 days (1)
452 truncatedDate = dateTimeParser.parse("February 1, 2007 0:00:00.000");
453 lastTruncateDate = dateTimeParser.parse("February 15, 2007 23:59:59.999");
454 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
455
456 //month with 28 days (2)
457 truncatedDate = dateTimeParser.parse("February 16, 2007 0:00:00.000");
458 lastTruncateDate = dateTimeParser.parse("February 28, 2007 23:59:59.999");
459 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
460
461 //month with 29 days (1)
462 truncatedDate = dateTimeParser.parse("February 1, 2008 0:00:00.000");
463 lastTruncateDate = dateTimeParser.parse("February 15, 2008 23:59:59.999");
464 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
465
466 //month with 29 days (2)
467 truncatedDate = dateTimeParser.parse("February 16, 2008 0:00:00.000");
468 lastTruncateDate = dateTimeParser.parse("February 29, 2008 23:59:59.999");
469 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
470
471 //month with 30 days (1)
472 truncatedDate = dateTimeParser.parse("April 1, 2008 0:00:00.000");
473 lastTruncateDate = dateTimeParser.parse("April 15, 2008 23:59:59.999");
474 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
475
476 //month with 30 days (2)
477 truncatedDate = dateTimeParser.parse("April 16, 2008 0:00:00.000");
478 lastTruncateDate = dateTimeParser.parse("April 30, 2008 23:59:59.999");
479 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
480
481 //month with 31 days (1)
482 truncatedDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
483 lastTruncateDate = dateTimeParser.parse("March 15, 2008 23:59:59.999");
484 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
485
486 //month with 31 days (2)
487 truncatedDate = dateTimeParser.parse("March 16, 2008 0:00:00.000");
488 lastTruncateDate = dateTimeParser.parse("March 31, 2008 23:59:59.999");
489 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
490
491 }
492
493 /**
494 * Test DateUtils.truncate()-method with Calendar.DATE
495 *
496 * @throws Exception so we don't have to catch it
497 * @since 3.0
498 */
499 @Test
500 public void testTruncateDate() throws Exception {
501 final int calendarField = Calendar.DATE;
502 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 23:59:59.999");
503 baseTruncateTest(targetDateDate, lastTruncateDate, calendarField);
504 }
505
506 /**
507 * Test DateUtils.truncate()-method with Calendar.DAY_OF_MONTH
508 *
509 * @throws Exception so we don't have to catch it
510 * @since 3.0
511 */
512 @Test
513 public void testTruncateDayOfMonth() throws Exception {
514 final int calendarField = Calendar.DAY_OF_MONTH;
515 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 23:59:59.999");
516 baseTruncateTest(targetDayOfMonthDate, lastTruncateDate, calendarField);
517 }
518
519 /**
520 * Test DateUtils.truncate()-method with Calendar.AM_PM
521 * Includes truncating the extremes of both AM and PM of one day
522 *
523 * @throws Exception so we don't have to catch it
524 * @since 3.0
525 */
526 @Test
527 public void testTruncateAmPm() throws Exception {
528 final int calendarField = Calendar.AM_PM;
529
530 //AM
531 Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 11:59:59.999");
532 baseTruncateTest(targetAmDate, lastTruncateDate, calendarField);
533
534 //PM
535 lastTruncateDate = dateTimeParser.parse("June 1, 2008 23:59:59.999");
536 baseTruncateTest(targetPmDate, lastTruncateDate, calendarField);
537 }
538
539 /**
540 * Test DateUtils.truncate()-method with Calendar.HOUR
541 *
542 * @throws Exception so we don't have to catch it
543 * @since 3.0
544 */
545 @Test
546 public void testTruncateHour() throws Exception {
547 final int calendarField = Calendar.HOUR;
548 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:59:59.999");
549 baseTruncateTest(targetHourDate, lastTruncateDate, calendarField);
550 }
551
552 /**
553 * Test DateUtils.truncate()-method with Calendar.HOUR_OF_DAY
554 *
555 * @throws Exception so we don't have to catch it
556 * @since 3.0
557 */
558 @Test
559 public void testTruncateHourOfDay() throws Exception {
560 final int calendarField = Calendar.HOUR_OF_DAY;
561 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:59:59.999");
562 baseTruncateTest(targetHourOfDayDate, lastTruncateDate, calendarField);
563 }
564
565 /**
566 * Test DateUtils.truncate()-method with Calendar.MINUTE
567 *
568 * @throws Exception so we don't have to catch it
569 * @since 3.0
570 */
571 @Test
572 public void testTruncateMinute() throws Exception {
573 final int calendarField = Calendar.MINUTE;
574 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:15:59.999");
575 baseTruncateTest(targetMinuteDate, lastTruncateDate, calendarField);
576 }
577
578 /**
579 * Test DateUtils.truncate()-method with Calendar.SECOND
580 *
581 * @throws Exception so we don't have to catch it
582 * @since 3.0
583 */
584 @Test
585 public void testTruncateSecond() throws Exception {
586 final int calendarField = Calendar.SECOND;
587 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:15:14.999");
588 baseTruncateTest(targetSecondDate, lastTruncateDate, calendarField);
589 }
590
591 /**
592 * Test DateUtils.truncate()-method with Calendar.SECOND
593 *
594 * @since 3.0
595 */
596 @Test
597 public void testTruncateMilliSecond() {
598 final int calendarField = Calendar.MILLISECOND;
599 baseTruncateTest(targetMilliSecondDate, targetMilliSecondDate, calendarField);
600 }
601
60260 /**
60361 * When using this basetest all extremes are tested.<br>
60462 * It will test the Date, Calendar and Object-implementation<br>
725183 assertNotEquals(januaryOneDate, DateUtils.round(toPrevRoundDate, calendarField), fdf.format(minCalendar) + " is not an lower-extreme when rounding as Date with CalendarField-value " + calendarField);
726184 assertNotEquals(januaryOneDate, DateUtils.round(toNextRoundDate, calendarField), fdf.format(maxCalendar) + " is not an upper-extreme when rounding as Date with CalendarField-value " + calendarField);
727185 }
186
187 @BeforeEach
188 public void setUp() throws Exception {
189
190 dateTimeParser = new SimpleDateFormat("MMM dd, yyyy H:mm:ss.SSS", Locale.ENGLISH);
191
192 targetYearDate = dateTimeParser.parse("January 1, 2007 0:00:00.000");
193 targetDateDate = targetDayOfMonthDate = dateTimeParser.parse("June 1, 2008 0:00:00.000");
194 targetAmDate = dateTimeParser.parse("June 1, 2008 0:00:00.000");
195 targetPmDate = dateTimeParser.parse("June 1, 2008 12:00:00.000");
196 targetHourDate = dateTimeParser.parse("June 1, 2008 8:00:00.000");
197 targetHourOfDayDate = dateTimeParser.parse("June 1, 2008 8:00:00.000");
198 targetMinuteDate = dateTimeParser.parse("June 1, 2008 8:15:00.000");
199 targetSecondDate = dateTimeParser.parse("June 1, 2008 8:15:14.000");
200 targetMilliSecondDate = dateTimeParser.parse("June 1, 2008 8:15:14.231");
201
202 januaryOneDate = dateTimeParser.parse("January 1, 2008 0:00:00.000");
203 januaryOneCalendar = Calendar.getInstance();
204 januaryOneCalendar.setTime(januaryOneDate);
205 }
206
207 /**
208 * Tests DateUtils.round()-method with Calendar.AM_PM
209 * Includes rounding the extremes of both AM and PM of one day
210 * Includes rounding to January 1
211 *
212 * @throws Exception so we don't have to catch it
213 * @since 3.0
214 */
215 @Test
216 public void testRoundAmPm() throws Exception {
217 final int calendarField = Calendar.AM_PM;
218 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
219 Date minDate, maxDate;
220
221 //AM
222 roundedUpDate = dateTimeParser.parse("June 1, 2008 12:00:00.000");
223 roundedDownDate = targetAmDate;
224 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 5:59:59.999");
225 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
226
227 //PM
228 roundedUpDate = dateTimeParser.parse("June 2, 2008 0:00:00.000");
229 roundedDownDate = targetPmDate;
230 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 17:59:59.999");
231 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
232
233 //round to January 1
234 minDate = dateTimeParser.parse("December 31, 2007 18:00:00.000");
235 maxDate = dateTimeParser.parse("January 1, 2008 5:59:59.999");
236 roundToJanuaryFirst(minDate, maxDate, calendarField);
237 }
238
239 /**
240 * Tests DateUtils.round()-method with Calendar.DATE
241 * Includes rounding the extremes of one day
242 * Includes rounding to January 1
243 *
244 * @throws Exception so we don't have to catch it
245 * @since 3.0
246 */
247 @Test
248 public void testRoundDate() throws Exception {
249 final int calendarField = Calendar.DATE;
250 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
251 Date minDate, maxDate;
252
253 roundedUpDate = dateTimeParser.parse("June 2, 2008 0:00:00.000");
254 roundedDownDate = targetDateDate;
255 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 11:59:59.999");
256 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
257
258 //round to January 1
259 minDate = dateTimeParser.parse("December 31, 2007 12:00:00.000");
260 maxDate = dateTimeParser.parse("January 1, 2008 11:59:59.999");
261 roundToJanuaryFirst(minDate, maxDate, calendarField);
262 }
263
264 /**
265 * Tests DateUtils.round()-method with Calendar.DAY_OF_MONTH
266 * Includes rounding the extremes of one day
267 * Includes rounding to January 1
268 *
269 * @throws Exception so we don't have to catch it
270 * @since 3.0
271 */
272 @Test
273 public void testRoundDayOfMonth() throws Exception {
274 final int calendarField = Calendar.DAY_OF_MONTH;
275 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
276 Date minDate, maxDate;
277
278 roundedUpDate = dateTimeParser.parse("June 2, 2008 0:00:00.000");
279 roundedDownDate = targetDayOfMonthDate;
280 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 11:59:59.999");
281 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
282
283 //round to January 1
284 minDate = dateTimeParser.parse("December 31, 2007 12:00:00.000");
285 maxDate = dateTimeParser.parse("January 1, 2008 11:59:59.999");
286 roundToJanuaryFirst(minDate, maxDate, calendarField);
287 }
288
289 /**
290 * Tests DateUtils.round()-method with Calendar.HOUR
291 * Includes rounding the extremes of one hour
292 * Includes rounding to January 1
293 *
294 * @throws Exception so we don't have to catch it
295 * @since 3.0
296 */
297 @Test
298 public void testRoundHour() throws Exception {
299 final int calendarField = Calendar.HOUR;
300 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
301 Date minDate, maxDate;
302
303 roundedUpDate = dateTimeParser.parse("June 1, 2008 9:00:00.000");
304 roundedDownDate = targetHourDate;
305 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:29:59.999");
306 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
307
308 //round to January 1
309 minDate = dateTimeParser.parse("December 31, 2007 23:30:00.000");
310 maxDate = dateTimeParser.parse("January 1, 2008 0:29:59.999");
311 roundToJanuaryFirst(minDate, maxDate, calendarField);
312 }
313
314 /**
315 * Tests DateUtils.round()-method with Calendar.HOUR_OF_DAY
316 * Includes rounding the extremes of one hour
317 * Includes rounding to January 1
318 *
319 * @throws Exception so we don't have to catch it
320 * @since 3.0
321 */
322 @Test
323 public void testRoundHourOfDay() throws Exception {
324 final int calendarField = Calendar.HOUR_OF_DAY;
325 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
326 Date minDate, maxDate;
327
328 roundedUpDate = dateTimeParser.parse("June 1, 2008 9:00:00.000");
329 roundedDownDate = targetHourOfDayDate;
330 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:29:59.999");
331 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
332
333 //round to January 1
334 minDate = dateTimeParser.parse("December 31, 2007 23:30:00.000");
335 maxDate = dateTimeParser.parse("January 1, 2008 0:29:59.999");
336 roundToJanuaryFirst(minDate, maxDate, calendarField);
337 }
338
339 /**
340 * Tests DateUtils.round()-method with Calendar.MILLISECOND
341 * Includes rounding the extremes of one second
342 * Includes rounding to January 1
343 *
344 * @throws Exception so we don't have to catch it
345 * @since 3.0
346 */
347 @Test
348 public void testRoundMilliSecond() throws Exception {
349 final int calendarField = Calendar.MILLISECOND;
350 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
351 Date minDate, maxDate;
352
353 roundedDownDate = lastRoundedDownDate = targetMilliSecondDate;
354 roundedUpDate = dateTimeParser.parse("June 1, 2008 8:15:14.232");
355 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
356
357 //round to January 1
358 minDate = maxDate = januaryOneDate;
359 roundToJanuaryFirst(minDate, maxDate, calendarField);
360 }
361
362 /**
363 * Tests DateUtils.round()-method with Calendar.MINUTE
364 * Includes rounding the extremes of one minute
365 * Includes rounding to January 1
366 *
367 * @throws Exception so we don't have to catch it
368 * @since 3.0
369 */
370 @Test
371 public void testRoundMinute() throws Exception {
372 final int calendarField = Calendar.MINUTE;
373 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
374 Date minDate, maxDate;
375
376 roundedUpDate = dateTimeParser.parse("June 1, 2008 8:16:00.000");
377 roundedDownDate = targetMinuteDate;
378 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:15:29.999");
379 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
380
381 //round to January 1
382 minDate = dateTimeParser.parse("December 31, 2007 23:59:30.000");
383 maxDate = dateTimeParser.parse("January 1, 2008 0:00:29.999");
384 roundToJanuaryFirst(minDate, maxDate, calendarField);
385 }
386
387 /**
388 * Tests DateUtils.round()-method with Calendar.MONTH
389 * Includes rounding months with 28, 29, 30 and 31 days
390 * Includes rounding to January 1
391 *
392 * @throws Exception so we don't have to catch it
393 * @since 3.0
394 */
395 @Test
396 public void testRoundMonth() throws Exception {
397 final int calendarField = Calendar.MONTH;
398 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
399 Date minDate, maxDate;
400
401 //month with 28 days
402 roundedUpDate = dateTimeParser.parse("March 1, 2007 0:00:00.000");
403 roundedDownDate = dateTimeParser.parse("February 1, 2007 0:00:00.000");
404 lastRoundedDownDate = dateTimeParser.parse("February 14, 2007 23:59:59.999");
405 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
406
407 //month with 29 days
408 roundedUpDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
409 roundedDownDate = dateTimeParser.parse("February 1, 2008 0:00:00.000");
410 lastRoundedDownDate = dateTimeParser.parse("February 15, 2008 23:59:59.999");
411 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
412
413 //month with 30 days
414 roundedUpDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
415 roundedDownDate = dateTimeParser.parse("April 1, 2008 0:00:00.000");
416 lastRoundedDownDate = dateTimeParser.parse("April 15, 2008 23:59:59.999");
417 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
418
419 //month with 31 days
420 roundedUpDate = dateTimeParser.parse("June 1, 2008 0:00:00.000");
421 roundedDownDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
422 lastRoundedDownDate = dateTimeParser.parse("May 16, 2008 23:59:59.999");
423 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
424
425 //round to January 1
426 minDate = dateTimeParser.parse("December 17, 2007 00:00:00.000");
427 maxDate = dateTimeParser.parse("January 16, 2008 23:59:59.999");
428 roundToJanuaryFirst(minDate, maxDate, calendarField);
429 }
430
431 /**
432 * Tests DateUtils.round()-method with Calendar.SECOND
433 * Includes rounding the extremes of one second
434 * Includes rounding to January 1
435 *
436 * @throws Exception so we don't have to catch it
437 * @since 3.0
438 */
439 @Test
440 public void testRoundSecond() throws Exception {
441 final int calendarField = Calendar.SECOND;
442 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
443 Date minDate, maxDate;
444
445 roundedUpDate = dateTimeParser.parse("June 1, 2008 8:15:15.000");
446 roundedDownDate = targetSecondDate;
447 lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:15:14.499");
448 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
449
450 //round to January 1
451 minDate = dateTimeParser.parse("December 31, 2007 23:59:59.500");
452 maxDate = dateTimeParser.parse("January 1, 2008 0:00:00.499");
453 roundToJanuaryFirst(minDate, maxDate, calendarField);
454 }
455
456 /**
457 * Tests DateUtils.round()-method with DateUtils.SEMI_MONTH
458 * Includes rounding months with 28, 29, 30 and 31 days, each with first and second half
459 * Includes rounding to January 1
460 *
461 * @throws Exception so we don't have to catch it
462 * @since 3.0
463 */
464 @Test
465 public void testRoundSemiMonth() throws Exception {
466 final int calendarField = DateUtils.SEMI_MONTH;
467 Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
468 Date minDate, maxDate;
469
470 //month with 28 days (1)
471 roundedUpDate = dateTimeParser.parse("February 16, 2007 0:00:00.000");
472 roundedDownDate = dateTimeParser.parse("February 1, 2007 0:00:00.000");
473 lastRoundedDownDate = dateTimeParser.parse("February 8, 2007 23:59:59.999");
474 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
475
476 //month with 28 days (2)
477 roundedUpDate = dateTimeParser.parse("March 1, 2007 0:00:00.000");
478 roundedDownDate = dateTimeParser.parse("February 16, 2007 0:00:00.000");
479 lastRoundedDownDate = dateTimeParser.parse("February 23, 2007 23:59:59.999");
480 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
481
482 //month with 29 days (1)
483 roundedUpDate = dateTimeParser.parse("February 16, 2008 0:00:00.000");
484 roundedDownDate = dateTimeParser.parse("February 1, 2008 0:00:00.000");
485 lastRoundedDownDate = dateTimeParser.parse("February 8, 2008 23:59:59.999");
486 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
487
488 //month with 29 days (2)
489 roundedUpDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
490 roundedDownDate = dateTimeParser.parse("February 16, 2008 0:00:00.000");
491 lastRoundedDownDate = dateTimeParser.parse("February 23, 2008 23:59:59.999");
492 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
493
494 //month with 30 days (1)
495 roundedUpDate = dateTimeParser.parse("April 16, 2008 0:00:00.000");
496 roundedDownDate = dateTimeParser.parse("April 1, 2008 0:00:00.000");
497 lastRoundedDownDate = dateTimeParser.parse("April 8, 2008 23:59:59.999");
498 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
499
500 //month with 30 days (2)
501 roundedUpDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
502 roundedDownDate = dateTimeParser.parse("April 16, 2008 0:00:00.000");
503 lastRoundedDownDate = dateTimeParser.parse("April 23, 2008 23:59:59.999");
504 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
505
506 //month with 31 days (1)
507 roundedUpDate = dateTimeParser.parse("May 16, 2008 0:00:00.000");
508 roundedDownDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
509 lastRoundedDownDate = dateTimeParser.parse("May 8, 2008 23:59:59.999");
510 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
511
512 //month with 31 days (2)
513 roundedUpDate = dateTimeParser.parse("June 1, 2008 0:00:00.000");
514 roundedDownDate = dateTimeParser.parse("May 16, 2008 0:00:00.000");
515 lastRoundedDownDate = dateTimeParser.parse("May 23, 2008 23:59:59.999");
516 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
517
518 //round to January 1
519 minDate = dateTimeParser.parse("December 24, 2007 00:00:00.000");
520 maxDate = dateTimeParser.parse("January 8, 2008 23:59:59.999");
521 roundToJanuaryFirst(minDate, maxDate, calendarField);
522 }
523
524 /**
525 * Tests DateUtils.round()-method with Calendar.Year
526 *
527 * @throws Exception so we don't have to catch it
528 * @since 3.0
529 */
530 @Test
531 public void testRoundYear() throws Exception {
532 final int calendarField = Calendar.YEAR;
533 final Date roundedUpDate = dateTimeParser.parse("January 1, 2008 0:00:00.000");
534 final Date roundedDownDate = targetYearDate;
535 final Date lastRoundedDownDate = dateTimeParser.parse("June 30, 2007 23:59:59.999");
536 baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate, calendarField);
537 }
538
539 /**
540 * Test DateUtils.truncate()-method with Calendar.AM_PM
541 * Includes truncating the extremes of both AM and PM of one day
542 *
543 * @throws Exception so we don't have to catch it
544 * @since 3.0
545 */
546 @Test
547 public void testTruncateAmPm() throws Exception {
548 final int calendarField = Calendar.AM_PM;
549
550 //AM
551 Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 11:59:59.999");
552 baseTruncateTest(targetAmDate, lastTruncateDate, calendarField);
553
554 //PM
555 lastTruncateDate = dateTimeParser.parse("June 1, 2008 23:59:59.999");
556 baseTruncateTest(targetPmDate, lastTruncateDate, calendarField);
557 }
558
559 /**
560 * Test DateUtils.truncate()-method with Calendar.DATE
561 *
562 * @throws Exception so we don't have to catch it
563 * @since 3.0
564 */
565 @Test
566 public void testTruncateDate() throws Exception {
567 final int calendarField = Calendar.DATE;
568 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 23:59:59.999");
569 baseTruncateTest(targetDateDate, lastTruncateDate, calendarField);
570 }
571
572 /**
573 * Test DateUtils.truncate()-method with Calendar.DAY_OF_MONTH
574 *
575 * @throws Exception so we don't have to catch it
576 * @since 3.0
577 */
578 @Test
579 public void testTruncateDayOfMonth() throws Exception {
580 final int calendarField = Calendar.DAY_OF_MONTH;
581 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 23:59:59.999");
582 baseTruncateTest(targetDayOfMonthDate, lastTruncateDate, calendarField);
583 }
584
585 /**
586 * Test DateUtils.truncate()-method with Calendar.HOUR
587 *
588 * @throws Exception so we don't have to catch it
589 * @since 3.0
590 */
591 @Test
592 public void testTruncateHour() throws Exception {
593 final int calendarField = Calendar.HOUR;
594 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:59:59.999");
595 baseTruncateTest(targetHourDate, lastTruncateDate, calendarField);
596 }
597
598 /**
599 * Test DateUtils.truncate()-method with Calendar.HOUR_OF_DAY
600 *
601 * @throws Exception so we don't have to catch it
602 * @since 3.0
603 */
604 @Test
605 public void testTruncateHourOfDay() throws Exception {
606 final int calendarField = Calendar.HOUR_OF_DAY;
607 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:59:59.999");
608 baseTruncateTest(targetHourOfDayDate, lastTruncateDate, calendarField);
609 }
610
611 /**
612 * Test DateUtils.truncate()-method with Calendar.SECOND
613 *
614 * @since 3.0
615 */
616 @Test
617 public void testTruncateMilliSecond() {
618 final int calendarField = Calendar.MILLISECOND;
619 baseTruncateTest(targetMilliSecondDate, targetMilliSecondDate, calendarField);
620 }
621
622 /**
623 * Test DateUtils.truncate()-method with Calendar.MINUTE
624 *
625 * @throws Exception so we don't have to catch it
626 * @since 3.0
627 */
628 @Test
629 public void testTruncateMinute() throws Exception {
630 final int calendarField = Calendar.MINUTE;
631 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:15:59.999");
632 baseTruncateTest(targetMinuteDate, lastTruncateDate, calendarField);
633 }
634
635 /**
636 * Test DateUtils.truncate()-method with Calendar.MONTH
637 *
638 * @throws Exception so we don't have to catch it
639 * @since 3.0
640 */
641 @Test
642 public void testTruncateMonth() throws Exception {
643 final int calendarField = Calendar.MONTH;
644 final Date truncatedDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
645 final Date lastTruncateDate = dateTimeParser.parse("March 31, 2008 23:59:59.999");
646 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
647 }
648
649 /**
650 * Test DateUtils.truncate()-method with Calendar.SECOND
651 *
652 * @throws Exception so we don't have to catch it
653 * @since 3.0
654 */
655 @Test
656 public void testTruncateSecond() throws Exception {
657 final int calendarField = Calendar.SECOND;
658 final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:15:14.999");
659 baseTruncateTest(targetSecondDate, lastTruncateDate, calendarField);
660 }
661
662 /**
663 * Test DateUtils.truncate()-method with DateUtils.SEMI_MONTH
664 * Includes truncating months with 28, 29, 30 and 31 days, each with first and second half
665 *
666 * @throws Exception so we don't have to catch it
667 * @since 3.0
668 */
669 @Test
670 public void testTruncateSemiMonth() throws Exception {
671 final int calendarField = DateUtils.SEMI_MONTH;
672 Date truncatedDate, lastTruncateDate;
673
674 //month with 28 days (1)
675 truncatedDate = dateTimeParser.parse("February 1, 2007 0:00:00.000");
676 lastTruncateDate = dateTimeParser.parse("February 15, 2007 23:59:59.999");
677 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
678
679 //month with 28 days (2)
680 truncatedDate = dateTimeParser.parse("February 16, 2007 0:00:00.000");
681 lastTruncateDate = dateTimeParser.parse("February 28, 2007 23:59:59.999");
682 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
683
684 //month with 29 days (1)
685 truncatedDate = dateTimeParser.parse("February 1, 2008 0:00:00.000");
686 lastTruncateDate = dateTimeParser.parse("February 15, 2008 23:59:59.999");
687 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
688
689 //month with 29 days (2)
690 truncatedDate = dateTimeParser.parse("February 16, 2008 0:00:00.000");
691 lastTruncateDate = dateTimeParser.parse("February 29, 2008 23:59:59.999");
692 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
693
694 //month with 30 days (1)
695 truncatedDate = dateTimeParser.parse("April 1, 2008 0:00:00.000");
696 lastTruncateDate = dateTimeParser.parse("April 15, 2008 23:59:59.999");
697 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
698
699 //month with 30 days (2)
700 truncatedDate = dateTimeParser.parse("April 16, 2008 0:00:00.000");
701 lastTruncateDate = dateTimeParser.parse("April 30, 2008 23:59:59.999");
702 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
703
704 //month with 31 days (1)
705 truncatedDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
706 lastTruncateDate = dateTimeParser.parse("March 15, 2008 23:59:59.999");
707 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
708
709 //month with 31 days (2)
710 truncatedDate = dateTimeParser.parse("March 16, 2008 0:00:00.000");
711 lastTruncateDate = dateTimeParser.parse("March 31, 2008 23:59:59.999");
712 baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
713
714 }
715
716 /**
717 * Test DateUtils.truncate()-method with Calendar.YEAR
718 *
719 * @throws Exception so we don't have to catch it
720 * @since 3.0
721 */
722 @Test
723 public void testTruncateYear() throws Exception {
724 final int calendarField = Calendar.YEAR;
725 final Date lastTruncateDate = dateTimeParser.parse("December 31, 2007 23:59:59.999");
726 baseTruncateTest(targetYearDate, lastTruncateDate, calendarField);
727 }
728728 }
4747
4848 private static Date BASE_DATE;
4949
50 /**
51 * Used to check that Calendar objects are close enough
52 * delta is in milliseconds
53 */
54 private static void assertCalendarsEquals(final String message, final Calendar cal1, final Calendar cal2, final long delta) {
55 assertFalse(Math.abs(cal1.getTime().getTime() - cal2.getTime().getTime()) > delta,
56 message + " expected " + cal1.getTime() + " but got " + cal2.getTime());
57 }
58
59 /**
60 * This checks that this is a 7 element iterator of Calendar objects
61 * that are dates (no time), and exactly 1 day spaced after each other.
62 */
63 private static void assertWeekIterator(final Iterator<?> it, final Calendar start) {
64 final Calendar end = (Calendar) start.clone();
65 end.add(Calendar.DATE, 6);
66
67 assertWeekIterator(it, start, end);
68 }
69 /**
70 * This checks that this is a 7 divisble iterator of Calendar objects
71 * that are dates (no time), and exactly 1 day spaced after each other
72 * (in addition to the proper start and stop dates)
73 */
74 private static void assertWeekIterator(final Iterator<?> it, final Calendar start, final Calendar end) {
75 Calendar cal = (Calendar) it.next();
76 assertCalendarsEquals("", start, cal, 0);
77 Calendar last = null;
78 int count = 1;
79 while (it.hasNext()) {
80 //Check this is just a date (no time component)
81 assertCalendarsEquals("", cal, DateUtils.truncate(cal, Calendar.DATE), 0);
82
83 last = cal;
84 cal = (Calendar) it.next();
85 count++;
86
87 //Check that this is one day more than the last date
88 last.add(Calendar.DATE, 1);
89 assertCalendarsEquals("", last, cal, 0);
90 }
91
92 assertFalse(count % 7 != 0, "There were " + count + " days in this iterator");
93 assertCalendarsEquals("", end, cal, 0);
94 }
95 /**
96 * Convenience method for when working with Date objects
97 */
98 private static void assertWeekIterator(final Iterator<?> it, final Date start, final Date end) {
99 final Calendar calStart = Calendar.getInstance();
100 calStart.setTime(start);
101 final Calendar calEnd = Calendar.getInstance();
102 calEnd.setTime(end);
103
104 assertWeekIterator(it, calStart, calEnd);
105 }
50106 @BeforeAll
51107 public static void classSetup() {
52108 final GregorianCalendar cal = new GregorianCalendar(2000, 6, 5, 4, 3, 2);
53109 cal.set(Calendar.MILLISECOND, 1);
54110 BASE_DATE = cal.getTime();
55111 }
56
57112 private DateFormat dateParser = null;
58113 private DateFormat dateTimeParser = null;
59114 private Date dateAmPm1 = null;
79134 private Calendar cal4 = null;
80135 private Calendar cal5 = null;
81136 private Calendar cal6 = null;
137
82138 private Calendar cal7 = null;
139
83140 private Calendar cal8 = null;
141
84142 private TimeZone zone = null;
143
85144 private TimeZone defaultZone = null;
145
146 //-----------------------------------------------------------------------
147 private void assertDate(final Date date, final int year, final int month, final int day, final int hour, final int min, final int sec, final int mil) {
148 final GregorianCalendar cal = new GregorianCalendar();
149 cal.setTime(date);
150 assertEquals(year, cal.get(Calendar.YEAR));
151 assertEquals(month, cal.get(Calendar.MONTH));
152 assertEquals(day, cal.get(Calendar.DAY_OF_MONTH));
153 assertEquals(hour, cal.get(Calendar.HOUR_OF_DAY));
154 assertEquals(min, cal.get(Calendar.MINUTE));
155 assertEquals(sec, cal.get(Calendar.SECOND));
156 assertEquals(mil, cal.get(Calendar.MILLISECOND));
157 }
86158
87159 @BeforeEach
88160 public void setUp() throws Exception {
144216
145217 //-----------------------------------------------------------------------
146218 @Test
219 public void testAddDays() throws Exception {
220 Date result = DateUtils.addDays(BASE_DATE, 0);
221 assertNotSame(BASE_DATE, result);
222 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
223 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
224
225 result = DateUtils.addDays(BASE_DATE, 1);
226 assertNotSame(BASE_DATE, result);
227 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
228 assertDate(result, 2000, 6, 6, 4, 3, 2, 1);
229
230 result = DateUtils.addDays(BASE_DATE, -1);
231 assertNotSame(BASE_DATE, result);
232 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
233 assertDate(result, 2000, 6, 4, 4, 3, 2, 1);
234 }
235
236 //-----------------------------------------------------------------------
237 @Test
238 public void testAddHours() throws Exception {
239 Date result = DateUtils.addHours(BASE_DATE, 0);
240 assertNotSame(BASE_DATE, result);
241 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
242 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
243
244 result = DateUtils.addHours(BASE_DATE, 1);
245 assertNotSame(BASE_DATE, result);
246 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
247 assertDate(result, 2000, 6, 5, 5, 3, 2, 1);
248
249 result = DateUtils.addHours(BASE_DATE, -1);
250 assertNotSame(BASE_DATE, result);
251 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
252 assertDate(result, 2000, 6, 5, 3, 3, 2, 1);
253 }
254
255 //-----------------------------------------------------------------------
256 @Test
257 public void testAddMilliseconds() throws Exception {
258 Date result = DateUtils.addMilliseconds(BASE_DATE, 0);
259 assertNotSame(BASE_DATE, result);
260 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
261 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
262
263 result = DateUtils.addMilliseconds(BASE_DATE, 1);
264 assertNotSame(BASE_DATE, result);
265 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
266 assertDate(result, 2000, 6, 5, 4, 3, 2, 2);
267
268 result = DateUtils.addMilliseconds(BASE_DATE, -1);
269 assertNotSame(BASE_DATE, result);
270 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
271 assertDate(result, 2000, 6, 5, 4, 3, 2, 0);
272 }
273
274 //-----------------------------------------------------------------------
275 @Test
276 public void testAddMinutes() throws Exception {
277 Date result = DateUtils.addMinutes(BASE_DATE, 0);
278 assertNotSame(BASE_DATE, result);
279 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
280 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
281
282 result = DateUtils.addMinutes(BASE_DATE, 1);
283 assertNotSame(BASE_DATE, result);
284 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
285 assertDate(result, 2000, 6, 5, 4, 4, 2, 1);
286
287 result = DateUtils.addMinutes(BASE_DATE, -1);
288 assertNotSame(BASE_DATE, result);
289 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
290 assertDate(result, 2000, 6, 5, 4, 2, 2, 1);
291 }
292
293 //-----------------------------------------------------------------------
294 @Test
295 public void testAddMonths() throws Exception {
296 Date result = DateUtils.addMonths(BASE_DATE, 0);
297 assertNotSame(BASE_DATE, result);
298 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
299 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
300
301 result = DateUtils.addMonths(BASE_DATE, 1);
302 assertNotSame(BASE_DATE, result);
303 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
304 assertDate(result, 2000, 7, 5, 4, 3, 2, 1);
305
306 result = DateUtils.addMonths(BASE_DATE, -1);
307 assertNotSame(BASE_DATE, result);
308 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
309 assertDate(result, 2000, 5, 5, 4, 3, 2, 1);
310 }
311
312 //-----------------------------------------------------------------------
313 @Test
314 public void testAddSeconds() throws Exception {
315 Date result = DateUtils.addSeconds(BASE_DATE, 0);
316 assertNotSame(BASE_DATE, result);
317 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
318 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
319
320 result = DateUtils.addSeconds(BASE_DATE, 1);
321 assertNotSame(BASE_DATE, result);
322 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
323 assertDate(result, 2000, 6, 5, 4, 3, 3, 1);
324
325 result = DateUtils.addSeconds(BASE_DATE, -1);
326 assertNotSame(BASE_DATE, result);
327 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
328 assertDate(result, 2000, 6, 5, 4, 3, 1, 1);
329 }
330
331 //-----------------------------------------------------------------------
332 @Test
333 public void testAddWeeks() throws Exception {
334 Date result = DateUtils.addWeeks(BASE_DATE, 0);
335 assertNotSame(BASE_DATE, result);
336 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
337 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
338
339 result = DateUtils.addWeeks(BASE_DATE, 1);
340 assertNotSame(BASE_DATE, result);
341 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
342 assertDate(result, 2000, 6, 12, 4, 3, 2, 1);
343
344 result = DateUtils.addWeeks(BASE_DATE, -1);
345 assertNotSame(BASE_DATE, result);
346 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1); // july
347 assertDate(result, 2000, 5, 28, 4, 3, 2, 1); // june
348 }
349
350 //-----------------------------------------------------------------------
351 @Test
352 public void testAddYears() throws Exception {
353 Date result = DateUtils.addYears(BASE_DATE, 0);
354 assertNotSame(BASE_DATE, result);
355 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
356 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
357
358 result = DateUtils.addYears(BASE_DATE, 1);
359 assertNotSame(BASE_DATE, result);
360 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
361 assertDate(result, 2001, 6, 5, 4, 3, 2, 1);
362
363 result = DateUtils.addYears(BASE_DATE, -1);
364 assertNotSame(BASE_DATE, result);
365 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
366 assertDate(result, 1999, 6, 5, 4, 3, 2, 1);
367 }
368
369 /**
370 * Tests various values with the ceiling method
371 *
372 * @throws java.lang.Exception so we don't have to catch it
373 */
374 @Test
375 public void testCeil() throws Exception {
376 // test javadoc
377 assertEquals(dateTimeParser.parse("March 28, 2002 14:00:00.000"),
378 DateUtils.ceiling(
379 dateTimeParser.parse("March 28, 2002 13:45:01.231"),
380 Calendar.HOUR),
381 "ceiling javadoc-1 failed");
382 assertEquals(dateTimeParser.parse("April 1, 2002 00:00:00.000"),
383 DateUtils.ceiling(
384 dateTimeParser.parse("March 28, 2002 13:45:01.231"),
385 Calendar.MONTH),
386 "ceiling javadoc-2 failed");
387
388 // tests public static Date ceiling(Date date, int field)
389 assertEquals(dateParser.parse("January 1, 2003"),
390 DateUtils.ceiling(date1, Calendar.YEAR),
391 "ceiling year-1 failed");
392 assertEquals(dateParser.parse("January 1, 2002"),
393 DateUtils.ceiling(date2, Calendar.YEAR),
394 "ceiling year-2 failed");
395 assertEquals(dateParser.parse("March 1, 2002"),
396 DateUtils.ceiling(date1, Calendar.MONTH),
397 "ceiling month-1 failed");
398 assertEquals(dateParser.parse("December 1, 2001"),
399 DateUtils.ceiling(date2, Calendar.MONTH),
400 "ceiling month-2 failed");
401 assertEquals(dateParser.parse("February 16, 2002"),
402 DateUtils.ceiling(date1, DateUtils.SEMI_MONTH),
403 "ceiling semimonth-1 failed");
404 assertEquals(dateParser.parse("December 1, 2001"),
405 DateUtils.ceiling(date2, DateUtils.SEMI_MONTH),
406 "ceiling semimonth-2 failed");
407 assertEquals(dateParser.parse("February 13, 2002"),
408 DateUtils.ceiling(date1, Calendar.DATE),
409 "ceiling date-1 failed");
410 assertEquals(dateParser.parse("November 19, 2001"),
411 DateUtils.ceiling(date2, Calendar.DATE),
412 "ceiling date-2 failed");
413 assertEquals(dateTimeParser.parse("February 12, 2002 13:00:00.000"),
414 DateUtils.ceiling(date1, Calendar.HOUR),
415 "ceiling hour-1 failed");
416 assertEquals(dateTimeParser.parse("November 18, 2001 2:00:00.000"),
417 DateUtils.ceiling(date2, Calendar.HOUR),
418 "ceiling hour-2 failed");
419 assertEquals(dateTimeParser.parse("February 12, 2002 12:35:00.000"),
420 DateUtils.ceiling(date1, Calendar.MINUTE),
421 "ceiling minute-1 failed");
422 assertEquals(dateTimeParser.parse("November 18, 2001 1:24:00.000"),
423 DateUtils.ceiling(date2, Calendar.MINUTE),
424 "ceiling minute-2 failed");
425 assertEquals(dateTimeParser.parse("February 12, 2002 12:34:57.000"),
426 DateUtils.ceiling(date1, Calendar.SECOND),
427 "ceiling second-1 failed");
428 assertEquals(dateTimeParser.parse("November 18, 2001 1:23:12.000"),
429 DateUtils.ceiling(date2, Calendar.SECOND),
430 "ceiling second-2 failed");
431 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
432 DateUtils.ceiling(dateAmPm1, Calendar.AM_PM),
433 "ceiling ampm-1 failed");
434 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
435 DateUtils.ceiling(dateAmPm2, Calendar.AM_PM),
436 "ceiling ampm-2 failed");
437 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
438 DateUtils.ceiling(dateAmPm3, Calendar.AM_PM),
439 "ceiling ampm-3 failed");
440 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
441 DateUtils.ceiling(dateAmPm4, Calendar.AM_PM),
442 "ceiling ampm-4 failed");
443
444 // tests public static Date ceiling(Object date, int field)
445 assertEquals(dateParser.parse("January 1, 2003"),
446 DateUtils.ceiling((Object) date1, Calendar.YEAR),
447 "ceiling year-1 failed");
448 assertEquals(dateParser.parse("January 1, 2002"),
449 DateUtils.ceiling((Object) date2, Calendar.YEAR),
450 "ceiling year-2 failed");
451 assertEquals(dateParser.parse("March 1, 2002"),
452 DateUtils.ceiling((Object) date1, Calendar.MONTH),
453 "ceiling month-1 failed");
454 assertEquals(dateParser.parse("December 1, 2001"),
455 DateUtils.ceiling((Object) date2, Calendar.MONTH),
456 "ceiling month-2 failed");
457 assertEquals(dateParser.parse("February 16, 2002"),
458 DateUtils.ceiling((Object) date1, DateUtils.SEMI_MONTH),
459 "ceiling semimonth-1 failed");
460 assertEquals(dateParser.parse("December 1, 2001"),
461 DateUtils.ceiling((Object) date2, DateUtils.SEMI_MONTH),
462 "ceiling semimonth-2 failed");
463 assertEquals(dateParser.parse("February 13, 2002"),
464 DateUtils.ceiling((Object) date1, Calendar.DATE),
465 "ceiling date-1 failed");
466 assertEquals(dateParser.parse("November 19, 2001"),
467 DateUtils.ceiling((Object) date2, Calendar.DATE),
468 "ceiling date-2 failed");
469 assertEquals(dateTimeParser.parse("February 12, 2002 13:00:00.000"),
470 DateUtils.ceiling((Object) date1, Calendar.HOUR),
471 "ceiling hour-1 failed");
472 assertEquals(dateTimeParser.parse("November 18, 2001 2:00:00.000"),
473 DateUtils.ceiling((Object) date2, Calendar.HOUR),
474 "ceiling hour-2 failed");
475 assertEquals(dateTimeParser.parse("February 12, 2002 12:35:00.000"),
476 DateUtils.ceiling((Object) date1, Calendar.MINUTE),
477 "ceiling minute-1 failed");
478 assertEquals(dateTimeParser.parse("November 18, 2001 1:24:00.000"),
479 DateUtils.ceiling((Object) date2, Calendar.MINUTE),
480 "ceiling minute-2 failed");
481 assertEquals(dateTimeParser.parse("February 12, 2002 12:34:57.000"),
482 DateUtils.ceiling((Object) date1, Calendar.SECOND),
483 "ceiling second-1 failed");
484 assertEquals(dateTimeParser.parse("November 18, 2001 1:23:12.000"),
485 DateUtils.ceiling((Object) date2, Calendar.SECOND),
486 "ceiling second-2 failed");
487 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
488 DateUtils.ceiling((Object) dateAmPm1, Calendar.AM_PM),
489 "ceiling ampm-1 failed");
490 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
491 DateUtils.ceiling((Object) dateAmPm2, Calendar.AM_PM),
492 "ceiling ampm-2 failed");
493 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
494 DateUtils.ceiling((Object) dateAmPm3, Calendar.AM_PM),
495 "ceiling ampm-3 failed");
496 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
497 DateUtils.ceiling((Object) dateAmPm4, Calendar.AM_PM),
498 "ceiling ampm-4 failed");
499
500 assertEquals(dateTimeParser.parse("February 12, 2002 12:34:57.000"),
501 DateUtils.ceiling((Object) cal1, Calendar.SECOND),
502 "ceiling calendar second-1 failed");
503 assertEquals(dateTimeParser.parse("November 18, 2001 1:23:12.000"),
504 DateUtils.ceiling((Object) cal2, Calendar.SECOND),
505 "ceiling calendar second-2 failed");
506
507 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
508 DateUtils.ceiling((Object) calAmPm1, Calendar.AM_PM),
509 "ceiling ampm-1 failed");
510 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
511 DateUtils.ceiling((Object) calAmPm2, Calendar.AM_PM),
512 "ceiling ampm-2 failed");
513 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
514 DateUtils.ceiling((Object) calAmPm3, Calendar.AM_PM),
515 "ceiling ampm-3 failed");
516 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
517 DateUtils.ceiling((Object) calAmPm4, Calendar.AM_PM),
518 "ceiling ampm-4 failed");
519
520 assertThrows(NullPointerException.class, () -> DateUtils.ceiling((Date) null, Calendar.SECOND));
521 assertThrows(IllegalArgumentException.class, () -> DateUtils.ceiling((Calendar) null, Calendar.SECOND));
522 assertThrows(IllegalArgumentException.class, () -> DateUtils.ceiling((Object) null, Calendar.SECOND));
523 assertThrows(ClassCastException.class, () -> DateUtils.ceiling("", Calendar.SECOND));
524 assertThrows(IllegalArgumentException.class, () -> DateUtils.ceiling(date1, -9999));
525
526 // Fix for https://issues.apache.org/bugzilla/show_bug.cgi?id=25560
527 // Test ceiling across the beginning of daylight saving time
528 try {
529 TimeZone.setDefault(zone);
530 dateTimeParser.setTimeZone(zone);
531
532 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
533 DateUtils.ceiling(date4, Calendar.DATE),
534 "ceiling MET date across DST change-over");
535 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
536 DateUtils.ceiling((Object) cal4, Calendar.DATE),
537 "ceiling MET date across DST change-over");
538 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
539 DateUtils.ceiling(date5, Calendar.DATE),
540 "ceiling MET date across DST change-over");
541 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
542 DateUtils.ceiling((Object) cal5, Calendar.DATE),
543 "ceiling MET date across DST change-over");
544 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
545 DateUtils.ceiling(date6, Calendar.DATE),
546 "ceiling MET date across DST change-over");
547 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
548 DateUtils.ceiling((Object) cal6, Calendar.DATE),
549 "ceiling MET date across DST change-over");
550 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
551 DateUtils.ceiling(date7, Calendar.DATE),
552 "ceiling MET date across DST change-over");
553 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
554 DateUtils.ceiling((Object) cal7, Calendar.DATE),
555 "ceiling MET date across DST change-over");
556
557 assertEquals(dateTimeParser.parse("March 30, 2003 03:00:00.000"),
558 DateUtils.ceiling(date4, Calendar.HOUR_OF_DAY),
559 "ceiling MET date across DST change-over");
560 assertEquals(dateTimeParser.parse("March 30, 2003 03:00:00.000"),
561 DateUtils.ceiling((Object) cal4, Calendar.HOUR_OF_DAY),
562 "ceiling MET date across DST change-over");
563 assertEquals(dateTimeParser.parse("March 30, 2003 03:00:00.000"),
564 DateUtils.ceiling(date5, Calendar.HOUR_OF_DAY),
565 "ceiling MET date across DST change-over");
566 assertEquals(dateTimeParser.parse("March 30, 2003 03:00:00.000"),
567 DateUtils.ceiling((Object) cal5, Calendar.HOUR_OF_DAY),
568 "ceiling MET date across DST change-over");
569 assertEquals(dateTimeParser.parse("March 30, 2003 04:00:00.000"),
570 DateUtils.ceiling(date6, Calendar.HOUR_OF_DAY),
571 "ceiling MET date across DST change-over");
572 assertEquals(dateTimeParser.parse("March 30, 2003 04:00:00.000"),
573 DateUtils.ceiling((Object) cal6, Calendar.HOUR_OF_DAY),
574 "ceiling MET date across DST change-over");
575 assertEquals(dateTimeParser.parse("March 30, 2003 04:00:00.000"),
576 DateUtils.ceiling(date7, Calendar.HOUR_OF_DAY),
577 "ceiling MET date across DST change-over");
578 assertEquals(dateTimeParser.parse("March 30, 2003 04:00:00.000"),
579 DateUtils.ceiling((Object) cal7, Calendar.HOUR_OF_DAY),
580 "ceiling MET date across DST change-over");
581
582 } finally {
583 TimeZone.setDefault(defaultZone);
584 dateTimeParser.setTimeZone(defaultZone);
585 }
586
587 // Bug 31395, large dates
588 final Date endOfTime = new Date(Long.MAX_VALUE); // fyi: Sun Aug 17 07:12:55 CET 292278994 -- 807 millis
589 final GregorianCalendar endCal = new GregorianCalendar();
590 endCal.setTime(endOfTime);
591 assertThrows(ArithmeticException.class, () -> DateUtils.ceiling(endCal, Calendar.DATE));
592 endCal.set(Calendar.YEAR, 280000001);
593 assertThrows(ArithmeticException.class, () -> DateUtils.ceiling(endCal, Calendar.DATE));
594 endCal.set(Calendar.YEAR, 280000000);
595 final Calendar cal = DateUtils.ceiling(endCal, Calendar.DATE);
596 assertEquals(0, cal.get(Calendar.HOUR));
597 }
598
599 //-----------------------------------------------------------------------
600 @Test
147601 public void testConstructor() {
148602 assertNotNull(new DateUtils());
149603 final Constructor<?>[] cons = DateUtils.class.getDeclaredConstructors();
151605 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
152606 assertTrue(Modifier.isPublic(DateUtils.class.getModifiers()));
153607 assertFalse(Modifier.isFinal(DateUtils.class.getModifiers()));
608 }
609
610 //-----------------------------------------------------------------------
611 @Test
612 public void testIsSameDay_Cal() {
613 final GregorianCalendar cala = new GregorianCalendar(2004, 6, 9, 13, 45);
614 final GregorianCalendar calb = new GregorianCalendar(2004, 6, 9, 13, 45);
615 assertTrue(DateUtils.isSameDay(cala, calb));
616 calb.add(Calendar.DAY_OF_YEAR, 1);
617 assertFalse(DateUtils.isSameDay(cala, calb));
618 cala.add(Calendar.DAY_OF_YEAR, 1);
619 assertTrue(DateUtils.isSameDay(cala, calb));
620 calb.add(Calendar.YEAR, 1);
621 assertFalse(DateUtils.isSameDay(cala, calb));
622 }
623
624 @Test
625 public void testIsSameDay_CalNotNullNull() {
626 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameDay(Calendar.getInstance(), null));
627 }
628
629 @Test
630 public void testIsSameDay_CalNullNotNull() {
631 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameDay(null, Calendar.getInstance()));
632 }
633
634 @Test
635 public void testIsSameDay_CalNullNull() {
636 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameDay((Calendar) null, null));
154637 }
155638
156639 //-----------------------------------------------------------------------
168651 }
169652
170653 @Test
654 public void testIsSameDay_DateNotNullNull() {
655 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameDay(new Date(), null));
656 }
657
658 @Test
659 public void testIsSameDay_DateNullNotNull() {
660 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameDay(null, new Date()));
661 }
662
663 @Test
171664 public void testIsSameDay_DateNullNull() {
172665 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameDay((Date) null, null));
173666 }
174667
175 @Test
176 public void testIsSameDay_DateNullNotNull() {
177 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameDay(null, new Date()));
178 }
179
180 @Test
181 public void testIsSameDay_DateNotNullNull() {
182 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameDay(new Date(), null));
183 }
184
185 //-----------------------------------------------------------------------
186 @Test
187 public void testIsSameDay_Cal() {
188 final GregorianCalendar cala = new GregorianCalendar(2004, 6, 9, 13, 45);
189 final GregorianCalendar calb = new GregorianCalendar(2004, 6, 9, 13, 45);
190 assertTrue(DateUtils.isSameDay(cala, calb));
191 calb.add(Calendar.DAY_OF_YEAR, 1);
192 assertFalse(DateUtils.isSameDay(cala, calb));
193 cala.add(Calendar.DAY_OF_YEAR, 1);
194 assertTrue(DateUtils.isSameDay(cala, calb));
195 calb.add(Calendar.YEAR, 1);
196 assertFalse(DateUtils.isSameDay(cala, calb));
197 }
198
199 @Test
200 public void testIsSameDay_CalNullNull() {
201 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameDay((Calendar) null, null));
202 }
203
204 @Test
205 public void testIsSameDay_CalNullNotNull() {
206 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameDay(null, Calendar.getInstance()));
207 }
208
209 @Test
210 public void testIsSameDay_CalNotNullNull() {
211 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameDay(Calendar.getInstance(), null));
668 //-----------------------------------------------------------------------
669 @Test
670 public void testIsSameInstant_Cal() {
671 final GregorianCalendar cala = new GregorianCalendar(TimeZone.getTimeZone("GMT+1"));
672 final GregorianCalendar calb = new GregorianCalendar(TimeZone.getTimeZone("GMT-1"));
673 cala.set(2004, Calendar.JULY, 9, 13, 45, 0);
674 cala.set(Calendar.MILLISECOND, 0);
675 calb.set(2004, Calendar.JULY, 9, 13, 45, 0);
676 calb.set(Calendar.MILLISECOND, 0);
677 assertFalse(DateUtils.isSameInstant(cala, calb));
678
679 calb.set(2004, Calendar.JULY, 9, 11, 45, 0);
680 assertTrue(DateUtils.isSameInstant(cala, calb));
681 }
682
683 @Test
684 public void testIsSameInstant_CalNotNullNull() {
685 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameInstant(Calendar.getInstance(), null));
686 }
687
688 @Test
689 public void testIsSameInstant_CalNullNotNull() {
690 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameInstant(null, Calendar.getInstance()));
691 }
692
693 @Test
694 public void testIsSameInstant_CalNullNull() {
695 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameInstant((Calendar) null, null));
212696 }
213697
214698 //-----------------------------------------------------------------------
226710 }
227711
228712 @Test
713 public void testIsSameInstant_DateNotNullNull() {
714 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameInstant(new Date(), null));
715 }
716
717 @Test
718 public void testIsSameInstant_DateNullNotNull() {
719 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameInstant(null, new Date()));
720 }
721
722 @Test
229723 public void testIsSameInstant_DateNullNull() {
230724 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameInstant((Date) null, null));
231 }
232
233 @Test
234 public void testIsSameInstant_DateNullNotNull() {
235 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameInstant(null, new Date()));
236 }
237
238 @Test
239 public void testIsSameInstant_DateNotNullNull() {
240 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameInstant(new Date(), null));
241 }
242
243 //-----------------------------------------------------------------------
244 @Test
245 public void testIsSameInstant_Cal() {
246 final GregorianCalendar cala = new GregorianCalendar(TimeZone.getTimeZone("GMT+1"));
247 final GregorianCalendar calb = new GregorianCalendar(TimeZone.getTimeZone("GMT-1"));
248 cala.set(2004, Calendar.JULY, 9, 13, 45, 0);
249 cala.set(Calendar.MILLISECOND, 0);
250 calb.set(2004, Calendar.JULY, 9, 13, 45, 0);
251 calb.set(Calendar.MILLISECOND, 0);
252 assertFalse(DateUtils.isSameInstant(cala, calb));
253
254 calb.set(2004, Calendar.JULY, 9, 11, 45, 0);
255 assertTrue(DateUtils.isSameInstant(cala, calb));
256 }
257
258 @Test
259 public void testIsSameInstant_CalNullNull() {
260 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameInstant((Calendar) null, null));
261 }
262
263 @Test
264 public void testIsSameInstant_CalNullNotNull() {
265 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameInstant(null, Calendar.getInstance()));
266 }
267
268 @Test
269 public void testIsSameInstant_CalNotNullNull() {
270 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameInstant(Calendar.getInstance(), null));
271725 }
272726
273727 //-----------------------------------------------------------------------
294748 }
295749
296750 @Test
751 public void testIsSameLocalTime_CalNotNullNull() {
752 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameLocalTime(Calendar.getInstance(), null));
753 }
754
755 @Test
756 public void testIsSameLocalTime_CalNullNotNull() {
757 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameLocalTime(null, Calendar.getInstance()));
758 }
759
760 @Test
297761 public void testIsSameLocalTime_CalNullNull() {
298762 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameLocalTime(null, null));
299763 }
300764
301 @Test
302 public void testIsSameLocalTime_CalNullNotNull() {
303 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameLocalTime(null, Calendar.getInstance()));
304 }
305
306 @Test
307 public void testIsSameLocalTime_CalNotNullNull() {
308 assertThrows(IllegalArgumentException.class, () -> DateUtils.isSameLocalTime(Calendar.getInstance(), null));
765 /**
766 * Tests the iterator exceptions
767 */
768 @Test
769 public void testIteratorEx() {
770 assertThrows(IllegalArgumentException.class, () -> DateUtils.iterator(Calendar.getInstance(), -9999));
771 assertThrows
772 (NullPointerException.class, () -> DateUtils.iterator((Date) null, DateUtils.RANGE_WEEK_CENTER));
773 assertThrows
774 (IllegalArgumentException.class, () -> DateUtils.iterator((Calendar) null, DateUtils.RANGE_WEEK_CENTER));
775 assertThrows
776 (IllegalArgumentException.class, () -> DateUtils.iterator((Object) null, DateUtils.RANGE_WEEK_CENTER));
777 assertThrows(ClassCastException.class, () -> DateUtils.iterator("", DateUtils.RANGE_WEEK_CENTER));
778 }
779
780 // https://issues.apache.org/jira/browse/LANG-530
781 @SuppressWarnings("deprecation")
782 @Test
783 public void testLang530() throws ParseException {
784 final Date d = new Date();
785 final String isoDateStr = DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(d);
786 final Date d2 = DateUtils.parseDate(isoDateStr, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern());
787 // the format loses milliseconds so have to reintroduce them
788 assertEquals(d.getTime(), d2.getTime() + d.getTime() % 1000, "Date not equal to itself ISO formatted and parsed");
789 }
790
791 @Test
792 public void testLANG799() throws ParseException {
793 DateUtils.parseDateStrictly("09 abril 2008 23:55:38 GMT", new Locale("es"), "dd MMM yyyy HH:mm:ss zzz");
794 }
795
796 // Parse English date with German Locale
797 @DefaultLocale(language = "de")
798 @Test
799 public void testLANG799_DE_FAIL() {
800 assertThrows(ParseException.class, () -> DateUtils.parseDate("Wed, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz"));
801 }
802
803 @DefaultLocale(language = "de")
804 @Test
805 public void testLANG799_DE_OK() throws ParseException {
806 DateUtils.parseDate("Mi, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz");
807 DateUtils.parseDateStrictly("Mi, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz");
808 }
809
810 // Parse German date with English Locale
811 @DefaultLocale(language = "en")
812 @Test
813 public void testLANG799_EN_FAIL() {
814 assertThrows(ParseException.class, () -> DateUtils.parseDate("Mi, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz"));
815 }
816
817 @DefaultLocale(language = "en")
818 @Test
819 public void testLANG799_EN_OK() throws ParseException {
820 DateUtils.parseDate("Wed, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz");
821 DateUtils.parseDateStrictly("Wed, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz");
822 }
823
824 // Parse German date with English Locale, specifying German Locale override
825 @DefaultLocale(language = "en")
826 @Test
827 public void testLANG799_EN_WITH_DE_LOCALE() throws ParseException {
828 DateUtils.parseDate("Mi, 09 Apr 2008 23:55:38 GMT", Locale.GERMAN, "EEE, dd MMM yyyy HH:mm:ss zzz");
829 }
830
831 /**
832 * Tests the calendar iterator for month-based ranges
833 *
834 * @throws java.lang.Exception so we don't have to catch it
835 */
836 @Test
837 public void testMonthIterator() throws Exception {
838 Iterator<?> it = DateUtils.iterator(date1, DateUtils.RANGE_MONTH_SUNDAY);
839 assertWeekIterator(it,
840 dateParser.parse("January 27, 2002"),
841 dateParser.parse("March 2, 2002"));
842
843 it = DateUtils.iterator(date1, DateUtils.RANGE_MONTH_MONDAY);
844 assertWeekIterator(it,
845 dateParser.parse("January 28, 2002"),
846 dateParser.parse("March 3, 2002"));
847
848 it = DateUtils.iterator(date2, DateUtils.RANGE_MONTH_SUNDAY);
849 assertWeekIterator(it,
850 dateParser.parse("October 28, 2001"),
851 dateParser.parse("December 1, 2001"));
852
853 it = DateUtils.iterator(date2, DateUtils.RANGE_MONTH_MONDAY);
854 assertWeekIterator(it,
855 dateParser.parse("October 29, 2001"),
856 dateParser.parse("December 2, 2001"));
857 }
858
859 @Test
860 public void testParse_EmptyParsers() {
861 assertThrows(ParseException.class, () -> DateUtils.parseDate("19721203"));
862 }
863
864 @Test
865 public void testParse_NullParsers() {
866 assertThrows(IllegalArgumentException.class, () -> DateUtils.parseDate("19721203", (String[]) null));
309867 }
310868
311869 //-----------------------------------------------------------------------
327885 }
328886
329887 @Test
888 public void testParseDate_InvalidDateString() {
889 final String[] parsers = new String[] {"yyyy'-'DDD", "yyyy'-'MM'-'dd", "yyyyMMdd"};
890 assertThrows(ParseException.class, () -> DateUtils.parseDate("197212AB", parsers));
891 }
892
893 @Test
330894 public void testParseDate_NoDateString() {
331895 final String[] parsers = new String[] {"yyyy'-'DDD", "yyyy'-'MM'-'dd", "yyyyMMdd"};
332896 assertThrows(ParseException.class, () -> DateUtils.parseDate("PURPLE", parsers));
333897 }
334898
335899 @Test
336 public void testParseDate_InvalidDateString() {
337 final String[] parsers = new String[] {"yyyy'-'DDD", "yyyy'-'MM'-'dd", "yyyyMMdd"};
338 assertThrows(ParseException.class, () -> DateUtils.parseDate("197212AB", parsers));
339 }
340
341 @Test
342900 public void testParseDate_Null() {
343901 final String[] parsers = new String[] {"yyyy'-'DDD", "yyyy'-'MM'-'dd", "yyyyMMdd"};
344902 assertThrows(IllegalArgumentException.class, () -> DateUtils.parseDate(null, parsers));
345 }
346
347 @Test
348 public void testParse_NullParsers() {
349 assertThrows(IllegalArgumentException.class, () -> DateUtils.parseDate("19721203", (String[]) null));
350 }
351
352 @Test
353 public void testParse_EmptyParsers() {
354 assertThrows(ParseException.class, () -> DateUtils.parseDate("19721203"));
355903 }
356904
357905 // LANG-486
365913 assertEquals(cal.getTime(), date);
366914
367915 assertThrows(ParseException.class, () -> DateUtils.parseDateStrictly(dateStr, parsers));
368 }
369
370 //-----------------------------------------------------------------------
371 @Test
372 public void testAddYears() throws Exception {
373 Date result = DateUtils.addYears(BASE_DATE, 0);
374 assertNotSame(BASE_DATE, result);
375 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
376 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
377
378 result = DateUtils.addYears(BASE_DATE, 1);
379 assertNotSame(BASE_DATE, result);
380 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
381 assertDate(result, 2001, 6, 5, 4, 3, 2, 1);
382
383 result = DateUtils.addYears(BASE_DATE, -1);
384 assertNotSame(BASE_DATE, result);
385 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
386 assertDate(result, 1999, 6, 5, 4, 3, 2, 1);
387 }
388
389 //-----------------------------------------------------------------------
390 @Test
391 public void testAddMonths() throws Exception {
392 Date result = DateUtils.addMonths(BASE_DATE, 0);
393 assertNotSame(BASE_DATE, result);
394 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
395 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
396
397 result = DateUtils.addMonths(BASE_DATE, 1);
398 assertNotSame(BASE_DATE, result);
399 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
400 assertDate(result, 2000, 7, 5, 4, 3, 2, 1);
401
402 result = DateUtils.addMonths(BASE_DATE, -1);
403 assertNotSame(BASE_DATE, result);
404 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
405 assertDate(result, 2000, 5, 5, 4, 3, 2, 1);
406 }
407
408 //-----------------------------------------------------------------------
409 @Test
410 public void testAddWeeks() throws Exception {
411 Date result = DateUtils.addWeeks(BASE_DATE, 0);
412 assertNotSame(BASE_DATE, result);
413 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
414 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
415
416 result = DateUtils.addWeeks(BASE_DATE, 1);
417 assertNotSame(BASE_DATE, result);
418 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
419 assertDate(result, 2000, 6, 12, 4, 3, 2, 1);
420
421 result = DateUtils.addWeeks(BASE_DATE, -1);
422 assertNotSame(BASE_DATE, result);
423 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1); // july
424 assertDate(result, 2000, 5, 28, 4, 3, 2, 1); // june
425 }
426
427 //-----------------------------------------------------------------------
428 @Test
429 public void testAddDays() throws Exception {
430 Date result = DateUtils.addDays(BASE_DATE, 0);
431 assertNotSame(BASE_DATE, result);
432 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
433 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
434
435 result = DateUtils.addDays(BASE_DATE, 1);
436 assertNotSame(BASE_DATE, result);
437 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
438 assertDate(result, 2000, 6, 6, 4, 3, 2, 1);
439
440 result = DateUtils.addDays(BASE_DATE, -1);
441 assertNotSame(BASE_DATE, result);
442 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
443 assertDate(result, 2000, 6, 4, 4, 3, 2, 1);
444 }
445
446 //-----------------------------------------------------------------------
447 @Test
448 public void testAddHours() throws Exception {
449 Date result = DateUtils.addHours(BASE_DATE, 0);
450 assertNotSame(BASE_DATE, result);
451 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
452 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
453
454 result = DateUtils.addHours(BASE_DATE, 1);
455 assertNotSame(BASE_DATE, result);
456 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
457 assertDate(result, 2000, 6, 5, 5, 3, 2, 1);
458
459 result = DateUtils.addHours(BASE_DATE, -1);
460 assertNotSame(BASE_DATE, result);
461 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
462 assertDate(result, 2000, 6, 5, 3, 3, 2, 1);
463 }
464
465 //-----------------------------------------------------------------------
466 @Test
467 public void testAddMinutes() throws Exception {
468 Date result = DateUtils.addMinutes(BASE_DATE, 0);
469 assertNotSame(BASE_DATE, result);
470 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
471 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
472
473 result = DateUtils.addMinutes(BASE_DATE, 1);
474 assertNotSame(BASE_DATE, result);
475 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
476 assertDate(result, 2000, 6, 5, 4, 4, 2, 1);
477
478 result = DateUtils.addMinutes(BASE_DATE, -1);
479 assertNotSame(BASE_DATE, result);
480 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
481 assertDate(result, 2000, 6, 5, 4, 2, 2, 1);
482 }
483
484 //-----------------------------------------------------------------------
485 @Test
486 public void testAddSeconds() throws Exception {
487 Date result = DateUtils.addSeconds(BASE_DATE, 0);
488 assertNotSame(BASE_DATE, result);
489 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
490 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
491
492 result = DateUtils.addSeconds(BASE_DATE, 1);
493 assertNotSame(BASE_DATE, result);
494 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
495 assertDate(result, 2000, 6, 5, 4, 3, 3, 1);
496
497 result = DateUtils.addSeconds(BASE_DATE, -1);
498 assertNotSame(BASE_DATE, result);
499 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
500 assertDate(result, 2000, 6, 5, 4, 3, 1, 1);
501 }
502
503 //-----------------------------------------------------------------------
504 @Test
505 public void testAddMilliseconds() throws Exception {
506 Date result = DateUtils.addMilliseconds(BASE_DATE, 0);
507 assertNotSame(BASE_DATE, result);
508 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
509 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
510
511 result = DateUtils.addMilliseconds(BASE_DATE, 1);
512 assertNotSame(BASE_DATE, result);
513 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
514 assertDate(result, 2000, 6, 5, 4, 3, 2, 2);
515
516 result = DateUtils.addMilliseconds(BASE_DATE, -1);
517 assertNotSame(BASE_DATE, result);
518 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
519 assertDate(result, 2000, 6, 5, 4, 3, 2, 0);
520 }
521
522 // -----------------------------------------------------------------------
523 @Test
524 public void testSetYears() throws Exception {
525 Date result = DateUtils.setYears(BASE_DATE, 2000);
526 assertNotSame(BASE_DATE, result);
527 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
528 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
529
530 result = DateUtils.setYears(BASE_DATE, 2008);
531 assertNotSame(BASE_DATE, result);
532 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
533 assertDate(result, 2008, 6, 5, 4, 3, 2, 1);
534
535 result = DateUtils.setYears(BASE_DATE, 2005);
536 assertNotSame(BASE_DATE, result);
537 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
538 assertDate(result, 2005, 6, 5, 4, 3, 2, 1);
539 }
540
541 // -----------------------------------------------------------------------
542 @Test
543 public void testSetMonths() throws Exception {
544 Date result = DateUtils.setMonths(BASE_DATE, 5);
545 assertNotSame(BASE_DATE, result);
546 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
547 assertDate(result, 2000, 5, 5, 4, 3, 2, 1);
548
549 result = DateUtils.setMonths(BASE_DATE, 1);
550 assertNotSame(BASE_DATE, result);
551 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
552 assertDate(result, 2000, 1, 5, 4, 3, 2, 1);
553
554 assertThrows(
555 IllegalArgumentException.class,
556 () -> DateUtils.setMonths(BASE_DATE, 12),
557 "DateUtils.setMonths did not throw an expected IllegalArgumentException.");
558 }
559
560 // -----------------------------------------------------------------------
561 @Test
562 public void testSetDays() throws Exception {
563 Date result = DateUtils.setDays(BASE_DATE, 1);
564 assertNotSame(BASE_DATE, result);
565 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
566 assertDate(result, 2000, 6, 1, 4, 3, 2, 1);
567
568 result = DateUtils.setDays(BASE_DATE, 29);
569 assertNotSame(BASE_DATE, result);
570 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
571 assertDate(result, 2000, 6, 29, 4, 3, 2, 1);
572
573 assertThrows(
574 IllegalArgumentException.class,
575 () -> DateUtils.setDays(BASE_DATE, 32),
576 "DateUtils.setDays did not throw an expected IllegalArgumentException.");
577 }
578
579 // -----------------------------------------------------------------------
580 @Test
581 public void testSetHours() throws Exception {
582 Date result = DateUtils.setHours(BASE_DATE, 0);
583 assertNotSame(BASE_DATE, result);
584 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
585 assertDate(result, 2000, 6, 5, 0, 3, 2, 1);
586
587 result = DateUtils.setHours(BASE_DATE, 23);
588 assertNotSame(BASE_DATE, result);
589 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
590 assertDate(result, 2000, 6, 5, 23, 3, 2, 1);
591
592 assertThrows(
593 IllegalArgumentException.class,
594 () -> DateUtils.setHours(BASE_DATE, 24),
595 "DateUtils.setHours did not throw an expected IllegalArgumentException.");
596 }
597
598 // -----------------------------------------------------------------------
599 @Test
600 public void testSetMinutes() throws Exception {
601 Date result = DateUtils.setMinutes(BASE_DATE, 0);
602 assertNotSame(BASE_DATE, result);
603 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
604 assertDate(result, 2000, 6, 5, 4, 0, 2, 1);
605
606 result = DateUtils.setMinutes(BASE_DATE, 59);
607 assertNotSame(BASE_DATE, result);
608 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
609 assertDate(result, 2000, 6, 5, 4, 59, 2, 1);
610
611 assertThrows(
612 IllegalArgumentException.class,
613 () -> DateUtils.setMinutes(BASE_DATE, 60),
614 "DateUtils.setMinutes did not throw an expected IllegalArgumentException.");
615 }
616
617 // -----------------------------------------------------------------------
618 @Test
619 public void testSetSeconds() throws Exception {
620 Date result = DateUtils.setSeconds(BASE_DATE, 0);
621 assertNotSame(BASE_DATE, result);
622 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
623 assertDate(result, 2000, 6, 5, 4, 3, 0, 1);
624
625 result = DateUtils.setSeconds(BASE_DATE, 59);
626 assertNotSame(BASE_DATE, result);
627 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
628 assertDate(result, 2000, 6, 5, 4, 3, 59, 1);
629
630 assertThrows(
631 IllegalArgumentException.class,
632 () -> DateUtils.setSeconds(BASE_DATE, 60),
633 "DateUtils.setSeconds did not throw an expected IllegalArgumentException.");
634 }
635
636 // -----------------------------------------------------------------------
637 @Test
638 public void testSetMilliseconds() throws Exception {
639 Date result = DateUtils.setMilliseconds(BASE_DATE, 0);
640 assertNotSame(BASE_DATE, result);
641 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
642 assertDate(result, 2000, 6, 5, 4, 3, 2, 0);
643
644 result = DateUtils.setMilliseconds(BASE_DATE, 999);
645 assertNotSame(BASE_DATE, result);
646 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
647 assertDate(result, 2000, 6, 5, 4, 3, 2, 999);
648
649 assertThrows(
650 IllegalArgumentException.class,
651 () -> DateUtils.setMilliseconds(BASE_DATE, 1000),
652 "DateUtils.setMilliseconds did not throw an expected IllegalArgumentException.");
653 }
654
655 //-----------------------------------------------------------------------
656 private void assertDate(final Date date, final int year, final int month, final int day, final int hour, final int min, final int sec, final int mil) {
657 final GregorianCalendar cal = new GregorianCalendar();
658 cal.setTime(date);
659 assertEquals(year, cal.get(Calendar.YEAR));
660 assertEquals(month, cal.get(Calendar.MONTH));
661 assertEquals(day, cal.get(Calendar.DAY_OF_MONTH));
662 assertEquals(hour, cal.get(Calendar.HOUR_OF_DAY));
663 assertEquals(min, cal.get(Calendar.MINUTE));
664 assertEquals(sec, cal.get(Calendar.SECOND));
665 assertEquals(mil, cal.get(Calendar.MILLISECOND));
666 }
667
668 //-----------------------------------------------------------------------
669 @Test
670 public void testToCalendar() {
671 assertEquals(date1, DateUtils.toCalendar(date1).getTime(), "Failed to convert to a Calendar and back");
672 assertThrows(NullPointerException.class, () -> DateUtils.toCalendar(null));
673 }
674
675 //-----------------------------------------------------------------------
676 @Test
677 public void testToCalendarWithDateNull() {
678 assertThrows(NullPointerException.class, () -> DateUtils.toCalendar(null, zone));
679 }
680
681 //-----------------------------------------------------------------------
682 @Test
683 public void testToCalendarWithTimeZoneNull() {
684 assertThrows(NullPointerException.class, () -> DateUtils.toCalendar(date1, null));
685 }
686
687 //-----------------------------------------------------------------------
688 @Test
689 public void testToCalendarWithDateAndTimeZoneNotNull() {
690 final Calendar c = DateUtils.toCalendar(date2, defaultZone);
691 assertEquals(date2, c.getTime(), "Convert Date and TimeZone to a Calendar, but failed to get the Date back");
692 assertEquals(defaultZone, c.getTimeZone(), "Convert Date and TimeZone to a Calendar, but failed to get the TimeZone back");
693 }
694
695 //-----------------------------------------------------------------------
696 @Test
697 public void testToCalendarWithDateAndTimeZoneNull() {
698 assertThrows(NullPointerException.class, () -> DateUtils.toCalendar(null, null));
699916 }
700917
701918 //-----------------------------------------------------------------------
9711188 "Hour Round Up Failed");
9721189 }
9731190
1191 // -----------------------------------------------------------------------
1192 @Test
1193 public void testSetDays() throws Exception {
1194 Date result = DateUtils.setDays(BASE_DATE, 1);
1195 assertNotSame(BASE_DATE, result);
1196 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1197 assertDate(result, 2000, 6, 1, 4, 3, 2, 1);
1198
1199 result = DateUtils.setDays(BASE_DATE, 29);
1200 assertNotSame(BASE_DATE, result);
1201 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1202 assertDate(result, 2000, 6, 29, 4, 3, 2, 1);
1203
1204 assertThrows(
1205 IllegalArgumentException.class,
1206 () -> DateUtils.setDays(BASE_DATE, 32),
1207 "DateUtils.setDays did not throw an expected IllegalArgumentException.");
1208 }
1209
1210 // -----------------------------------------------------------------------
1211 @Test
1212 public void testSetHours() throws Exception {
1213 Date result = DateUtils.setHours(BASE_DATE, 0);
1214 assertNotSame(BASE_DATE, result);
1215 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1216 assertDate(result, 2000, 6, 5, 0, 3, 2, 1);
1217
1218 result = DateUtils.setHours(BASE_DATE, 23);
1219 assertNotSame(BASE_DATE, result);
1220 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1221 assertDate(result, 2000, 6, 5, 23, 3, 2, 1);
1222
1223 assertThrows(
1224 IllegalArgumentException.class,
1225 () -> DateUtils.setHours(BASE_DATE, 24),
1226 "DateUtils.setHours did not throw an expected IllegalArgumentException.");
1227 }
1228
1229 // -----------------------------------------------------------------------
1230 @Test
1231 public void testSetMilliseconds() throws Exception {
1232 Date result = DateUtils.setMilliseconds(BASE_DATE, 0);
1233 assertNotSame(BASE_DATE, result);
1234 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1235 assertDate(result, 2000, 6, 5, 4, 3, 2, 0);
1236
1237 result = DateUtils.setMilliseconds(BASE_DATE, 999);
1238 assertNotSame(BASE_DATE, result);
1239 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1240 assertDate(result, 2000, 6, 5, 4, 3, 2, 999);
1241
1242 assertThrows(
1243 IllegalArgumentException.class,
1244 () -> DateUtils.setMilliseconds(BASE_DATE, 1000),
1245 "DateUtils.setMilliseconds did not throw an expected IllegalArgumentException.");
1246 }
1247
1248 // -----------------------------------------------------------------------
1249 @Test
1250 public void testSetMinutes() throws Exception {
1251 Date result = DateUtils.setMinutes(BASE_DATE, 0);
1252 assertNotSame(BASE_DATE, result);
1253 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1254 assertDate(result, 2000, 6, 5, 4, 0, 2, 1);
1255
1256 result = DateUtils.setMinutes(BASE_DATE, 59);
1257 assertNotSame(BASE_DATE, result);
1258 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1259 assertDate(result, 2000, 6, 5, 4, 59, 2, 1);
1260
1261 assertThrows(
1262 IllegalArgumentException.class,
1263 () -> DateUtils.setMinutes(BASE_DATE, 60),
1264 "DateUtils.setMinutes did not throw an expected IllegalArgumentException.");
1265 }
1266
1267 // -----------------------------------------------------------------------
1268 @Test
1269 public void testSetMonths() throws Exception {
1270 Date result = DateUtils.setMonths(BASE_DATE, 5);
1271 assertNotSame(BASE_DATE, result);
1272 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1273 assertDate(result, 2000, 5, 5, 4, 3, 2, 1);
1274
1275 result = DateUtils.setMonths(BASE_DATE, 1);
1276 assertNotSame(BASE_DATE, result);
1277 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1278 assertDate(result, 2000, 1, 5, 4, 3, 2, 1);
1279
1280 assertThrows(
1281 IllegalArgumentException.class,
1282 () -> DateUtils.setMonths(BASE_DATE, 12),
1283 "DateUtils.setMonths did not throw an expected IllegalArgumentException.");
1284 }
1285
1286 // -----------------------------------------------------------------------
1287 @Test
1288 public void testSetSeconds() throws Exception {
1289 Date result = DateUtils.setSeconds(BASE_DATE, 0);
1290 assertNotSame(BASE_DATE, result);
1291 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1292 assertDate(result, 2000, 6, 5, 4, 3, 0, 1);
1293
1294 result = DateUtils.setSeconds(BASE_DATE, 59);
1295 assertNotSame(BASE_DATE, result);
1296 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1297 assertDate(result, 2000, 6, 5, 4, 3, 59, 1);
1298
1299 assertThrows(
1300 IllegalArgumentException.class,
1301 () -> DateUtils.setSeconds(BASE_DATE, 60),
1302 "DateUtils.setSeconds did not throw an expected IllegalArgumentException.");
1303 }
1304
1305 // -----------------------------------------------------------------------
1306 @Test
1307 public void testSetYears() throws Exception {
1308 Date result = DateUtils.setYears(BASE_DATE, 2000);
1309 assertNotSame(BASE_DATE, result);
1310 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1311 assertDate(result, 2000, 6, 5, 4, 3, 2, 1);
1312
1313 result = DateUtils.setYears(BASE_DATE, 2008);
1314 assertNotSame(BASE_DATE, result);
1315 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1316 assertDate(result, 2008, 6, 5, 4, 3, 2, 1);
1317
1318 result = DateUtils.setYears(BASE_DATE, 2005);
1319 assertNotSame(BASE_DATE, result);
1320 assertDate(BASE_DATE, 2000, 6, 5, 4, 3, 2, 1);
1321 assertDate(result, 2005, 6, 5, 4, 3, 2, 1);
1322 }
1323
1324 //-----------------------------------------------------------------------
1325 @Test
1326 public void testToCalendar() {
1327 assertEquals(date1, DateUtils.toCalendar(date1).getTime(), "Failed to convert to a Calendar and back");
1328 assertThrows(NullPointerException.class, () -> DateUtils.toCalendar(null));
1329 }
1330
1331 //-----------------------------------------------------------------------
1332 @Test
1333 public void testToCalendarWithDateAndTimeZoneNotNull() {
1334 final Calendar c = DateUtils.toCalendar(date2, defaultZone);
1335 assertEquals(date2, c.getTime(), "Convert Date and TimeZone to a Calendar, but failed to get the Date back");
1336 assertEquals(defaultZone, c.getTimeZone(), "Convert Date and TimeZone to a Calendar, but failed to get the TimeZone back");
1337 }
1338
1339 //-----------------------------------------------------------------------
1340 @Test
1341 public void testToCalendarWithDateAndTimeZoneNull() {
1342 assertThrows(NullPointerException.class, () -> DateUtils.toCalendar(null, null));
1343 }
1344
1345 //-----------------------------------------------------------------------
1346 @Test
1347 public void testToCalendarWithDateNull() {
1348 assertThrows(NullPointerException.class, () -> DateUtils.toCalendar(null, zone));
1349 }
1350
1351 //-----------------------------------------------------------------------
1352 @Test
1353 public void testToCalendarWithTimeZoneNull() {
1354 assertThrows(NullPointerException.class, () -> DateUtils.toCalendar(date1, null));
1355 }
1356
9741357 /**
9751358 * Tests various values with the trunc method
9761359 *
12261609 }
12271610 }
12281611
1229 // https://issues.apache.org/jira/browse/LANG-530
1230 @SuppressWarnings("deprecation")
1231 @Test
1232 public void testLang530() throws ParseException {
1233 final Date d = new Date();
1234 final String isoDateStr = DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(d);
1235 final Date d2 = DateUtils.parseDate(isoDateStr, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern());
1236 // the format loses milliseconds so have to reintroduce them
1237 assertEquals(d.getTime(), d2.getTime() + d.getTime() % 1000, "Date not equal to itself ISO formatted and parsed");
1238 }
1239
1240 /**
1241 * Tests various values with the ceiling method
1242 *
1243 * @throws java.lang.Exception so we don't have to catch it
1244 */
1245 @Test
1246 public void testCeil() throws Exception {
1247 // test javadoc
1248 assertEquals(dateTimeParser.parse("March 28, 2002 14:00:00.000"),
1249 DateUtils.ceiling(
1250 dateTimeParser.parse("March 28, 2002 13:45:01.231"),
1251 Calendar.HOUR),
1252 "ceiling javadoc-1 failed");
1253 assertEquals(dateTimeParser.parse("April 1, 2002 00:00:00.000"),
1254 DateUtils.ceiling(
1255 dateTimeParser.parse("March 28, 2002 13:45:01.231"),
1256 Calendar.MONTH),
1257 "ceiling javadoc-2 failed");
1258
1259 // tests public static Date ceiling(Date date, int field)
1260 assertEquals(dateParser.parse("January 1, 2003"),
1261 DateUtils.ceiling(date1, Calendar.YEAR),
1262 "ceiling year-1 failed");
1263 assertEquals(dateParser.parse("January 1, 2002"),
1264 DateUtils.ceiling(date2, Calendar.YEAR),
1265 "ceiling year-2 failed");
1266 assertEquals(dateParser.parse("March 1, 2002"),
1267 DateUtils.ceiling(date1, Calendar.MONTH),
1268 "ceiling month-1 failed");
1269 assertEquals(dateParser.parse("December 1, 2001"),
1270 DateUtils.ceiling(date2, Calendar.MONTH),
1271 "ceiling month-2 failed");
1272 assertEquals(dateParser.parse("February 16, 2002"),
1273 DateUtils.ceiling(date1, DateUtils.SEMI_MONTH),
1274 "ceiling semimonth-1 failed");
1275 assertEquals(dateParser.parse("December 1, 2001"),
1276 DateUtils.ceiling(date2, DateUtils.SEMI_MONTH),
1277 "ceiling semimonth-2 failed");
1278 assertEquals(dateParser.parse("February 13, 2002"),
1279 DateUtils.ceiling(date1, Calendar.DATE),
1280 "ceiling date-1 failed");
1281 assertEquals(dateParser.parse("November 19, 2001"),
1282 DateUtils.ceiling(date2, Calendar.DATE),
1283 "ceiling date-2 failed");
1284 assertEquals(dateTimeParser.parse("February 12, 2002 13:00:00.000"),
1285 DateUtils.ceiling(date1, Calendar.HOUR),
1286 "ceiling hour-1 failed");
1287 assertEquals(dateTimeParser.parse("November 18, 2001 2:00:00.000"),
1288 DateUtils.ceiling(date2, Calendar.HOUR),
1289 "ceiling hour-2 failed");
1290 assertEquals(dateTimeParser.parse("February 12, 2002 12:35:00.000"),
1291 DateUtils.ceiling(date1, Calendar.MINUTE),
1292 "ceiling minute-1 failed");
1293 assertEquals(dateTimeParser.parse("November 18, 2001 1:24:00.000"),
1294 DateUtils.ceiling(date2, Calendar.MINUTE),
1295 "ceiling minute-2 failed");
1296 assertEquals(dateTimeParser.parse("February 12, 2002 12:34:57.000"),
1297 DateUtils.ceiling(date1, Calendar.SECOND),
1298 "ceiling second-1 failed");
1299 assertEquals(dateTimeParser.parse("November 18, 2001 1:23:12.000"),
1300 DateUtils.ceiling(date2, Calendar.SECOND),
1301 "ceiling second-2 failed");
1302 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
1303 DateUtils.ceiling(dateAmPm1, Calendar.AM_PM),
1304 "ceiling ampm-1 failed");
1305 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
1306 DateUtils.ceiling(dateAmPm2, Calendar.AM_PM),
1307 "ceiling ampm-2 failed");
1308 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
1309 DateUtils.ceiling(dateAmPm3, Calendar.AM_PM),
1310 "ceiling ampm-3 failed");
1311 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
1312 DateUtils.ceiling(dateAmPm4, Calendar.AM_PM),
1313 "ceiling ampm-4 failed");
1314
1315 // tests public static Date ceiling(Object date, int field)
1316 assertEquals(dateParser.parse("January 1, 2003"),
1317 DateUtils.ceiling((Object) date1, Calendar.YEAR),
1318 "ceiling year-1 failed");
1319 assertEquals(dateParser.parse("January 1, 2002"),
1320 DateUtils.ceiling((Object) date2, Calendar.YEAR),
1321 "ceiling year-2 failed");
1322 assertEquals(dateParser.parse("March 1, 2002"),
1323 DateUtils.ceiling((Object) date1, Calendar.MONTH),
1324 "ceiling month-1 failed");
1325 assertEquals(dateParser.parse("December 1, 2001"),
1326 DateUtils.ceiling((Object) date2, Calendar.MONTH),
1327 "ceiling month-2 failed");
1328 assertEquals(dateParser.parse("February 16, 2002"),
1329 DateUtils.ceiling((Object) date1, DateUtils.SEMI_MONTH),
1330 "ceiling semimonth-1 failed");
1331 assertEquals(dateParser.parse("December 1, 2001"),
1332 DateUtils.ceiling((Object) date2, DateUtils.SEMI_MONTH),
1333 "ceiling semimonth-2 failed");
1334 assertEquals(dateParser.parse("February 13, 2002"),
1335 DateUtils.ceiling((Object) date1, Calendar.DATE),
1336 "ceiling date-1 failed");
1337 assertEquals(dateParser.parse("November 19, 2001"),
1338 DateUtils.ceiling((Object) date2, Calendar.DATE),
1339 "ceiling date-2 failed");
1340 assertEquals(dateTimeParser.parse("February 12, 2002 13:00:00.000"),
1341 DateUtils.ceiling((Object) date1, Calendar.HOUR),
1342 "ceiling hour-1 failed");
1343 assertEquals(dateTimeParser.parse("November 18, 2001 2:00:00.000"),
1344 DateUtils.ceiling((Object) date2, Calendar.HOUR),
1345 "ceiling hour-2 failed");
1346 assertEquals(dateTimeParser.parse("February 12, 2002 12:35:00.000"),
1347 DateUtils.ceiling((Object) date1, Calendar.MINUTE),
1348 "ceiling minute-1 failed");
1349 assertEquals(dateTimeParser.parse("November 18, 2001 1:24:00.000"),
1350 DateUtils.ceiling((Object) date2, Calendar.MINUTE),
1351 "ceiling minute-2 failed");
1352 assertEquals(dateTimeParser.parse("February 12, 2002 12:34:57.000"),
1353 DateUtils.ceiling((Object) date1, Calendar.SECOND),
1354 "ceiling second-1 failed");
1355 assertEquals(dateTimeParser.parse("November 18, 2001 1:23:12.000"),
1356 DateUtils.ceiling((Object) date2, Calendar.SECOND),
1357 "ceiling second-2 failed");
1358 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
1359 DateUtils.ceiling((Object) dateAmPm1, Calendar.AM_PM),
1360 "ceiling ampm-1 failed");
1361 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
1362 DateUtils.ceiling((Object) dateAmPm2, Calendar.AM_PM),
1363 "ceiling ampm-2 failed");
1364 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
1365 DateUtils.ceiling((Object) dateAmPm3, Calendar.AM_PM),
1366 "ceiling ampm-3 failed");
1367 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
1368 DateUtils.ceiling((Object) dateAmPm4, Calendar.AM_PM),
1369 "ceiling ampm-4 failed");
1370
1371 assertEquals(dateTimeParser.parse("February 12, 2002 12:34:57.000"),
1372 DateUtils.ceiling((Object) cal1, Calendar.SECOND),
1373 "ceiling calendar second-1 failed");
1374 assertEquals(dateTimeParser.parse("November 18, 2001 1:23:12.000"),
1375 DateUtils.ceiling((Object) cal2, Calendar.SECOND),
1376 "ceiling calendar second-2 failed");
1377
1378 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
1379 DateUtils.ceiling((Object) calAmPm1, Calendar.AM_PM),
1380 "ceiling ampm-1 failed");
1381 assertEquals(dateTimeParser.parse("February 3, 2002 12:00:00.000"),
1382 DateUtils.ceiling((Object) calAmPm2, Calendar.AM_PM),
1383 "ceiling ampm-2 failed");
1384 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
1385 DateUtils.ceiling((Object) calAmPm3, Calendar.AM_PM),
1386 "ceiling ampm-3 failed");
1387 assertEquals(dateTimeParser.parse("February 4, 2002 00:00:00.000"),
1388 DateUtils.ceiling((Object) calAmPm4, Calendar.AM_PM),
1389 "ceiling ampm-4 failed");
1390
1391 assertThrows(NullPointerException.class, () -> DateUtils.ceiling((Date) null, Calendar.SECOND));
1392 assertThrows(IllegalArgumentException.class, () -> DateUtils.ceiling((Calendar) null, Calendar.SECOND));
1393 assertThrows(IllegalArgumentException.class, () -> DateUtils.ceiling((Object) null, Calendar.SECOND));
1394 assertThrows(ClassCastException.class, () -> DateUtils.ceiling("", Calendar.SECOND));
1395 assertThrows(IllegalArgumentException.class, () -> DateUtils.ceiling(date1, -9999));
1396
1397 // Fix for https://issues.apache.org/bugzilla/show_bug.cgi?id=25560
1398 // Test ceiling across the beginning of daylight saving time
1399 try {
1400 TimeZone.setDefault(zone);
1401 dateTimeParser.setTimeZone(zone);
1402
1403 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
1404 DateUtils.ceiling(date4, Calendar.DATE),
1405 "ceiling MET date across DST change-over");
1406 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
1407 DateUtils.ceiling((Object) cal4, Calendar.DATE),
1408 "ceiling MET date across DST change-over");
1409 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
1410 DateUtils.ceiling(date5, Calendar.DATE),
1411 "ceiling MET date across DST change-over");
1412 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
1413 DateUtils.ceiling((Object) cal5, Calendar.DATE),
1414 "ceiling MET date across DST change-over");
1415 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
1416 DateUtils.ceiling(date6, Calendar.DATE),
1417 "ceiling MET date across DST change-over");
1418 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
1419 DateUtils.ceiling((Object) cal6, Calendar.DATE),
1420 "ceiling MET date across DST change-over");
1421 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
1422 DateUtils.ceiling(date7, Calendar.DATE),
1423 "ceiling MET date across DST change-over");
1424 assertEquals(dateTimeParser.parse("March 31, 2003 00:00:00.000"),
1425 DateUtils.ceiling((Object) cal7, Calendar.DATE),
1426 "ceiling MET date across DST change-over");
1427
1428 assertEquals(dateTimeParser.parse("March 30, 2003 03:00:00.000"),
1429 DateUtils.ceiling(date4, Calendar.HOUR_OF_DAY),
1430 "ceiling MET date across DST change-over");
1431 assertEquals(dateTimeParser.parse("March 30, 2003 03:00:00.000"),
1432 DateUtils.ceiling((Object) cal4, Calendar.HOUR_OF_DAY),
1433 "ceiling MET date across DST change-over");
1434 assertEquals(dateTimeParser.parse("March 30, 2003 03:00:00.000"),
1435 DateUtils.ceiling(date5, Calendar.HOUR_OF_DAY),
1436 "ceiling MET date across DST change-over");
1437 assertEquals(dateTimeParser.parse("March 30, 2003 03:00:00.000"),
1438 DateUtils.ceiling((Object) cal5, Calendar.HOUR_OF_DAY),
1439 "ceiling MET date across DST change-over");
1440 assertEquals(dateTimeParser.parse("March 30, 2003 04:00:00.000"),
1441 DateUtils.ceiling(date6, Calendar.HOUR_OF_DAY),
1442 "ceiling MET date across DST change-over");
1443 assertEquals(dateTimeParser.parse("March 30, 2003 04:00:00.000"),
1444 DateUtils.ceiling((Object) cal6, Calendar.HOUR_OF_DAY),
1445 "ceiling MET date across DST change-over");
1446 assertEquals(dateTimeParser.parse("March 30, 2003 04:00:00.000"),
1447 DateUtils.ceiling(date7, Calendar.HOUR_OF_DAY),
1448 "ceiling MET date across DST change-over");
1449 assertEquals(dateTimeParser.parse("March 30, 2003 04:00:00.000"),
1450 DateUtils.ceiling((Object) cal7, Calendar.HOUR_OF_DAY),
1451 "ceiling MET date across DST change-over");
1452
1453 } finally {
1454 TimeZone.setDefault(defaultZone);
1455 dateTimeParser.setTimeZone(defaultZone);
1456 }
1457
1458 // Bug 31395, large dates
1459 final Date endOfTime = new Date(Long.MAX_VALUE); // fyi: Sun Aug 17 07:12:55 CET 292278994 -- 807 millis
1460 final GregorianCalendar endCal = new GregorianCalendar();
1461 endCal.setTime(endOfTime);
1462 assertThrows(ArithmeticException.class, () -> DateUtils.ceiling(endCal, Calendar.DATE));
1463 endCal.set(Calendar.YEAR, 280000001);
1464 assertThrows(ArithmeticException.class, () -> DateUtils.ceiling(endCal, Calendar.DATE));
1465 endCal.set(Calendar.YEAR, 280000000);
1466 final Calendar cal = DateUtils.ceiling(endCal, Calendar.DATE);
1467 assertEquals(0, cal.get(Calendar.HOUR));
1468 }
1469
1470 /**
1471 * Tests the iterator exceptions
1472 */
1473 @Test
1474 public void testIteratorEx() {
1475 assertThrows(IllegalArgumentException.class, () -> DateUtils.iterator(Calendar.getInstance(), -9999));
1476 assertThrows
1477 (NullPointerException.class, () -> DateUtils.iterator((Date) null, DateUtils.RANGE_WEEK_CENTER));
1478 assertThrows
1479 (IllegalArgumentException.class, () -> DateUtils.iterator((Calendar) null, DateUtils.RANGE_WEEK_CENTER));
1480 assertThrows
1481 (IllegalArgumentException.class, () -> DateUtils.iterator((Object) null, DateUtils.RANGE_WEEK_CENTER));
1482 assertThrows(ClassCastException.class, () -> DateUtils.iterator("", DateUtils.RANGE_WEEK_CENTER));
1483 }
1484
14851612 /**
14861613 * Tests the calendar iterator for week ranges
14871614 */
15231650 now.add(Calendar.DATE, 1);
15241651 }
15251652 }
1526
1527 /**
1528 * Tests the calendar iterator for month-based ranges
1529 *
1530 * @throws java.lang.Exception so we don't have to catch it
1531 */
1532 @Test
1533 public void testMonthIterator() throws Exception {
1534 Iterator<?> it = DateUtils.iterator(date1, DateUtils.RANGE_MONTH_SUNDAY);
1535 assertWeekIterator(it,
1536 dateParser.parse("January 27, 2002"),
1537 dateParser.parse("March 2, 2002"));
1538
1539 it = DateUtils.iterator(date1, DateUtils.RANGE_MONTH_MONDAY);
1540 assertWeekIterator(it,
1541 dateParser.parse("January 28, 2002"),
1542 dateParser.parse("March 3, 2002"));
1543
1544 it = DateUtils.iterator(date2, DateUtils.RANGE_MONTH_SUNDAY);
1545 assertWeekIterator(it,
1546 dateParser.parse("October 28, 2001"),
1547 dateParser.parse("December 1, 2001"));
1548
1549 it = DateUtils.iterator(date2, DateUtils.RANGE_MONTH_MONDAY);
1550 assertWeekIterator(it,
1551 dateParser.parse("October 29, 2001"),
1552 dateParser.parse("December 2, 2001"));
1553 }
1554
1555 @DefaultLocale(language = "en")
1556 @Test
1557 public void testLANG799_EN_OK() throws ParseException {
1558 DateUtils.parseDate("Wed, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz");
1559 DateUtils.parseDateStrictly("Wed, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz");
1560 }
1561
1562 // Parse German date with English Locale
1563 @DefaultLocale(language = "en")
1564 @Test
1565 public void testLANG799_EN_FAIL() {
1566 assertThrows(ParseException.class, () -> DateUtils.parseDate("Mi, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz"));
1567 }
1568
1569 @DefaultLocale(language = "de")
1570 @Test
1571 public void testLANG799_DE_OK() throws ParseException {
1572 DateUtils.parseDate("Mi, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz");
1573 DateUtils.parseDateStrictly("Mi, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz");
1574 }
1575
1576 // Parse English date with German Locale
1577 @DefaultLocale(language = "de")
1578 @Test
1579 public void testLANG799_DE_FAIL() {
1580 assertThrows(ParseException.class, () -> DateUtils.parseDate("Wed, 09 Apr 2008 23:55:38 GMT", "EEE, dd MMM yyyy HH:mm:ss zzz"));
1581 }
1582
1583 // Parse German date with English Locale, specifying German Locale override
1584 @DefaultLocale(language = "en")
1585 @Test
1586 public void testLANG799_EN_WITH_DE_LOCALE() throws ParseException {
1587 DateUtils.parseDate("Mi, 09 Apr 2008 23:55:38 GMT", Locale.GERMAN, "EEE, dd MMM yyyy HH:mm:ss zzz");
1588 }
1589
1590 /**
1591 * This checks that this is a 7 element iterator of Calendar objects
1592 * that are dates (no time), and exactly 1 day spaced after each other.
1593 */
1594 private static void assertWeekIterator(final Iterator<?> it, final Calendar start) {
1595 final Calendar end = (Calendar) start.clone();
1596 end.add(Calendar.DATE, 6);
1597
1598 assertWeekIterator(it, start, end);
1599 }
1600
1601 /**
1602 * Convenience method for when working with Date objects
1603 */
1604 private static void assertWeekIterator(final Iterator<?> it, final Date start, final Date end) {
1605 final Calendar calStart = Calendar.getInstance();
1606 calStart.setTime(start);
1607 final Calendar calEnd = Calendar.getInstance();
1608 calEnd.setTime(end);
1609
1610 assertWeekIterator(it, calStart, calEnd);
1611 }
1612
1613 /**
1614 * This checks that this is a 7 divisble iterator of Calendar objects
1615 * that are dates (no time), and exactly 1 day spaced after each other
1616 * (in addition to the proper start and stop dates)
1617 */
1618 private static void assertWeekIterator(final Iterator<?> it, final Calendar start, final Calendar end) {
1619 Calendar cal = (Calendar) it.next();
1620 assertCalendarsEquals("", start, cal, 0);
1621 Calendar last = null;
1622 int count = 1;
1623 while (it.hasNext()) {
1624 //Check this is just a date (no time component)
1625 assertCalendarsEquals("", cal, DateUtils.truncate(cal, Calendar.DATE), 0);
1626
1627 last = cal;
1628 cal = (Calendar) it.next();
1629 count++;
1630
1631 //Check that this is one day more than the last date
1632 last.add(Calendar.DATE, 1);
1633 assertCalendarsEquals("", last, cal, 0);
1634 }
1635
1636 assertFalse(count % 7 != 0, "There were " + count + " days in this iterator");
1637 assertCalendarsEquals("", end, cal, 0);
1638 }
1639
1640 /**
1641 * Used to check that Calendar objects are close enough
1642 * delta is in milliseconds
1643 */
1644 private static void assertCalendarsEquals(final String message, final Calendar cal1, final Calendar cal2, final long delta) {
1645 assertFalse(Math.abs(cal1.getTime().getTime() - cal2.getTime().getTime()) > delta,
1646 message + " expected " + cal1.getTime() + " but got " + cal2.getTime());
1647 }
1648
1649 @Test
1650 public void testLANG799() throws ParseException {
1651 DateUtils.parseDateStrictly("09 abril 2008 23:55:38 GMT", new Locale("es"), "dd MMM yyyy HH:mm:ss zzz");
1652 }
16531653 }
16541654
3636 */
3737 public class DurationFormatUtilsTest {
3838
39 private static final int FOUR_YEARS = 365 * 3 + 366;
40
41 private void assertEqualDuration(final String expected, final int[] start, final int[] end, final String format) {
42 assertEqualDuration(null, expected, start, end, format);
43 }
44
45 private void assertEqualDuration(final String message, final String expected, final int[] start, final int[] end, final String format) {
46 final Calendar cal1 = Calendar.getInstance();
47 cal1.set(start[0], start[1], start[2], start[3], start[4], start[5]);
48 cal1.set(Calendar.MILLISECOND, 0);
49 final Calendar cal2 = Calendar.getInstance();
50 cal2.set(end[0], end[1], end[2], end[3], end[4], end[5]);
51 cal2.set(Calendar.MILLISECOND, 0);
52 final long milli1 = cal1.getTime().getTime();
53 final long milli2 = cal2.getTime().getTime();
54 final String result = DurationFormatUtils.formatPeriod(milli1, milli2, format);
55 if (message == null) {
56 assertEquals(expected, result);
57 } else {
58 assertEquals(expected, result, message);
59 }
60 }
61
62 private void bruteForce(final int year, final int month, final int day, final String format, final int calendarType) {
63 final String msg = year + "-" + month + "-" + day + " to ";
64 final Calendar c = Calendar.getInstance();
65 c.set(year, month, day, 0, 0, 0);
66 final int[] array1 = new int[] { year, month, day, 0, 0, 0 };
67 final int[] array2 = new int[] { year, month, day, 0, 0, 0 };
68 for (int i=0; i < FOUR_YEARS; i++) {
69 array2[0] = c.get(Calendar.YEAR);
70 array2[1] = c.get(Calendar.MONTH);
71 array2[2] = c.get(Calendar.DAY_OF_MONTH);
72 final String tmpMsg = msg + array2[0] + "-" + array2[1] + "-" + array2[2] + " at ";
73 assertEqualDuration( tmpMsg + i, Integer.toString(i), array1, array2, format );
74 c.add(calendarType, 1);
75 }
76 }
77
78 // https://issues.apache.org/bugzilla/show_bug.cgi?id=38401
79 @Test
80 public void testBugzilla38401() {
81 assertEqualDuration( "0000/00/30 16:00:00 000", new int[] { 2006, 0, 26, 18, 47, 34 },
82 new int[] { 2006, 1, 26, 10, 47, 34 }, "yyyy/MM/dd HH:mm:ss SSS");
83 }
84
3985 // -----------------------------------------------------------------------
4086 @Test
4187 public void testConstructor() {
4793 assertFalse(Modifier.isFinal(DurationFormatUtils.class.getModifiers()));
4894 }
4995
96 @Test
97 public void testDurationsByBruteForce() {
98 bruteForce(2006, 0, 1, "d", Calendar.DAY_OF_MONTH);
99 bruteForce(2006, 0, 2, "d", Calendar.DAY_OF_MONTH);
100 bruteForce(2007, 1, 2, "d", Calendar.DAY_OF_MONTH);
101 bruteForce(2004, 1, 29, "d", Calendar.DAY_OF_MONTH);
102 bruteForce(1996, 1, 29, "d", Calendar.DAY_OF_MONTH);
103
104 bruteForce(1969, 1, 28, "M", Calendar.MONTH); // tests for 48 years
105 //bruteForce(1996, 1, 29, "M", Calendar.MONTH); // this will fail
106 }
107
108 // Attempting to test edge cases in DurationFormatUtils.formatPeriod
109 @Test
110 public void testEdgeDurations() {
111 // This test case must use a time zone without DST
112 TimeZone.setDefault(FastTimeZone.getGmtTimeZone());
113 assertEqualDuration( "01", new int[] { 2006, 0, 15, 0, 0, 0 },
114 new int[] { 2006, 2, 10, 0, 0, 0 }, "MM");
115 assertEqualDuration( "12", new int[] { 2005, 0, 15, 0, 0, 0 },
116 new int[] { 2006, 0, 15, 0, 0, 0 }, "MM");
117 assertEqualDuration( "12", new int[] { 2005, 0, 15, 0, 0, 0 },
118 new int[] { 2006, 0, 16, 0, 0, 0 }, "MM");
119 assertEqualDuration( "11", new int[] { 2005, 0, 15, 0, 0, 0 },
120 new int[] { 2006, 0, 14, 0, 0, 0 }, "MM");
121
122 assertEqualDuration( "01 26", new int[] { 2006, 0, 15, 0, 0, 0 },
123 new int[] { 2006, 2, 10, 0, 0, 0 }, "MM dd");
124 assertEqualDuration( "54", new int[] { 2006, 0, 15, 0, 0, 0 },
125 new int[] { 2006, 2, 10, 0, 0, 0 }, "dd");
126
127 assertEqualDuration( "09 12", new int[] { 2006, 1, 20, 0, 0, 0 },
128 new int[] { 2006, 11, 4, 0, 0, 0 }, "MM dd");
129 assertEqualDuration( "287", new int[] { 2006, 1, 20, 0, 0, 0 },
130 new int[] { 2006, 11, 4, 0, 0, 0 }, "dd");
131
132 assertEqualDuration( "11 30", new int[] { 2006, 0, 2, 0, 0, 0 },
133 new int[] { 2007, 0, 1, 0, 0, 0 }, "MM dd");
134 assertEqualDuration( "364", new int[] { 2006, 0, 2, 0, 0, 0 },
135 new int[] { 2007, 0, 1, 0, 0, 0 }, "dd");
136
137 assertEqualDuration( "12 00", new int[] { 2006, 0, 1, 0, 0, 0 },
138 new int[] { 2007, 0, 1, 0, 0, 0 }, "MM dd");
139 assertEqualDuration( "365", new int[] { 2006, 0, 1, 0, 0, 0 },
140 new int[] { 2007, 0, 1, 0, 0, 0 }, "dd");
141
142 assertEqualDuration( "31", new int[] { 2006, 0, 1, 0, 0, 0 },
143 new int[] { 2006, 1, 1, 0, 0, 0 }, "dd");
144
145 assertEqualDuration( "92", new int[] { 2005, 9, 1, 0, 0, 0 },
146 new int[] { 2006, 0, 1, 0, 0, 0 }, "dd");
147 assertEqualDuration( "77", new int[] { 2005, 9, 16, 0, 0, 0 },
148 new int[] { 2006, 0, 1, 0, 0, 0 }, "dd");
149
150 // test month larger in start than end
151 assertEqualDuration( "136", new int[] { 2005, 9, 16, 0, 0, 0 },
152 new int[] { 2006, 2, 1, 0, 0, 0 }, "dd");
153 // test when start in leap year
154 assertEqualDuration( "136", new int[] { 2004, 9, 16, 0, 0, 0 },
155 new int[] { 2005, 2, 1, 0, 0, 0 }, "dd");
156 // test when end in leap year
157 assertEqualDuration( "137", new int[] { 2003, 9, 16, 0, 0, 0 },
158 new int[] { 2004, 2, 1, 0, 0, 0 }, "dd");
159 // test when end in leap year but less than end of feb
160 assertEqualDuration( "135", new int[] { 2003, 9, 16, 0, 0, 0 },
161 new int[] { 2004, 1, 28, 0, 0, 0 }, "dd");
162
163 assertEqualDuration( "364", new int[] { 2007, 0, 2, 0, 0, 0 },
164 new int[] { 2008, 0, 1, 0, 0, 0 }, "dd");
165 assertEqualDuration( "729", new int[] { 2006, 0, 2, 0, 0, 0 },
166 new int[] { 2008, 0, 1, 0, 0, 0 }, "dd");
167
168 assertEqualDuration( "365", new int[] { 2007, 2, 2, 0, 0, 0 },
169 new int[] { 2008, 2, 1, 0, 0, 0 }, "dd");
170 assertEqualDuration( "333", new int[] { 2007, 1, 2, 0, 0, 0 },
171 new int[] { 2008, 0, 1, 0, 0, 0 }, "dd");
172
173 assertEqualDuration( "28", new int[] { 2008, 1, 2, 0, 0, 0 },
174 new int[] { 2008, 2, 1, 0, 0, 0 }, "dd");
175 assertEqualDuration( "393", new int[] { 2007, 1, 2, 0, 0, 0 },
176 new int[] { 2008, 2, 1, 0, 0, 0 }, "dd");
177
178 assertEqualDuration( "369", new int[] { 2004, 0, 29, 0, 0, 0 },
179 new int[] { 2005, 1, 1, 0, 0, 0 }, "dd");
180
181 assertEqualDuration( "338", new int[] { 2004, 1, 29, 0, 0, 0 },
182 new int[] { 2005, 1, 1, 0, 0, 0 }, "dd");
183
184 assertEqualDuration( "28", new int[] { 2004, 2, 8, 0, 0, 0 },
185 new int[] { 2004, 3, 5, 0, 0, 0 }, "dd");
186
187 assertEqualDuration( "48", new int[] { 1992, 1, 29, 0, 0, 0 },
188 new int[] { 1996, 1, 29, 0, 0, 0 }, "M");
189
190
191 // this seems odd - and will fail if I throw it in as a brute force
192 // below as it expects the answer to be 12. It's a tricky edge case
193 assertEqualDuration( "11", new int[] { 1996, 1, 29, 0, 0, 0 },
194 new int[] { 1997, 1, 28, 0, 0, 0 }, "M");
195 // again - this seems odd
196 assertEqualDuration( "11 28", new int[] { 1996, 1, 29, 0, 0, 0 },
197 new int[] { 1997, 1, 28, 0, 0, 0 }, "M d");
198
199 }
200
201 @Test
202 public void testFormatDuration() {
203 long duration = 0;
204 assertEquals("0", DurationFormatUtils.formatDuration(duration, "y"));
205 assertEquals("0", DurationFormatUtils.formatDuration(duration, "M"));
206 assertEquals("0", DurationFormatUtils.formatDuration(duration, "d"));
207 assertEquals("0", DurationFormatUtils.formatDuration(duration, "H"));
208 assertEquals("0", DurationFormatUtils.formatDuration(duration, "m"));
209 assertEquals("0", DurationFormatUtils.formatDuration(duration, "s"));
210 assertEquals("0", DurationFormatUtils.formatDuration(duration, "S"));
211 assertEquals("0000", DurationFormatUtils.formatDuration(duration, "SSSS"));
212 assertEquals("0000", DurationFormatUtils.formatDuration(duration, "yyyy"));
213 assertEquals("0000", DurationFormatUtils.formatDuration(duration, "yyMM"));
214
215 duration = 60 * 1000;
216 assertEquals("0", DurationFormatUtils.formatDuration(duration, "y"));
217 assertEquals("0", DurationFormatUtils.formatDuration(duration, "M"));
218 assertEquals("0", DurationFormatUtils.formatDuration(duration, "d"));
219 assertEquals("0", DurationFormatUtils.formatDuration(duration, "H"));
220 assertEquals("1", DurationFormatUtils.formatDuration(duration, "m"));
221 assertEquals("60", DurationFormatUtils.formatDuration(duration, "s"));
222 assertEquals("60000", DurationFormatUtils.formatDuration(duration, "S"));
223 assertEquals("01:00", DurationFormatUtils.formatDuration(duration, "mm:ss"));
224
225 final Calendar base = Calendar.getInstance();
226 base.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
227 base.set(Calendar.MILLISECOND, 0);
228
229 final Calendar cal = Calendar.getInstance();
230 cal.set(2003, Calendar.FEBRUARY, 1, 0, 0, 0);
231 cal.set(Calendar.MILLISECOND, 0);
232 duration = cal.getTime().getTime() - base.getTime().getTime(); // duration from 2000-01-01 to cal
233 // don't use 1970 in test as time zones were less reliable in 1970 than now
234 // remember that duration formatting ignores time zones, working on strict hour lengths
235 final int days = 366 + 365 + 365 + 31;
236 assertEquals("0 0 " + days, DurationFormatUtils.formatDuration(duration, "y M d"));
237 }
238
239 @Test
240 public void testFormatDurationHMS() {
241 long time = 0;
242 assertEquals("00:00:00.000", DurationFormatUtils.formatDurationHMS(time));
243
244 time = 1;
245 assertEquals("00:00:00.001", DurationFormatUtils.formatDurationHMS(time));
246
247 time = 15;
248 assertEquals("00:00:00.015", DurationFormatUtils.formatDurationHMS(time));
249
250 time = 165;
251 assertEquals("00:00:00.165", DurationFormatUtils.formatDurationHMS(time));
252
253 time = 1675;
254 assertEquals("00:00:01.675", DurationFormatUtils.formatDurationHMS(time));
255
256 time = 13465;
257 assertEquals("00:00:13.465", DurationFormatUtils.formatDurationHMS(time));
258
259 time = 72789;
260 assertEquals("00:01:12.789", DurationFormatUtils.formatDurationHMS(time));
261
262 time = 12789 + 32 * 60000;
263 assertEquals("00:32:12.789", DurationFormatUtils.formatDurationHMS(time));
264
265 time = 12789 + 62 * 60000;
266 assertEquals("01:02:12.789", DurationFormatUtils.formatDurationHMS(time));
267 }
268
269 @Test
270 public void testFormatDurationISO() {
271 assertEquals("P0Y0M0DT0H0M0.000S", DurationFormatUtils.formatDurationISO(0L));
272 assertEquals("P0Y0M0DT0H0M0.001S", DurationFormatUtils.formatDurationISO(1L));
273 assertEquals("P0Y0M0DT0H0M0.010S", DurationFormatUtils.formatDurationISO(10L));
274 assertEquals("P0Y0M0DT0H0M0.100S", DurationFormatUtils.formatDurationISO(100L));
275 assertEquals("P0Y0M0DT0H1M15.321S", DurationFormatUtils.formatDurationISO(75321L));
276 }
277
278 /**
279 * Tests that "1 &lt;unit&gt;s" gets converted to "1 &lt;unit&gt;" but that "11 &lt;unit&gt;s" is left alone.
280 */
281 @Test
282 public void testFormatDurationPluralWords() {
283 final long oneSecond = 1000;
284 final long oneMinute = oneSecond * 60;
285 final long oneHour = oneMinute * 60;
286 final long oneDay = oneHour * 24;
287 String text;
288
289 text = DurationFormatUtils.formatDurationWords(oneSecond, false, false);
290 assertEquals("0 days 0 hours 0 minutes 1 second", text);
291 text = DurationFormatUtils.formatDurationWords(oneSecond * 2, false, false);
292 assertEquals("0 days 0 hours 0 minutes 2 seconds", text);
293 text = DurationFormatUtils.formatDurationWords(oneSecond * 11, false, false);
294 assertEquals("0 days 0 hours 0 minutes 11 seconds", text);
295
296 text = DurationFormatUtils.formatDurationWords(oneMinute, false, false);
297 assertEquals("0 days 0 hours 1 minute 0 seconds", text);
298 text = DurationFormatUtils.formatDurationWords(oneMinute * 2, false, false);
299 assertEquals("0 days 0 hours 2 minutes 0 seconds", text);
300 text = DurationFormatUtils.formatDurationWords(oneMinute * 11, false, false);
301 assertEquals("0 days 0 hours 11 minutes 0 seconds", text);
302 text = DurationFormatUtils.formatDurationWords(oneMinute + oneSecond, false, false);
303 assertEquals("0 days 0 hours 1 minute 1 second", text);
304
305 text = DurationFormatUtils.formatDurationWords(oneHour, false, false);
306 assertEquals("0 days 1 hour 0 minutes 0 seconds", text);
307 text = DurationFormatUtils.formatDurationWords(oneHour * 2, false, false);
308 assertEquals("0 days 2 hours 0 minutes 0 seconds", text);
309 text = DurationFormatUtils.formatDurationWords(oneHour * 11, false, false);
310 assertEquals("0 days 11 hours 0 minutes 0 seconds", text);
311 text = DurationFormatUtils.formatDurationWords(oneHour + oneMinute + oneSecond, false, false);
312 assertEquals("0 days 1 hour 1 minute 1 second", text);
313
314 text = DurationFormatUtils.formatDurationWords(oneDay, false, false);
315 assertEquals("1 day 0 hours 0 minutes 0 seconds", text);
316 text = DurationFormatUtils.formatDurationWords(oneDay * 2, false, false);
317 assertEquals("2 days 0 hours 0 minutes 0 seconds", text);
318 text = DurationFormatUtils.formatDurationWords(oneDay * 11, false, false);
319 assertEquals("11 days 0 hours 0 minutes 0 seconds", text);
320 text = DurationFormatUtils.formatDurationWords(oneDay + oneHour + oneMinute + oneSecond, false, false);
321 assertEquals("1 day 1 hour 1 minute 1 second", text);
322 }
323
50324 // -----------------------------------------------------------------------
51325 @Test
52326 public void testFormatDurationWords() {
53 String text = null;
327 String text;
54328
55329 text = DurationFormatUtils.formatDurationWords(50 * 1000, true, false);
56330 assertEquals("50 seconds", text);
111385 }
112386 }
113387
114 /**
115 * Tests that "1 &lt;unit&gt;s" gets converted to "1 &lt;unit&gt;" but that "11 &lt;unit&gt;s" is left alone.
116 */
117 @Test
118 public void testFormatDurationPluralWords() {
119 final long oneSecond = 1000;
120 final long oneMinute = oneSecond * 60;
121 final long oneHour = oneMinute * 60;
122 final long oneDay = oneHour * 24;
123 String text = null;
124
125 text = DurationFormatUtils.formatDurationWords(oneSecond, false, false);
126 assertEquals("0 days 0 hours 0 minutes 1 second", text);
127 text = DurationFormatUtils.formatDurationWords(oneSecond * 2, false, false);
128 assertEquals("0 days 0 hours 0 minutes 2 seconds", text);
129 text = DurationFormatUtils.formatDurationWords(oneSecond * 11, false, false);
130 assertEquals("0 days 0 hours 0 minutes 11 seconds", text);
131
132 text = DurationFormatUtils.formatDurationWords(oneMinute, false, false);
133 assertEquals("0 days 0 hours 1 minute 0 seconds", text);
134 text = DurationFormatUtils.formatDurationWords(oneMinute * 2, false, false);
135 assertEquals("0 days 0 hours 2 minutes 0 seconds", text);
136 text = DurationFormatUtils.formatDurationWords(oneMinute * 11, false, false);
137 assertEquals("0 days 0 hours 11 minutes 0 seconds", text);
138 text = DurationFormatUtils.formatDurationWords(oneMinute + oneSecond, false, false);
139 assertEquals("0 days 0 hours 1 minute 1 second", text);
140
141 text = DurationFormatUtils.formatDurationWords(oneHour, false, false);
142 assertEquals("0 days 1 hour 0 minutes 0 seconds", text);
143 text = DurationFormatUtils.formatDurationWords(oneHour * 2, false, false);
144 assertEquals("0 days 2 hours 0 minutes 0 seconds", text);
145 text = DurationFormatUtils.formatDurationWords(oneHour * 11, false, false);
146 assertEquals("0 days 11 hours 0 minutes 0 seconds", text);
147 text = DurationFormatUtils.formatDurationWords(oneHour + oneMinute + oneSecond, false, false);
148 assertEquals("0 days 1 hour 1 minute 1 second", text);
149
150 text = DurationFormatUtils.formatDurationWords(oneDay, false, false);
151 assertEquals("1 day 0 hours 0 minutes 0 seconds", text);
152 text = DurationFormatUtils.formatDurationWords(oneDay * 2, false, false);
153 assertEquals("2 days 0 hours 0 minutes 0 seconds", text);
154 text = DurationFormatUtils.formatDurationWords(oneDay * 11, false, false);
155 assertEquals("11 days 0 hours 0 minutes 0 seconds", text);
156 text = DurationFormatUtils.formatDurationWords(oneDay + oneHour + oneMinute + oneSecond, false, false);
157 assertEquals("1 day 1 hour 1 minute 1 second", text);
158 }
388 @Test
389 public void testFormatNegativeDuration() {
390 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDuration(-5000, "S", true));
391 }
392
393 @Test
394 public void testFormatNegativeDurationHMS() {
395 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDurationHMS(-5000));
396 }
397
398 @Test
399 public void testFormatNegativeDurationISO() {
400 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDurationISO(-5000));
401 }
402
159403
160404 @Test
161405 public void testFormatNegativeDurationWords() {
163407 }
164408
165409 @Test
166 public void testFormatDurationHMS() {
167 long time = 0;
168 assertEquals("00:00:00.000", DurationFormatUtils.formatDurationHMS(time));
169
170 time = 1;
171 assertEquals("00:00:00.001", DurationFormatUtils.formatDurationHMS(time));
172
173 time = 15;
174 assertEquals("00:00:00.015", DurationFormatUtils.formatDurationHMS(time));
175
176 time = 165;
177 assertEquals("00:00:00.165", DurationFormatUtils.formatDurationHMS(time));
178
179 time = 1675;
180 assertEquals("00:00:01.675", DurationFormatUtils.formatDurationHMS(time));
181
182 time = 13465;
183 assertEquals("00:00:13.465", DurationFormatUtils.formatDurationHMS(time));
184
185 time = 72789;
186 assertEquals("00:01:12.789", DurationFormatUtils.formatDurationHMS(time));
187
188 time = 12789 + 32 * 60000;
189 assertEquals("00:32:12.789", DurationFormatUtils.formatDurationHMS(time));
190
191 time = 12789 + 62 * 60000;
192 assertEquals("01:02:12.789", DurationFormatUtils.formatDurationHMS(time));
193 }
194
195 @Test
196 public void testFormatNegativeDurationHMS() {
197 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDurationHMS(-5000));
198 }
199
200 @Test
201 public void testFormatDurationISO() {
202 assertEquals("P0Y0M0DT0H0M0.000S", DurationFormatUtils.formatDurationISO(0L));
203 assertEquals("P0Y0M0DT0H0M0.001S", DurationFormatUtils.formatDurationISO(1L));
204 assertEquals("P0Y0M0DT0H0M0.010S", DurationFormatUtils.formatDurationISO(10L));
205 assertEquals("P0Y0M0DT0H0M0.100S", DurationFormatUtils.formatDurationISO(100L));
206 assertEquals("P0Y0M0DT0H1M15.321S", DurationFormatUtils.formatDurationISO(75321L));
207 }
208
209 @Test
210 public void testFormatNegativeDurationISO() {
211 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDurationISO(-5000));
212 }
213
214 @Test
215 public void testFormatDuration() {
216 long duration = 0;
217 assertEquals("0", DurationFormatUtils.formatDuration(duration, "y"));
218 assertEquals("0", DurationFormatUtils.formatDuration(duration, "M"));
219 assertEquals("0", DurationFormatUtils.formatDuration(duration, "d"));
220 assertEquals("0", DurationFormatUtils.formatDuration(duration, "H"));
221 assertEquals("0", DurationFormatUtils.formatDuration(duration, "m"));
222 assertEquals("0", DurationFormatUtils.formatDuration(duration, "s"));
223 assertEquals("0", DurationFormatUtils.formatDuration(duration, "S"));
224 assertEquals("0000", DurationFormatUtils.formatDuration(duration, "SSSS"));
225 assertEquals("0000", DurationFormatUtils.formatDuration(duration, "yyyy"));
226 assertEquals("0000", DurationFormatUtils.formatDuration(duration, "yyMM"));
227
228 duration = 60 * 1000;
229 assertEquals("0", DurationFormatUtils.formatDuration(duration, "y"));
230 assertEquals("0", DurationFormatUtils.formatDuration(duration, "M"));
231 assertEquals("0", DurationFormatUtils.formatDuration(duration, "d"));
232 assertEquals("0", DurationFormatUtils.formatDuration(duration, "H"));
233 assertEquals("1", DurationFormatUtils.formatDuration(duration, "m"));
234 assertEquals("60", DurationFormatUtils.formatDuration(duration, "s"));
235 assertEquals("60000", DurationFormatUtils.formatDuration(duration, "S"));
236 assertEquals("01:00", DurationFormatUtils.formatDuration(duration, "mm:ss"));
237
238 final Calendar base = Calendar.getInstance();
239 base.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
240 base.set(Calendar.MILLISECOND, 0);
410 public void testFormatPeriod() {
411 final Calendar cal1970 = Calendar.getInstance();
412 cal1970.set(1970, Calendar.JANUARY, 1, 0, 0, 0);
413 cal1970.set(Calendar.MILLISECOND, 0);
414 final long time1970 = cal1970.getTime().getTime();
415
416 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "y"));
417 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "M"));
418 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "d"));
419 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "H"));
420 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "m"));
421 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "s"));
422 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "S"));
423 assertEquals("0000", DurationFormatUtils.formatPeriod(time1970, time1970, "SSSS"));
424 assertEquals("0000", DurationFormatUtils.formatPeriod(time1970, time1970, "yyyy"));
425 assertEquals("0000", DurationFormatUtils.formatPeriod(time1970, time1970, "yyMM"));
426
427 long time = time1970 + 60 * 1000;
428 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "y"));
429 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "M"));
430 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "d"));
431 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "H"));
432 assertEquals("1", DurationFormatUtils.formatPeriod(time1970, time, "m"));
433 assertEquals("60", DurationFormatUtils.formatPeriod(time1970, time, "s"));
434 assertEquals("60000", DurationFormatUtils.formatPeriod(time1970, time, "S"));
435 assertEquals("01:00", DurationFormatUtils.formatPeriod(time1970, time, "mm:ss"));
241436
242437 final Calendar cal = Calendar.getInstance();
243 cal.set(2003, Calendar.FEBRUARY, 1, 0, 0, 0);
438 cal.set(1973, Calendar.JULY, 1, 0, 0, 0);
244439 cal.set(Calendar.MILLISECOND, 0);
245 duration = cal.getTime().getTime() - base.getTime().getTime(); // duration from 2000-01-01 to cal
246 // don't use 1970 in test as time zones were less reliable in 1970 than now
247 // remember that duration formatting ignores time zones, working on strict hour lengths
248 final int days = 366 + 365 + 365 + 31;
249 assertEquals("0 0 " + days, DurationFormatUtils.formatDuration(duration, "y M d"));
250 }
251
252 @Test
253 public void testFormatNegativeDuration() {
254 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDuration(-5000, "S", true));
440 time = cal.getTime().getTime();
441 assertEquals("36", DurationFormatUtils.formatPeriod(time1970, time, "yM"));
442 assertEquals("3 years 6 months", DurationFormatUtils.formatPeriod(time1970, time, "y' years 'M' months'"));
443 assertEquals("03/06", DurationFormatUtils.formatPeriod(time1970, time, "yy/MM"));
444
445 cal.set(1973, Calendar.NOVEMBER, 1, 0, 0, 0);
446 cal.set(Calendar.MILLISECOND, 0);
447 time = cal.getTime().getTime();
448 assertEquals("310", DurationFormatUtils.formatPeriod(time1970, time, "yM"));
449 assertEquals("3 years 10 months", DurationFormatUtils.formatPeriod(time1970, time, "y' years 'M' months'"));
450 assertEquals("03/10", DurationFormatUtils.formatPeriod(time1970, time, "yy/MM"));
451
452 cal.set(1974, Calendar.JANUARY, 1, 0, 0, 0);
453 cal.set(Calendar.MILLISECOND, 0);
454 time = cal.getTime().getTime();
455 assertEquals("40", DurationFormatUtils.formatPeriod(time1970, time, "yM"));
456 assertEquals("4 years 0 months", DurationFormatUtils.formatPeriod(time1970, time, "y' years 'M' months'"));
457 assertEquals("04/00", DurationFormatUtils.formatPeriod(time1970, time, "yy/MM"));
458 assertEquals("48", DurationFormatUtils.formatPeriod(time1970, time, "M"));
459 assertEquals("48", DurationFormatUtils.formatPeriod(time1970, time, "MM"));
460 assertEquals("048", DurationFormatUtils.formatPeriod(time1970, time, "MMM"));
461 }
462
463 @Test
464 public void testFormatPeriodeStartGreaterEnd() {
465 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatPeriod(5000, 2500, "yy/MM"));
255466 }
256467
257468 @SuppressWarnings("deprecation")
284495 }
285496
286497 @Test
287 public void testFormatPeriodISOStartGreaterEnd() {
288 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatPeriodISO(5000, 2000));
289 }
290
291 @Test
292498 public void testFormatPeriodISOMethod() {
293499 assertEquals("P0Y0M0DT0H0M0.000S", DurationFormatUtils.formatPeriodISO(0L, 0L));
294500 assertEquals("P0Y0M0DT0H0M1.000S", DurationFormatUtils.formatPeriodISO(0L, 1000L));
296502 }
297503
298504 @Test
299 public void testFormatPeriod() {
300 final Calendar cal1970 = Calendar.getInstance();
301 cal1970.set(1970, Calendar.JANUARY, 1, 0, 0, 0);
302 cal1970.set(Calendar.MILLISECOND, 0);
303 final long time1970 = cal1970.getTime().getTime();
304
305 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "y"));
306 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "M"));
307 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "d"));
308 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "H"));
309 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "m"));
310 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "s"));
311 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "S"));
312 assertEquals("0000", DurationFormatUtils.formatPeriod(time1970, time1970, "SSSS"));
313 assertEquals("0000", DurationFormatUtils.formatPeriod(time1970, time1970, "yyyy"));
314 assertEquals("0000", DurationFormatUtils.formatPeriod(time1970, time1970, "yyMM"));
315
316 long time = time1970 + 60 * 1000;
317 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "y"));
318 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "M"));
319 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "d"));
320 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "H"));
321 assertEquals("1", DurationFormatUtils.formatPeriod(time1970, time, "m"));
322 assertEquals("60", DurationFormatUtils.formatPeriod(time1970, time, "s"));
323 assertEquals("60000", DurationFormatUtils.formatPeriod(time1970, time, "S"));
324 assertEquals("01:00", DurationFormatUtils.formatPeriod(time1970, time, "mm:ss"));
325
326 final Calendar cal = Calendar.getInstance();
327 cal.set(1973, Calendar.JULY, 1, 0, 0, 0);
328 cal.set(Calendar.MILLISECOND, 0);
329 time = cal.getTime().getTime();
330 assertEquals("36", DurationFormatUtils.formatPeriod(time1970, time, "yM"));
331 assertEquals("3 years 6 months", DurationFormatUtils.formatPeriod(time1970, time, "y' years 'M' months'"));
332 assertEquals("03/06", DurationFormatUtils.formatPeriod(time1970, time, "yy/MM"));
333
334 cal.set(1973, Calendar.NOVEMBER, 1, 0, 0, 0);
335 cal.set(Calendar.MILLISECOND, 0);
336 time = cal.getTime().getTime();
337 assertEquals("310", DurationFormatUtils.formatPeriod(time1970, time, "yM"));
338 assertEquals("3 years 10 months", DurationFormatUtils.formatPeriod(time1970, time, "y' years 'M' months'"));
339 assertEquals("03/10", DurationFormatUtils.formatPeriod(time1970, time, "yy/MM"));
340
341 cal.set(1974, Calendar.JANUARY, 1, 0, 0, 0);
342 cal.set(Calendar.MILLISECOND, 0);
343 time = cal.getTime().getTime();
344 assertEquals("40", DurationFormatUtils.formatPeriod(time1970, time, "yM"));
345 assertEquals("4 years 0 months", DurationFormatUtils.formatPeriod(time1970, time, "y' years 'M' months'"));
346 assertEquals("04/00", DurationFormatUtils.formatPeriod(time1970, time, "yy/MM"));
347 assertEquals("48", DurationFormatUtils.formatPeriod(time1970, time, "M"));
348 assertEquals("48", DurationFormatUtils.formatPeriod(time1970, time, "MM"));
349 assertEquals("048", DurationFormatUtils.formatPeriod(time1970, time, "MMM"));
350 }
351
352 @Test
353 public void testFormatPeriodeStartGreaterEnd() {
354 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatPeriod(5000, 2500, "yy/MM"));
505 public void testFormatPeriodISOStartGreaterEnd() {
506 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatPeriodISO(5000, 2000));
507 }
508
509 // https://issues.apache.org/jira/browse/LANG-281
510 @Test
511 public void testJiraLang281() {
512 assertEqualDuration( "09", new int[] { 2005, 11, 31, 0, 0, 0 },
513 new int[] { 2006, 9, 6, 0, 0, 0 }, "MM");
514 }
515
516 @Test
517 public void testLANG815() {
518 final Calendar calendar = Calendar.getInstance();
519 calendar.set(2012, Calendar.JULY, 30, 0, 0, 0);
520 final long startMillis = calendar.getTimeInMillis();
521
522 calendar.set(2012, Calendar.SEPTEMBER, 8);
523 final long endMillis = calendar.getTimeInMillis();
524
525 assertEquals("1 9", DurationFormatUtils.formatPeriod(startMillis, endMillis, "M d"));
526 }
527
528 @Test
529 public void testLANG981() { // unmatched quote char in lexx
530 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.lexx("'yMdHms''S"));
531 }
532
533 @Test
534 public void testLANG982() { // More than 3 millisecond digits following a second
535 assertEquals("61.999", DurationFormatUtils.formatDuration(61999, "s.S"));
536 assertEquals("1 1999", DurationFormatUtils.formatDuration(61999, "m S"));
537 assertEquals("61.999", DurationFormatUtils.formatDuration(61999, "s.SSS"));
538 assertEquals("1 1999", DurationFormatUtils.formatDuration(61999, "m SSS"));
539 assertEquals("61.0999", DurationFormatUtils.formatDuration(61999, "s.SSSS"));
540 assertEquals("1 1999", DurationFormatUtils.formatDuration(61999, "m SSSS"));
541 assertEquals("61.00999", DurationFormatUtils.formatDuration(61999, "s.SSSSS"));
542 assertEquals("1 01999", DurationFormatUtils.formatDuration(61999, "m SSSSS"));
543 }
544
545 // Takes a minute to run, so generally turned off
546 // public void testBrutally() {
547 // Calendar c = Calendar.getInstance();
548 // c.set(2004, 0, 1, 0, 0, 0);
549 // for (int i=0; i < FOUR_YEARS; i++) {
550 // bruteForce(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), "d", Calendar.DAY_OF_MONTH );
551 // c.add(Calendar.DAY_OF_MONTH, 1);
552 // }
553 // }
554
555 @Test
556 public void testLANG984() { // Long durations
557 assertEquals("0", DurationFormatUtils.formatDuration(0, "S"));
558 assertEquals(Integer.toString(Integer.MAX_VALUE), DurationFormatUtils.formatDuration(Integer.MAX_VALUE, "S"));
559 long maxIntPlus=Integer.MAX_VALUE;
560 maxIntPlus++;
561 assertEquals(Long.toString(maxIntPlus), DurationFormatUtils.formatDuration(maxIntPlus, "S"));
562 assertEquals(Long.toString(Long.MAX_VALUE), DurationFormatUtils.formatDuration(Long.MAX_VALUE, "S"));
355563 }
356564
357565 @Test
403611 final DurationFormatUtils.Token numToken = new DurationFormatUtils.Token(Integer.valueOf(1), 4);
404612 assertEquals(numToken, numToken, "Token with Number value not equal to itself. ");
405613 }
406
407
408 // https://issues.apache.org/bugzilla/show_bug.cgi?id=38401
409 @Test
410 public void testBugzilla38401() {
411 assertEqualDuration( "0000/00/30 16:00:00 000", new int[] { 2006, 0, 26, 18, 47, 34 },
412 new int[] { 2006, 1, 26, 10, 47, 34 }, "yyyy/MM/dd HH:mm:ss SSS");
413 }
414
415 // https://issues.apache.org/jira/browse/LANG-281
416 @Test
417 public void testJiraLang281() {
418 assertEqualDuration( "09", new int[] { 2005, 11, 31, 0, 0, 0 },
419 new int[] { 2006, 9, 6, 0, 0, 0 }, "MM");
420 }
421
422 @Test
423 public void testLANG815() {
424 final Calendar calendar = Calendar.getInstance();
425 calendar.set(2012, Calendar.JULY, 30, 0, 0, 0);
426 final long startMillis = calendar.getTimeInMillis();
427
428 calendar.set(2012, Calendar.SEPTEMBER, 8);
429 final long endMillis = calendar.getTimeInMillis();
430
431 assertEquals("1 9", DurationFormatUtils.formatPeriod(startMillis, endMillis, "M d"));
432 }
433
434614 // Testing the under a day range in DurationFormatUtils.formatPeriod
435615 @Test
436616 public void testLowDurations() {
447627 }
448628 }
449629
450 // Attempting to test edge cases in DurationFormatUtils.formatPeriod
451 @Test
452 public void testEdgeDurations() {
453 // This test case must use a time zone without DST
454 TimeZone.setDefault(FastTimeZone.getGmtTimeZone());
455 assertEqualDuration( "01", new int[] { 2006, 0, 15, 0, 0, 0 },
456 new int[] { 2006, 2, 10, 0, 0, 0 }, "MM");
457 assertEqualDuration( "12", new int[] { 2005, 0, 15, 0, 0, 0 },
458 new int[] { 2006, 0, 15, 0, 0, 0 }, "MM");
459 assertEqualDuration( "12", new int[] { 2005, 0, 15, 0, 0, 0 },
460 new int[] { 2006, 0, 16, 0, 0, 0 }, "MM");
461 assertEqualDuration( "11", new int[] { 2005, 0, 15, 0, 0, 0 },
462 new int[] { 2006, 0, 14, 0, 0, 0 }, "MM");
463
464 assertEqualDuration( "01 26", new int[] { 2006, 0, 15, 0, 0, 0 },
465 new int[] { 2006, 2, 10, 0, 0, 0 }, "MM dd");
466 assertEqualDuration( "54", new int[] { 2006, 0, 15, 0, 0, 0 },
467 new int[] { 2006, 2, 10, 0, 0, 0 }, "dd");
468
469 assertEqualDuration( "09 12", new int[] { 2006, 1, 20, 0, 0, 0 },
470 new int[] { 2006, 11, 4, 0, 0, 0 }, "MM dd");
471 assertEqualDuration( "287", new int[] { 2006, 1, 20, 0, 0, 0 },
472 new int[] { 2006, 11, 4, 0, 0, 0 }, "dd");
473
474 assertEqualDuration( "11 30", new int[] { 2006, 0, 2, 0, 0, 0 },
475 new int[] { 2007, 0, 1, 0, 0, 0 }, "MM dd");
476 assertEqualDuration( "364", new int[] { 2006, 0, 2, 0, 0, 0 },
477 new int[] { 2007, 0, 1, 0, 0, 0 }, "dd");
478
479 assertEqualDuration( "12 00", new int[] { 2006, 0, 1, 0, 0, 0 },
480 new int[] { 2007, 0, 1, 0, 0, 0 }, "MM dd");
481 assertEqualDuration( "365", new int[] { 2006, 0, 1, 0, 0, 0 },
482 new int[] { 2007, 0, 1, 0, 0, 0 }, "dd");
483
484 assertEqualDuration( "31", new int[] { 2006, 0, 1, 0, 0, 0 },
485 new int[] { 2006, 1, 1, 0, 0, 0 }, "dd");
486
487 assertEqualDuration( "92", new int[] { 2005, 9, 1, 0, 0, 0 },
488 new int[] { 2006, 0, 1, 0, 0, 0 }, "dd");
489 assertEqualDuration( "77", new int[] { 2005, 9, 16, 0, 0, 0 },
490 new int[] { 2006, 0, 1, 0, 0, 0 }, "dd");
491
492 // test month larger in start than end
493 assertEqualDuration( "136", new int[] { 2005, 9, 16, 0, 0, 0 },
494 new int[] { 2006, 2, 1, 0, 0, 0 }, "dd");
495 // test when start in leap year
496 assertEqualDuration( "136", new int[] { 2004, 9, 16, 0, 0, 0 },
497 new int[] { 2005, 2, 1, 0, 0, 0 }, "dd");
498 // test when end in leap year
499 assertEqualDuration( "137", new int[] { 2003, 9, 16, 0, 0, 0 },
500 new int[] { 2004, 2, 1, 0, 0, 0 }, "dd");
501 // test when end in leap year but less than end of feb
502 assertEqualDuration( "135", new int[] { 2003, 9, 16, 0, 0, 0 },
503 new int[] { 2004, 1, 28, 0, 0, 0 }, "dd");
504
505 assertEqualDuration( "364", new int[] { 2007, 0, 2, 0, 0, 0 },
506 new int[] { 2008, 0, 1, 0, 0, 0 }, "dd");
507 assertEqualDuration( "729", new int[] { 2006, 0, 2, 0, 0, 0 },
508 new int[] { 2008, 0, 1, 0, 0, 0 }, "dd");
509
510 assertEqualDuration( "365", new int[] { 2007, 2, 2, 0, 0, 0 },
511 new int[] { 2008, 2, 1, 0, 0, 0 }, "dd");
512 assertEqualDuration( "333", new int[] { 2007, 1, 2, 0, 0, 0 },
513 new int[] { 2008, 0, 1, 0, 0, 0 }, "dd");
514
515 assertEqualDuration( "28", new int[] { 2008, 1, 2, 0, 0, 0 },
516 new int[] { 2008, 2, 1, 0, 0, 0 }, "dd");
517 assertEqualDuration( "393", new int[] { 2007, 1, 2, 0, 0, 0 },
518 new int[] { 2008, 2, 1, 0, 0, 0 }, "dd");
519
520 assertEqualDuration( "369", new int[] { 2004, 0, 29, 0, 0, 0 },
521 new int[] { 2005, 1, 1, 0, 0, 0 }, "dd");
522
523 assertEqualDuration( "338", new int[] { 2004, 1, 29, 0, 0, 0 },
524 new int[] { 2005, 1, 1, 0, 0, 0 }, "dd");
525
526 assertEqualDuration( "28", new int[] { 2004, 2, 8, 0, 0, 0 },
527 new int[] { 2004, 3, 5, 0, 0, 0 }, "dd");
528
529 assertEqualDuration( "48", new int[] { 1992, 1, 29, 0, 0, 0 },
530 new int[] { 1996, 1, 29, 0, 0, 0 }, "M");
531
532
533 // this seems odd - and will fail if I throw it in as a brute force
534 // below as it expects the answer to be 12. It's a tricky edge case
535 assertEqualDuration( "11", new int[] { 1996, 1, 29, 0, 0, 0 },
536 new int[] { 1997, 1, 28, 0, 0, 0 }, "M");
537 // again - this seems odd
538 assertEqualDuration( "11 28", new int[] { 1996, 1, 29, 0, 0, 0 },
539 new int[] { 1997, 1, 28, 0, 0, 0 }, "M d");
540
541 }
542
543 @Test
544 public void testLANG984() { // Long durations
545 assertEquals("0", DurationFormatUtils.formatDuration(0, "S"));
546 assertEquals(Integer.toString(Integer.MAX_VALUE), DurationFormatUtils.formatDuration(Integer.MAX_VALUE, "S"));
547 long maxIntPlus=Integer.MAX_VALUE;
548 maxIntPlus++;
549 assertEquals(Long.toString(maxIntPlus), DurationFormatUtils.formatDuration(maxIntPlus, "S"));
550 assertEquals(Long.toString(Long.MAX_VALUE), DurationFormatUtils.formatDuration(Long.MAX_VALUE, "S"));
551 }
552
553 @Test
554 public void testLANG982() { // More than 3 millisecond digits following a second
555 assertEquals("61.999", DurationFormatUtils.formatDuration(61999, "s.S"));
556 assertEquals("1 1999", DurationFormatUtils.formatDuration(61999, "m S"));
557 assertEquals("61.999", DurationFormatUtils.formatDuration(61999, "s.SSS"));
558 assertEquals("1 1999", DurationFormatUtils.formatDuration(61999, "m SSS"));
559 assertEquals("61.0999", DurationFormatUtils.formatDuration(61999, "s.SSSS"));
560 assertEquals("1 1999", DurationFormatUtils.formatDuration(61999, "m SSSS"));
561 assertEquals("61.00999", DurationFormatUtils.formatDuration(61999, "s.SSSSS"));
562 assertEquals("1 01999", DurationFormatUtils.formatDuration(61999, "m SSSSS"));
563 }
564
565 @Test
566 public void testDurationsByBruteForce() {
567 bruteForce(2006, 0, 1, "d", Calendar.DAY_OF_MONTH);
568 bruteForce(2006, 0, 2, "d", Calendar.DAY_OF_MONTH);
569 bruteForce(2007, 1, 2, "d", Calendar.DAY_OF_MONTH);
570 bruteForce(2004, 1, 29, "d", Calendar.DAY_OF_MONTH);
571 bruteForce(1996, 1, 29, "d", Calendar.DAY_OF_MONTH);
572
573 bruteForce(1969, 1, 28, "M", Calendar.MONTH); // tests for 48 years
574 //bruteForce(1996, 1, 29, "M", Calendar.MONTH); // this will fail
575 }
576
577 @Test
578 public void testLANG981() { // unmatched quote char in lexx
579 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.lexx("'yMdHms''S"));
580 }
581
582 private static final int FOUR_YEARS = 365 * 3 + 366;
583
584 // Takes a minute to run, so generally turned off
585 // public void testBrutally() {
586 // Calendar c = Calendar.getInstance();
587 // c.set(2004, 0, 1, 0, 0, 0);
588 // for (int i=0; i < FOUR_YEARS; i++) {
589 // bruteForce(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), "d", Calendar.DAY_OF_MONTH );
590 // c.add(Calendar.DAY_OF_MONTH, 1);
591 // }
592 // }
593
594 private void bruteForce(final int year, final int month, final int day, final String format, final int calendarType) {
595 final String msg = year + "-" + month + "-" + day + " to ";
596 final Calendar c = Calendar.getInstance();
597 c.set(year, month, day, 0, 0, 0);
598 final int[] array1 = new int[] { year, month, day, 0, 0, 0 };
599 final int[] array2 = new int[] { year, month, day, 0, 0, 0 };
600 for (int i=0; i < FOUR_YEARS; i++) {
601 array2[0] = c.get(Calendar.YEAR);
602 array2[1] = c.get(Calendar.MONTH);
603 array2[2] = c.get(Calendar.DAY_OF_MONTH);
604 final String tmpMsg = msg + array2[0] + "-" + array2[1] + "-" + array2[2] + " at ";
605 assertEqualDuration( tmpMsg + i, Integer.toString(i), array1, array2, format );
606 c.add(calendarType, 1);
607 }
608 }
609
610 private void assertEqualDuration(final String expected, final int[] start, final int[] end, final String format) {
611 assertEqualDuration(null, expected, start, end, format);
612 }
613 private void assertEqualDuration(final String message, final String expected, final int[] start, final int[] end, final String format) {
614 final Calendar cal1 = Calendar.getInstance();
615 cal1.set(start[0], start[1], start[2], start[3], start[4], start[5]);
616 cal1.set(Calendar.MILLISECOND, 0);
617 final Calendar cal2 = Calendar.getInstance();
618 cal2.set(end[0], end[1], end[2], end[3], end[4], end[5]);
619 cal2.set(Calendar.MILLISECOND, 0);
620 final long milli1 = cal1.getTime().getTime();
621 final long milli2 = cal2.getTime().getTime();
622 final String result = DurationFormatUtils.formatPeriod(milli1, milli2, format);
623 if (message == null) {
624 assertEquals(expected, result);
625 } else {
626 assertEquals(expected, result, message);
627 }
628 }
629
630630 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.commons.lang3.time;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertTrue;
22
23 import java.time.Duration;
24 import java.util.concurrent.TimeUnit;
25
26 import org.apache.commons.lang3.math.NumberUtils;
27 import org.junit.jupiter.api.Test;
28
29 /**
30 * Tests {@link DurationUtils}.
31 */
32 public class DurationUtilsTest {
33
34 @Test
35 public void testGetNanosOfMilli() {
36 assertEquals(0, DurationUtils.getNanosOfMiili(Duration.ZERO));
37 assertEquals(1, DurationUtils.getNanosOfMiili(Duration.ofNanos(1)));
38 assertEquals(10, DurationUtils.getNanosOfMiili(Duration.ofNanos(10)));
39 assertEquals(100, DurationUtils.getNanosOfMiili(Duration.ofNanos(100)));
40 assertEquals(1_000, DurationUtils.getNanosOfMiili(Duration.ofNanos(1_000)));
41 assertEquals(10_000, DurationUtils.getNanosOfMiili(Duration.ofNanos(10_000)));
42 assertEquals(100_000, DurationUtils.getNanosOfMiili(Duration.ofNanos(100_000)));
43 assertEquals(0, DurationUtils.getNanosOfMiili(Duration.ofNanos(1_000_000)));
44 assertEquals(1, DurationUtils.getNanosOfMiili(Duration.ofNanos(1_000_001)));
45 }
46
47 @Test
48 public void testIsPositive() {
49 assertFalse(DurationUtils.isPositive(Duration.ZERO));
50 assertFalse(DurationUtils.isPositive(Duration.ofMillis(-1)));
51 assertTrue(DurationUtils.isPositive(Duration.ofMillis(1)));
52 }
53
54 @Test
55 public void testLongToIntRangeFit() {
56 assertEquals(0, DurationUtils.LONG_TO_INT_RANGE.fit(0L));
57 //
58 assertEquals(Integer.MIN_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MIN_VALUE));
59 assertEquals(Integer.MIN_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MIN_VALUE - 1));
60 assertEquals(Integer.MIN_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MIN_VALUE - 2));
61 assertEquals(Integer.MAX_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MAX_VALUE));
62 assertEquals(Integer.MAX_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MAX_VALUE + 1));
63 assertEquals(Integer.MAX_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MAX_VALUE + 2));
64 //
65 assertEquals(Integer.MIN_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(Long.MIN_VALUE));
66 assertEquals(Integer.MAX_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(Long.MAX_VALUE));
67 //
68 assertEquals(Short.MIN_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit((long) Short.MIN_VALUE));
69 assertEquals(Short.MAX_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit((long) Short.MAX_VALUE));
70 }
71
72 @Test
73 public void testToDuration() {
74 assertEquals(Duration.ofDays(1), DurationUtils.toDuration(1, TimeUnit.DAYS));
75 assertEquals(Duration.ofHours(1), DurationUtils.toDuration(1, TimeUnit.HOURS));
76 assertEquals(Duration.ofMillis(1), DurationUtils.toDuration(1_000, TimeUnit.MICROSECONDS));
77 assertEquals(Duration.ofMillis(1), DurationUtils.toDuration(1, TimeUnit.MILLISECONDS));
78 assertEquals(Duration.ofMinutes(1), DurationUtils.toDuration(1, TimeUnit.MINUTES));
79 assertEquals(Duration.ofNanos(1), DurationUtils.toDuration(1, TimeUnit.NANOSECONDS));
80 assertEquals(Duration.ofSeconds(1), DurationUtils.toDuration(1, TimeUnit.SECONDS));
81 assertEquals(1, DurationUtils.toDuration(1, TimeUnit.MILLISECONDS).toMillis());
82 assertEquals(-1, DurationUtils.toDuration(-1, TimeUnit.MILLISECONDS).toMillis());
83 assertEquals(0, DurationUtils.toDuration(0, TimeUnit.SECONDS).toMillis());
84 }
85
86 @Test
87 public void testToMillisInt() {
88 assertEquals(0, DurationUtils.toMillisInt(Duration.ZERO));
89 assertEquals(1, DurationUtils.toMillisInt(Duration.ofMillis(1)));
90 //
91 assertEquals(Integer.MIN_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(Integer.MIN_VALUE)));
92 assertEquals(Integer.MAX_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(Integer.MAX_VALUE)));
93 assertEquals(Integer.MAX_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(NumberUtils.LONG_INT_MAX_VALUE + 1)));
94 assertEquals(Integer.MAX_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(NumberUtils.LONG_INT_MAX_VALUE + 2)));
95 assertEquals(Integer.MIN_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(NumberUtils.LONG_INT_MIN_VALUE - 1)));
96 assertEquals(Integer.MIN_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(NumberUtils.LONG_INT_MIN_VALUE - 2)));
97 //
98 assertEquals(Integer.MIN_VALUE, DurationUtils.toMillisInt(Duration.ofNanos(Long.MIN_VALUE)));
99 assertEquals(Integer.MAX_VALUE, DurationUtils.toMillisInt(Duration.ofNanos(Long.MAX_VALUE)));
100 }
101
102 @Test
103 public void testZeroIfNull() {
104 assertEquals(Duration.ZERO, DurationUtils.zeroIfNull(null));
105 assertEquals(Duration.ofDays(1), DurationUtils.zeroIfNull(Duration.ofDays(1)));
106 }
107 }
4444 * @since 2.0
4545 */
4646 public class FastDateFormatTest {
47 /*
48 * Only the cache methods need to be tested here.
49 * The print methods are tested by {@link FastDateFormat_PrinterTest}
50 * and the parse methods are tested by {@link FastDateFormat_ParserTest}
51 */
52 @Test
53 public void test_getInstance() {
54 final FastDateFormat format1 = FastDateFormat.getInstance();
55 final FastDateFormat format2 = FastDateFormat.getInstance();
56 assertSame(format1, format2);
57 }
58
59 @Test
60 public void test_getInstance_String() {
61 final FastDateFormat format1 = FastDateFormat.getInstance("MM/DD/yyyy");
62 final FastDateFormat format2 = FastDateFormat.getInstance("MM-DD-yyyy");
63 final FastDateFormat format3 = FastDateFormat.getInstance("MM-DD-yyyy");
64
65 assertNotSame(format1, format2);
66 assertSame(format2, format3);
67 assertEquals("MM/DD/yyyy", format1.getPattern());
68 assertEquals(TimeZone.getDefault(), format1.getTimeZone());
69 assertEquals(TimeZone.getDefault(), format2.getTimeZone());
70 }
71
72 @DefaultLocale(language = "en", country = "US")
73 @DefaultTimeZone("America/New_York")
74 @Test
75 public void test_getInstance_String_TimeZone() {
76
77 final FastDateFormat format1 = FastDateFormat.getInstance("MM/DD/yyyy",
78 TimeZone.getTimeZone("Atlantic/Reykjavik"));
79 final FastDateFormat format2 = FastDateFormat.getInstance("MM/DD/yyyy");
80 final FastDateFormat format3 = FastDateFormat.getInstance("MM/DD/yyyy", TimeZone.getDefault());
81 final FastDateFormat format4 = FastDateFormat.getInstance("MM/DD/yyyy", TimeZone.getDefault());
82 final FastDateFormat format5 = FastDateFormat.getInstance("MM-DD-yyyy", TimeZone.getDefault());
83 final FastDateFormat format6 = FastDateFormat.getInstance("MM-DD-yyyy");
84
85 assertNotSame(format1, format2);
86 assertEquals(TimeZone.getTimeZone("Atlantic/Reykjavik"), format1.getTimeZone());
87 assertEquals(TimeZone.getDefault(), format2.getTimeZone());
88 assertSame(format3, format4);
89 assertNotSame(format3, format5);
90 assertNotSame(format4, format6);
91 }
92
93 @DefaultLocale(language = "en", country = "US")
94 @Test
95 public void test_getInstance_String_Locale() {
96 final FastDateFormat format1 = FastDateFormat.getInstance("MM/DD/yyyy", Locale.GERMANY);
97 final FastDateFormat format2 = FastDateFormat.getInstance("MM/DD/yyyy");
98 final FastDateFormat format3 = FastDateFormat.getInstance("MM/DD/yyyy", Locale.GERMANY);
99
100 assertNotSame(format1, format2);
101 assertSame(format1, format3);
102 assertEquals(Locale.GERMANY, format1.getLocale());
103 }
104
105 @DefaultLocale(language = "en", country = "US")
106 @Test
107 public void test_changeDefault_Locale_DateInstance() {
108 final FastDateFormat format1 = FastDateFormat.getDateInstance(FastDateFormat.FULL, Locale.GERMANY);
109 final FastDateFormat format2 = FastDateFormat.getDateInstance(FastDateFormat.FULL);
110 Locale.setDefault(Locale.GERMANY);
111 final FastDateFormat format3 = FastDateFormat.getDateInstance(FastDateFormat.FULL);
112
113 assertSame(Locale.GERMANY, format1.getLocale());
114 assertEquals(Locale.US, format2.getLocale());
115 assertSame(Locale.GERMANY, format3.getLocale());
116 assertNotSame(format1, format2);
117 assertNotSame(format2, format3);
118 }
119
120 @DefaultLocale(language = "en", country = "US")
121 @Test
122 public void test_changeDefault_Locale_DateTimeInstance() {
123 final FastDateFormat format1 = FastDateFormat.getDateTimeInstance(FastDateFormat.FULL, FastDateFormat.FULL, Locale.GERMANY);
124 final FastDateFormat format2 = FastDateFormat.getDateTimeInstance(FastDateFormat.FULL, FastDateFormat.FULL);
125 Locale.setDefault(Locale.GERMANY);
126 final FastDateFormat format3 = FastDateFormat.getDateTimeInstance(FastDateFormat.FULL, FastDateFormat.FULL);
127
128 assertSame(Locale.GERMANY, format1.getLocale());
129 assertEquals(Locale.US, format2.getLocale());
130 assertSame(Locale.GERMANY, format3.getLocale());
131 assertNotSame(format1, format2);
132 assertNotSame(format2, format3);
133 }
134
135 @DefaultLocale(language = "en", country = "US")
136 @DefaultTimeZone("America/New_York")
137 @Test
138 public void test_getInstance_String_TimeZone_Locale() {
139 final FastDateFormat format1 = FastDateFormat.getInstance("MM/DD/yyyy",
140 TimeZone.getTimeZone("Atlantic/Reykjavik"), Locale.GERMANY);
141 final FastDateFormat format2 = FastDateFormat.getInstance("MM/DD/yyyy", Locale.GERMANY);
142 final FastDateFormat format3 = FastDateFormat.getInstance("MM/DD/yyyy",
143 TimeZone.getDefault(), Locale.GERMANY);
144
145 assertNotSame(format1, format2);
146 assertEquals(TimeZone.getTimeZone("Atlantic/Reykjavik"), format1.getTimeZone());
147 assertEquals(TimeZone.getDefault(), format2.getTimeZone());
148 assertEquals(TimeZone.getDefault(), format3.getTimeZone());
149 assertEquals(Locale.GERMANY, format1.getLocale());
150 assertEquals(Locale.GERMANY, format2.getLocale());
151 assertEquals(Locale.GERMANY, format3.getLocale());
152 }
153
154 @Test
155 public void testCheckDefaults() {
156 final FastDateFormat format = FastDateFormat.getInstance();
157 final FastDateFormat medium = FastDateFormat.getDateTimeInstance(FastDateFormat.SHORT, FastDateFormat.SHORT);
158 assertEquals(medium, format);
159
160 final SimpleDateFormat sdf = new SimpleDateFormat();
161 assertEquals(sdf.toPattern(), format.getPattern());
162
163 assertEquals(Locale.getDefault(), format.getLocale());
164 assertEquals(TimeZone.getDefault(), format.getTimeZone());
165 }
166
167 @Test
168 public void testCheckDifferingStyles() {
169 final FastDateFormat shortShort = FastDateFormat.getDateTimeInstance(FastDateFormat.SHORT, FastDateFormat.SHORT, Locale.US);
170 final FastDateFormat shortLong = FastDateFormat.getDateTimeInstance(FastDateFormat.SHORT, FastDateFormat.LONG, Locale.US);
171 final FastDateFormat longShort = FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.SHORT, Locale.US);
172 final FastDateFormat longLong = FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.LONG, Locale.US);
173
174 assertNotEquals(shortShort, shortLong);
175 assertNotEquals(shortShort, longShort);
176 assertNotEquals(shortShort, longLong);
177 assertNotEquals(shortLong, longShort);
178 assertNotEquals(shortLong, longLong);
179 assertNotEquals(longShort, longLong);
180 }
181
182 @Test
183 public void testDateDefaults() {
184 assertEquals(FastDateFormat.getDateInstance(FastDateFormat.LONG, Locale.CANADA),
185 FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.CANADA));
186
187 assertEquals(FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York")),
188 FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York"), Locale.getDefault()));
189
190 assertEquals(FastDateFormat.getDateInstance(FastDateFormat.LONG),
191 FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.getDefault()));
192 }
193
194 @Test
195 public void testTimeDefaults() {
196 assertEquals(FastDateFormat.getTimeInstance(FastDateFormat.LONG, Locale.CANADA),
197 FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.CANADA));
198
199 assertEquals(FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York")),
200 FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York"), Locale.getDefault()));
201
202 assertEquals(FastDateFormat.getTimeInstance(FastDateFormat.LONG),
203 FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.getDefault()));
204 }
205
206 @Test
207 public void testTimeDateDefaults() {
208 assertEquals(FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, Locale.CANADA),
209 FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getDefault(), Locale.CANADA));
210
211 assertEquals(FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getTimeZone("America/New_York")),
212 FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getTimeZone("America/New_York"), Locale.getDefault()));
213
214 assertEquals(FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM),
215 FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getDefault(), Locale.getDefault()));
216 }
217
218 @Test
219 public void testParseSync() throws InterruptedException {
220 final String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS";
221 final SimpleDateFormat inner = new SimpleDateFormat(pattern);
222 final Format sdf= new Format() {
223 private static final long serialVersionUID = 1L;
224
225 @Override
226 public StringBuffer format(final Object obj,
227 final StringBuffer toAppendTo,
228 final FieldPosition fieldPosition) {
229 synchronized(this) {
230 return inner.format(obj, toAppendTo, fieldPosition);
231 }
232 }
233
234 @Override
235 public Object parseObject(final String source, final ParsePosition pos) {
236 synchronized(this) {
237 return inner.parseObject(source, pos);
238 }
239 }
240 };
241 final AtomicLongArray sdfTime= measureTime(sdf, sdf);
242
243 final Format fdf = FastDateFormat.getInstance(pattern);
244 final AtomicLongArray fdfTime= measureTime(fdf, fdf);
245
246 //System.out.println(">>FastDateFormatTest: FastDatePrinter:"+fdfTime.get(0)+" SimpleDateFormat:"+sdfTime.get(0));
247 //System.out.println(">>FastDateFormatTest: FastDateParser:"+fdfTime.get(1)+" SimpleDateFormat:"+sdfTime.get(1));
248 }
249
25047 private static final int NTHREADS = 10;
48
25149 private static final int NROUNDS = 10000;
25250
25351 private AtomicLongArray measureTime(final Format printer, final Format parser) throws InterruptedException {
26159 try {
26260 final Date date = new Date();
26361
264 final long t0 = System.currentTimeMillis();
62 final long t0Millis = System.currentTimeMillis();
26563 final String formattedDate = printer.format(date);
266 totalElapsed.addAndGet(0, System.currentTimeMillis() - t0);
267
268 final long t1 = System.currentTimeMillis();
64 totalElapsed.addAndGet(0, System.currentTimeMillis() - t0Millis);
65
66 final long t1Millis = System.currentTimeMillis();
26967 final Object pd = parser.parseObject(formattedDate);
270 totalElapsed.addAndGet(1, System.currentTimeMillis() - t1);
68 totalElapsed.addAndGet(1, System.currentTimeMillis() - t1Millis);
27169
27270 if (!date.equals(pd)) {
27371 failures.incrementAndGet();
29391 return totalElapsed;
29492 }
29593
94 @DefaultLocale(language = "en", country = "US")
95 @Test
96 public void test_changeDefault_Locale_DateInstance() {
97 final FastDateFormat format1 = FastDateFormat.getDateInstance(FastDateFormat.FULL, Locale.GERMANY);
98 final FastDateFormat format2 = FastDateFormat.getDateInstance(FastDateFormat.FULL);
99 Locale.setDefault(Locale.GERMANY);
100 final FastDateFormat format3 = FastDateFormat.getDateInstance(FastDateFormat.FULL);
101
102 assertSame(Locale.GERMANY, format1.getLocale());
103 assertEquals(Locale.US, format2.getLocale());
104 assertSame(Locale.GERMANY, format3.getLocale());
105 assertNotSame(format1, format2);
106 assertNotSame(format2, format3);
107 }
108
109 @DefaultLocale(language = "en", country = "US")
110 @Test
111 public void test_changeDefault_Locale_DateTimeInstance() {
112 final FastDateFormat format1 = FastDateFormat.getDateTimeInstance(FastDateFormat.FULL, FastDateFormat.FULL, Locale.GERMANY);
113 final FastDateFormat format2 = FastDateFormat.getDateTimeInstance(FastDateFormat.FULL, FastDateFormat.FULL);
114 Locale.setDefault(Locale.GERMANY);
115 final FastDateFormat format3 = FastDateFormat.getDateTimeInstance(FastDateFormat.FULL, FastDateFormat.FULL);
116
117 assertSame(Locale.GERMANY, format1.getLocale());
118 assertEquals(Locale.US, format2.getLocale());
119 assertSame(Locale.GERMANY, format3.getLocale());
120 assertNotSame(format1, format2);
121 assertNotSame(format2, format3);
122 }
123
124 /*
125 * Only the cache methods need to be tested here.
126 * The print methods are tested by {@link FastDateFormat_PrinterTest}
127 * and the parse methods are tested by {@link FastDateFormat_ParserTest}
128 */
129 @Test
130 public void test_getInstance() {
131 final FastDateFormat format1 = FastDateFormat.getInstance();
132 final FastDateFormat format2 = FastDateFormat.getInstance();
133 assertSame(format1, format2);
134 }
135
136 @Test
137 public void test_getInstance_String() {
138 final FastDateFormat format1 = FastDateFormat.getInstance("MM/DD/yyyy");
139 final FastDateFormat format2 = FastDateFormat.getInstance("MM-DD-yyyy");
140 final FastDateFormat format3 = FastDateFormat.getInstance("MM-DD-yyyy");
141
142 assertNotSame(format1, format2);
143 assertSame(format2, format3);
144 assertEquals("MM/DD/yyyy", format1.getPattern());
145 assertEquals(TimeZone.getDefault(), format1.getTimeZone());
146 assertEquals(TimeZone.getDefault(), format2.getTimeZone());
147 }
148
149 @DefaultLocale(language = "en", country = "US")
150 @Test
151 public void test_getInstance_String_Locale() {
152 final FastDateFormat format1 = FastDateFormat.getInstance("MM/DD/yyyy", Locale.GERMANY);
153 final FastDateFormat format2 = FastDateFormat.getInstance("MM/DD/yyyy");
154 final FastDateFormat format3 = FastDateFormat.getInstance("MM/DD/yyyy", Locale.GERMANY);
155
156 assertNotSame(format1, format2);
157 assertSame(format1, format3);
158 assertEquals(Locale.GERMANY, format1.getLocale());
159 }
160
161 @DefaultLocale(language = "en", country = "US")
162 @DefaultTimeZone("America/New_York")
163 @Test
164 public void test_getInstance_String_TimeZone() {
165
166 final FastDateFormat format1 = FastDateFormat.getInstance("MM/DD/yyyy",
167 TimeZone.getTimeZone("Atlantic/Reykjavik"));
168 final FastDateFormat format2 = FastDateFormat.getInstance("MM/DD/yyyy");
169 final FastDateFormat format3 = FastDateFormat.getInstance("MM/DD/yyyy", TimeZone.getDefault());
170 final FastDateFormat format4 = FastDateFormat.getInstance("MM/DD/yyyy", TimeZone.getDefault());
171 final FastDateFormat format5 = FastDateFormat.getInstance("MM-DD-yyyy", TimeZone.getDefault());
172 final FastDateFormat format6 = FastDateFormat.getInstance("MM-DD-yyyy");
173
174 assertNotSame(format1, format2);
175 assertEquals(TimeZone.getTimeZone("Atlantic/Reykjavik"), format1.getTimeZone());
176 assertEquals(TimeZone.getDefault(), format2.getTimeZone());
177 assertSame(format3, format4);
178 assertNotSame(format3, format5);
179 assertNotSame(format4, format6);
180 }
181
182 @DefaultLocale(language = "en", country = "US")
183 @DefaultTimeZone("America/New_York")
184 @Test
185 public void test_getInstance_String_TimeZone_Locale() {
186 final FastDateFormat format1 = FastDateFormat.getInstance("MM/DD/yyyy",
187 TimeZone.getTimeZone("Atlantic/Reykjavik"), Locale.GERMANY);
188 final FastDateFormat format2 = FastDateFormat.getInstance("MM/DD/yyyy", Locale.GERMANY);
189 final FastDateFormat format3 = FastDateFormat.getInstance("MM/DD/yyyy",
190 TimeZone.getDefault(), Locale.GERMANY);
191
192 assertNotSame(format1, format2);
193 assertEquals(TimeZone.getTimeZone("Atlantic/Reykjavik"), format1.getTimeZone());
194 assertEquals(TimeZone.getDefault(), format2.getTimeZone());
195 assertEquals(TimeZone.getDefault(), format3.getTimeZone());
196 assertEquals(Locale.GERMANY, format1.getLocale());
197 assertEquals(Locale.GERMANY, format2.getLocale());
198 assertEquals(Locale.GERMANY, format3.getLocale());
199 }
200
201 @Test
202 public void testCheckDefaults() {
203 final FastDateFormat format = FastDateFormat.getInstance();
204 final FastDateFormat medium = FastDateFormat.getDateTimeInstance(FastDateFormat.SHORT, FastDateFormat.SHORT);
205 assertEquals(medium, format);
206
207 final SimpleDateFormat sdf = new SimpleDateFormat();
208 assertEquals(sdf.toPattern(), format.getPattern());
209
210 assertEquals(Locale.getDefault(), format.getLocale());
211 assertEquals(TimeZone.getDefault(), format.getTimeZone());
212 }
213
214 @Test
215 public void testCheckDifferingStyles() {
216 final FastDateFormat shortShort = FastDateFormat.getDateTimeInstance(FastDateFormat.SHORT, FastDateFormat.SHORT, Locale.US);
217 final FastDateFormat shortLong = FastDateFormat.getDateTimeInstance(FastDateFormat.SHORT, FastDateFormat.LONG, Locale.US);
218 final FastDateFormat longShort = FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.SHORT, Locale.US);
219 final FastDateFormat longLong = FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.LONG, Locale.US);
220
221 assertNotEquals(shortShort, shortLong);
222 assertNotEquals(shortShort, longShort);
223 assertNotEquals(shortShort, longLong);
224 assertNotEquals(shortLong, longShort);
225 assertNotEquals(shortLong, longLong);
226 assertNotEquals(longShort, longLong);
227 }
228
229 @Test
230 public void testDateDefaults() {
231 assertEquals(FastDateFormat.getDateInstance(FastDateFormat.LONG, Locale.CANADA),
232 FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.CANADA));
233
234 assertEquals(FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York")),
235 FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York"), Locale.getDefault()));
236
237 assertEquals(FastDateFormat.getDateInstance(FastDateFormat.LONG),
238 FastDateFormat.getDateInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.getDefault()));
239 }
240
241 @Test
242 public void testLANG_1152() {
243 final TimeZone utc = FastTimeZone.getGmtTimeZone();
244 final Date date = new Date(Long.MAX_VALUE);
245
246 String dateAsString = FastDateFormat.getInstance("yyyy-MM-dd", utc, Locale.US).format(date);
247 assertEquals("292278994-08-17", dateAsString);
248
249 dateAsString = FastDateFormat.getInstance("dd/MM/yyyy", utc, Locale.US).format(date);
250 assertEquals("17/08/292278994", dateAsString);
251 }
252 @Test
253 public void testLANG_1267() {
254 FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
255 }
256
296257 /**
297258 * According to LANG-954 (https://issues.apache.org/jira/browse/LANG-954) this is broken in Android 2.1.
298259 */
303264 }
304265
305266 @Test
306 public void testLANG_1152() {
307 final TimeZone utc = FastTimeZone.getGmtTimeZone();
308 final Date date = new Date(Long.MAX_VALUE);
309
310 String dateAsString = FastDateFormat.getInstance("yyyy-MM-dd", utc, Locale.US).format(date);
311 assertEquals("292278994-08-17", dateAsString);
312
313 dateAsString = FastDateFormat.getInstance("dd/MM/yyyy", utc, Locale.US).format(date);
314 assertEquals("17/08/292278994", dateAsString);
315 }
316
317 @Test
318 public void testLANG_1267() {
319 FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
267 public void testParseSync() throws InterruptedException {
268 final String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS";
269 final SimpleDateFormat inner = new SimpleDateFormat(pattern);
270 final Format sdf= new Format() {
271 private static final long serialVersionUID = 1L;
272
273 @Override
274 public StringBuffer format(final Object obj,
275 final StringBuffer toAppendTo,
276 final FieldPosition fieldPosition) {
277 synchronized(this) {
278 return inner.format(obj, toAppendTo, fieldPosition);
279 }
280 }
281
282 @Override
283 public Object parseObject(final String source, final ParsePosition pos) {
284 synchronized(this) {
285 return inner.parseObject(source, pos);
286 }
287 }
288 };
289 final AtomicLongArray sdfTime= measureTime(sdf, sdf);
290
291 final Format fdf = FastDateFormat.getInstance(pattern);
292 final AtomicLongArray fdfTime= measureTime(fdf, fdf);
293
294 //System.out.println(">>FastDateFormatTest: FastDatePrinter:"+fdfTime.get(0)+" SimpleDateFormat:"+sdfTime.get(0));
295 //System.out.println(">>FastDateFormatTest: FastDateParser:"+fdfTime.get(1)+" SimpleDateFormat:"+sdfTime.get(1));
296 }
297
298 @Test
299 public void testTimeDateDefaults() {
300 assertEquals(FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, Locale.CANADA),
301 FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getDefault(), Locale.CANADA));
302
303 assertEquals(FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getTimeZone("America/New_York")),
304 FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getTimeZone("America/New_York"), Locale.getDefault()));
305
306 assertEquals(FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM),
307 FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.MEDIUM, TimeZone.getDefault(), Locale.getDefault()));
308 }
309
310 @Test
311 public void testTimeDefaults() {
312 assertEquals(FastDateFormat.getTimeInstance(FastDateFormat.LONG, Locale.CANADA),
313 FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.CANADA));
314
315 assertEquals(FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York")),
316 FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getTimeZone("America/New_York"), Locale.getDefault()));
317
318 assertEquals(FastDateFormat.getTimeInstance(FastDateFormat.LONG),
319 FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.getDefault()));
320320 }
321321 }
+0
-33
src/test/java/org/apache/commons/lang3/time/FastDateFormat_ParserTest.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.commons.lang3.time;
17
18 import java.util.Locale;
19 import java.util.TimeZone;
20
21 /**
22 * Unit tests for the parse methods of FastDateFormat
23 *
24 * @since 3.2
25 */
26 public class FastDateFormat_ParserTest extends FastDateParserTest {
27
28 @Override
29 protected DateParser getInstance(final String format, final TimeZone timeZone, final Locale locale) {
30 return FastDateFormat.getInstance(format, timeZone, locale);
31 }
32 }
3737 */
3838 public class FastDateParserSDFTest {
3939
40 private static final TimeZone timeZone = TimeZone.getDefault();
41
4042 public static Stream<Arguments> data() {
4143 return Stream.of(
4244 // General Time zone tests
101103 );
102104 }
103105
104 private static final TimeZone timeZone = TimeZone.getDefault();
105
106 @ParameterizedTest
107 @MethodSource("data")
108 public void testOriginal(final String format, final String input, final Locale locale, final boolean valid) {
109 checkParse(input, format, locale, valid);
110 }
111
112 @ParameterizedTest
113 @MethodSource("data")
114 public void testOriginalPP(final String format, final String input, final Locale locale, final boolean valid) {
115 checkParsePosition(input, format, locale, valid);
116 }
117
118 @ParameterizedTest
119 @MethodSource("data")
120 public void testUpperCase(final String format, final String input, final Locale locale, final boolean valid) {
121 checkParse(input.toUpperCase(locale), format, locale, valid);
122 }
123
124 @ParameterizedTest
125 @MethodSource("data")
126 public void testUpperCasePP(final String format, final String input, final Locale locale, final boolean valid) {
127 checkParsePosition(input.toUpperCase(locale), format, locale, valid);
128 }
129
130 @ParameterizedTest
131 @MethodSource("data")
132 public void testLowerCase(final String format, final String input, final Locale locale, final boolean valid) {
133 checkParse(input.toLowerCase(locale), format, locale, valid);
134 }
135
136 @ParameterizedTest
137 @MethodSource("data")
138 public void testLowerCasePP(final String format, final String input, final Locale locale, final boolean valid) {
139 checkParsePosition(input.toLowerCase(locale), format, locale, valid);
140 }
141
142106 private void checkParse(final String formattedDate, final String format, final Locale locale, final boolean valid) {
143107 final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
144108 sdf.setTimeZone(timeZone);
175139 assertEquals(sdfE, fdfE, locale.toString()+" "+formattedDate + " expected same Exception ");
176140 }
177141 }
142
178143 private void checkParsePosition(final String formattedDate, final String format, final Locale locale, final boolean valid) {
179144 final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
180145 sdf.setTimeZone(timeZone);
213178 "FDF error index ("+ fdferrorIndex + ") should approximate SDF index (" + sdferrorIndex + ")");
214179 }
215180 }
181
182 @ParameterizedTest
183 @MethodSource("data")
184 public void testLowerCase(final String format, final String input, final Locale locale, final boolean valid) {
185 checkParse(input.toLowerCase(locale), format, locale, valid);
186 }
187
188 @ParameterizedTest
189 @MethodSource("data")
190 public void testLowerCasePP(final String format, final String input, final Locale locale, final boolean valid) {
191 checkParsePosition(input.toLowerCase(locale), format, locale, valid);
192 }
193
194 @ParameterizedTest
195 @MethodSource("data")
196 public void testOriginal(final String format, final String input, final Locale locale, final boolean valid) {
197 checkParse(input, format, locale, valid);
198 }
199
200 @ParameterizedTest
201 @MethodSource("data")
202 public void testOriginalPP(final String format, final String input, final Locale locale, final boolean valid) {
203 checkParsePosition(input, format, locale, valid);
204 }
205
206 @ParameterizedTest
207 @MethodSource("data")
208 public void testUpperCase(final String format, final String input, final Locale locale, final boolean valid) {
209 checkParse(input.toUpperCase(locale), format, locale, valid);
210 }
211 @ParameterizedTest
212 @MethodSource("data")
213 public void testUpperCasePP(final String format, final String input, final Locale locale, final boolean valid) {
214 checkParsePosition(input.toUpperCase(locale), format, locale, valid);
215 }
216216 }
1818 import static org.junit.jupiter.api.Assertions.assertEquals;
1919 import static org.junit.jupiter.api.Assertions.assertFalse;
2020 import static org.junit.jupiter.api.Assertions.assertNotEquals;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
2122 import static org.junit.jupiter.api.Assertions.assertThrows;
2223 import static org.junit.jupiter.api.Assertions.assertTrue;
2324 import static org.junit.jupiter.api.Assertions.fail;
3334 import java.util.Locale;
3435 import java.util.Map;
3536 import java.util.TimeZone;
37 import java.util.stream.Stream;
3638
3739 import org.apache.commons.lang3.LocaleUtils;
3840 import org.apache.commons.lang3.SerializationUtils;
41 import org.apache.commons.lang3.SystemUtils;
42 import org.apache.commons.lang3.function.TriFunction;
3943 import org.junit.jupiter.api.Test;
44 import org.junit.jupiter.params.ParameterizedTest;
45 import org.junit.jupiter.params.provider.Arguments;
46 import org.junit.jupiter.params.provider.MethodSource;
4047
4148 /**
4249 * Unit tests {@link org.apache.commons.lang3.time.FastDateParser}.
4451 * @since 3.2
4552 */
4653 public class FastDateParserTest {
47 private static final String SHORT_FORMAT_NOERA = "y/M/d/h/a/m/s/E";
48 private static final String LONG_FORMAT_NOERA = "yyyy/MMMM/dddd/hhhh/mmmm/ss/aaaa/EEEE";
49 private static final String SHORT_FORMAT = "G/" + SHORT_FORMAT_NOERA;
50 private static final String LONG_FORMAT = "GGGG/" + LONG_FORMAT_NOERA;
54
55 private enum Expected1806 {
56 India(INDIA, "+05", "+0530", "+05:30", true), Greenwich(GMT, "Z", "Z", "Z", false),
57 NewYork(NEW_YORK, "-05", "-0500", "-05:00", false);
58
59 final TimeZone zone;
60
61 final String one;
62 final String two;
63 final String three;
64 final long offset;
65
66 Expected1806(final TimeZone zone, final String one, final String two, final String three,
67 final boolean hasHalfHourOffset) {
68 this.zone = zone;
69 this.one = one;
70 this.two = two;
71 this.three = three;
72 this.offset = hasHalfHourOffset ? 30 * 60 * 1000 : 0;
73 }
74 }
75
76 static final String DATE_PARSER_PARAMETERS = "dateParserParameters";
77
78 static final String SHORT_FORMAT_NOERA = "y/M/d/h/a/m/s/E";
79
80 static final String LONG_FORMAT_NOERA = "yyyy/MMMM/dddd/hhhh/mmmm/ss/aaaa/EEEE";
81 static final String SHORT_FORMAT = "G/" + SHORT_FORMAT_NOERA;
82 static final String LONG_FORMAT = "GGGG/" + LONG_FORMAT_NOERA;
5183
5284 private static final String yMdHmsSZ = "yyyy-MM-dd'T'HH:mm:ss.SSS Z";
5385 private static final String DMY_DOT = "dd.MM.yyyy";
5789
5890 private static final TimeZone REYKJAVIK = TimeZone.getTimeZone("Atlantic/Reykjavik");
5991 private static final TimeZone NEW_YORK = TimeZone.getTimeZone("America/New_York");
60 private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
92 static final TimeZone GMT = TimeZone.getTimeZone("GMT");
6193 private static final TimeZone INDIA = TimeZone.getTimeZone("Asia/Calcutta");
6294
6395 private static final Locale SWEDEN = new Locale("sv", "SE");
6496
97 static void checkParse(final Locale locale, final Calendar cal, final SimpleDateFormat simpleDateFormat,
98 final DateParser dateParser) {
99 final String formattedDate = simpleDateFormat.format(cal.getTime());
100 checkParse(locale, simpleDateFormat, dateParser, formattedDate, formattedDate);
101 checkParse(locale, simpleDateFormat, dateParser, formattedDate.toLowerCase(locale), formattedDate);
102 checkParse(locale, simpleDateFormat, dateParser, formattedDate.toUpperCase(locale), formattedDate);
103 }
104
105 static void checkParse(final Locale locale, final SimpleDateFormat simpleDateFormat, final DateParser dateParser,
106 final String formattedDate, final String originalFormattedDate) {
107 try {
108 final Date expectedTime = simpleDateFormat.parse(formattedDate);
109 final Date actualTime = dateParser.parse(formattedDate);
110 assertEquals(expectedTime, actualTime,
111 "locale: " + locale + ", formattedDate: '" + formattedDate + "', originalFormattedDate: '"
112 + originalFormattedDate + ", simpleDateFormat.pattern: '" + simpleDateFormat + "', Java: "
113 + SystemUtils.JAVA_RUNTIME_VERSION + "\n");
114 } catch (final Exception e) {
115 fail("locale: " + locale + ", formattedDate: '" + formattedDate + "', error : " + e + "\n", e);
116 }
117 }
118
119 static Stream<Arguments> dateParserParameters() {
120 return Stream.of(
121 // @formatter:off
122 Arguments.of((TriFunction<String, TimeZone, Locale, DateParser>) (format, timeZone, locale)
123 -> new FastDateParser(format, timeZone, locale, null)),
124 Arguments.of((TriFunction<String, TimeZone, Locale, DateParser>) FastDateFormat::getInstance)
125 // @formatter:on
126 );
127 }
128
129 private static Calendar initializeCalendar(final TimeZone timeZone) {
130 final Calendar cal = Calendar.getInstance(timeZone);
131 cal.set(Calendar.YEAR, 2001);
132 cal.set(Calendar.MONTH, 1); // not daylight savings
133 cal.set(Calendar.DAY_OF_MONTH, 4);
134 cal.set(Calendar.HOUR_OF_DAY, 12);
135 cal.set(Calendar.MINUTE, 8);
136 cal.set(Calendar.SECOND, 56);
137 cal.set(Calendar.MILLISECOND, 235);
138 return cal;
139 }
140
141 private final TriFunction<String, TimeZone, Locale, DateParser> dateParserProvider = (format, timeZone,
142 locale) -> new FastDateParser(format, timeZone, locale, null);
143
144 private DateParser getDateInstance(final int dateStyle, final Locale locale) {
145 return getInstance(null, FormatCache.getPatternForStyle(Integer.valueOf(dateStyle), null, locale),
146 TimeZone.getDefault(), Locale.getDefault());
147 }
148
149 private Calendar getEraStart(int year, final TimeZone zone, final Locale locale) {
150 final Calendar cal = Calendar.getInstance(zone, locale);
151 cal.clear();
152
153 // http://docs.oracle.com/javase/6/docs/technotes/guides/intl/calendar.doc.html
154 if (locale.equals(FastDateParser.JAPANESE_IMPERIAL)) {
155 if (year < 1868) {
156 cal.set(Calendar.ERA, 0);
157 cal.set(Calendar.YEAR, 1868 - year);
158 }
159 } else {
160 if (year < 0) {
161 cal.set(Calendar.ERA, GregorianCalendar.BC);
162 year = -year;
163 }
164 cal.set(Calendar.YEAR, year / 100 * 100);
165 }
166 return cal;
167 }
168
65169 DateParser getInstance(final String format) {
66 return getInstance(format, TimeZone.getDefault(), Locale.getDefault());
67 }
68
69 private DateParser getDateInstance(final int dateStyle, final Locale locale) {
70 return getInstance(FormatCache.getPatternForStyle(Integer.valueOf(dateStyle), null, locale), TimeZone.getDefault(), Locale.getDefault());
71 }
72
73 private DateParser getInstance(final String format, final Locale locale) {
74 return getInstance(format, TimeZone.getDefault(), locale);
170 return getInstance(null, format, TimeZone.getDefault(), Locale.getDefault());
171 }
172
173 DateParser getInstance(final String format, final Locale locale) {
174 return getInstance(null, format, TimeZone.getDefault(), locale);
75175 }
76176
77177 private DateParser getInstance(final String format, final TimeZone timeZone) {
78 return getInstance(format, timeZone, Locale.getDefault());
178 return getInstance(null, format, timeZone, Locale.getDefault());
79179 }
80180
81181 /**
82182 * Override this method in derived tests to change the construction of instances
83183 *
184 * @param dpProvider TODO
84185 * @param format the format string to use
85186 * @param timeZone the time zone to use
86187 * @param locale the locale to use
87188 *
88189 * @return the DateParser instance to use for testing
89190 */
90 protected DateParser getInstance(final String format, final TimeZone timeZone, final Locale locale) {
91 return new FastDateParser(format, timeZone, locale, null);
92 }
93
94 @Test
95 public void test_Equality_Hash() {
96 final DateParser[] parsers= {
97 getInstance(yMdHmsSZ, NEW_YORK, Locale.US),
98 getInstance(DMY_DOT, NEW_YORK, Locale.US),
99 getInstance(YMD_SLASH, NEW_YORK, Locale.US),
100 getInstance(MDY_DASH, NEW_YORK, Locale.US),
101 getInstance(MDY_SLASH, NEW_YORK, Locale.US),
102 getInstance(MDY_SLASH, REYKJAVIK, Locale.US),
103 getInstance(MDY_SLASH, REYKJAVIK, SWEDEN)
104 };
105
106 final Map<DateParser, Integer> map= new HashMap<>();
107 int i= 0;
108 for (final DateParser parser:parsers) {
191 protected DateParser getInstance(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider,
192 final String format, final TimeZone timeZone, final Locale locale) {
193 return (dpProvider == null ? this.dateParserProvider : dpProvider).apply(format, timeZone, locale);
194 }
195
196 @ParameterizedTest
197 @MethodSource(DATE_PARSER_PARAMETERS)
198 public void test_Equality_Hash(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider) {
199 final DateParser[] parsers = {getInstance(dpProvider, yMdHmsSZ, NEW_YORK, Locale.US),
200 getInstance(dpProvider, DMY_DOT, NEW_YORK, Locale.US),
201 getInstance(dpProvider, YMD_SLASH, NEW_YORK, Locale.US),
202 getInstance(dpProvider, MDY_DASH, NEW_YORK, Locale.US),
203 getInstance(dpProvider, MDY_SLASH, NEW_YORK, Locale.US),
204 getInstance(dpProvider, MDY_SLASH, REYKJAVIK, Locale.US),
205 getInstance(dpProvider, MDY_SLASH, REYKJAVIK, SWEDEN)};
206
207 final Map<DateParser, Integer> map = new HashMap<>();
208 int i = 0;
209 for (final DateParser parser : parsers) {
109210 map.put(parser, Integer.valueOf(i++));
110211 }
111212
112 i= 0;
113 for (final DateParser parser:parsers) {
213 i = 0;
214 for (final DateParser parser : parsers) {
114215 assertEquals(i++, map.get(parser).intValue());
115216 }
116217 }
117218
118219 @Test
119 public void testParseZone() throws ParseException {
120 final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
121 cal.clear();
122 cal.set(2003, Calendar.JULY, 10, 16, 33, 20);
123
124 final DateParser fdf = getInstance(yMdHmsSZ, NEW_YORK, Locale.US);
125
126 assertEquals(cal.getTime(), fdf.parse("2003-07-10T15:33:20.000 -0500"));
127 assertEquals(cal.getTime(), fdf.parse("2003-07-10T15:33:20.000 GMT-05:00"));
128 assertEquals(cal.getTime(), fdf.parse("2003-07-10T16:33:20.000 Eastern Daylight Time"));
129 assertEquals(cal.getTime(), fdf.parse("2003-07-10T16:33:20.000 EDT"));
130
131 cal.setTimeZone(TimeZone.getTimeZone("GMT-3"));
132 cal.set(2003, Calendar.FEBRUARY, 10, 9, 0, 0);
133
134 assertEquals(cal.getTime(), fdf.parse("2003-02-10T09:00:00.000 -0300"));
135
136 cal.setTimeZone(TimeZone.getTimeZone("GMT+5"));
137 cal.set(2003, Calendar.FEBRUARY, 10, 15, 5, 6);
138
139 assertEquals(cal.getTime(), fdf.parse("2003-02-10T15:05:06.000 +0500"));
140 }
141
142 @Test
143 public void testParseLongShort() throws ParseException {
144 final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
145 cal.clear();
146 cal.set(2003, Calendar.FEBRUARY, 10, 15, 33, 20);
147 cal.set(Calendar.MILLISECOND, 989);
148 cal.setTimeZone(NEW_YORK);
149
150 DateParser fdf = getInstance("yyyy GGGG MMMM dddd aaaa EEEE HHHH mmmm ssss SSSS ZZZZ", NEW_YORK, Locale.US);
151
152 assertEquals(cal.getTime(), fdf.parse("2003 AD February 0010 PM Monday 0015 0033 0020 0989 GMT-05:00"));
153 cal.set(Calendar.ERA, GregorianCalendar.BC);
154
155 final Date parse = fdf.parse("2003 BC February 0010 PM Saturday 0015 0033 0020 0989 GMT-05:00");
156 assertEquals(cal.getTime(), parse);
157
158 fdf = getInstance("y G M d a E H m s S Z", NEW_YORK, Locale.US);
159 assertEquals(cal.getTime(), fdf.parse("03 BC 2 10 PM Sat 15 33 20 989 -0500"));
160
161 cal.set(Calendar.ERA, GregorianCalendar.AD);
162 assertEquals(cal.getTime(), fdf.parse("03 AD 2 10 PM Saturday 15 33 20 989 -0500"));
163 }
164
165 @Test
166 public void testAmPm() throws ParseException {
167 final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
168 cal.clear();
169
170 final DateParser h = getInstance("yyyy-MM-dd hh a mm:ss", NEW_YORK, Locale.US);
171 final DateParser K = getInstance("yyyy-MM-dd KK a mm:ss", NEW_YORK, Locale.US);
172 final DateParser k = getInstance("yyyy-MM-dd kk:mm:ss", NEW_YORK, Locale.US);
173 final DateParser H = getInstance("yyyy-MM-dd HH:mm:ss", NEW_YORK, Locale.US);
220 public void test1806() throws ParseException {
221 final String formatStub = "yyyy-MM-dd'T'HH:mm:ss.SSS";
222 final String dateStub = "2001-02-04T12:08:56.235";
223
224 for (final Expected1806 trial : Expected1806.values()) {
225 final Calendar cal = initializeCalendar(trial.zone);
226
227 final String message = trial.zone.getDisplayName() + ";";
228
229 DateParser parser = getInstance(formatStub + "X", trial.zone);
230 assertEquals(cal.getTime().getTime(), parser.parse(dateStub + trial.one).getTime() - trial.offset,
231 message + trial.one);
232
233 parser = getInstance(formatStub + "XX", trial.zone);
234 assertEquals(cal.getTime(), parser.parse(dateStub + trial.two), message + trial.two);
235
236 parser = getInstance(formatStub + "XXX", trial.zone);
237 assertEquals(cal.getTime(), parser.parse(dateStub + trial.three), message + trial.three);
238 }
239 }
240
241 @Test
242 public void test1806Argument() {
243 assertThrows(IllegalArgumentException.class, () -> getInstance("XXXX"));
244 }
245
246 @ParameterizedTest
247 @MethodSource(DATE_PARSER_PARAMETERS)
248 public void testAmPm(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider) throws ParseException {
249 final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
250 cal.clear();
251
252 final DateParser h = getInstance(dpProvider, "yyyy-MM-dd hh a mm:ss", NEW_YORK, Locale.US);
253 final DateParser K = getInstance(dpProvider, "yyyy-MM-dd KK a mm:ss", NEW_YORK, Locale.US);
254 final DateParser k = getInstance(dpProvider, "yyyy-MM-dd kk:mm:ss", NEW_YORK, Locale.US);
255 final DateParser H = getInstance(dpProvider, "yyyy-MM-dd HH:mm:ss", NEW_YORK, Locale.US);
174256
175257 cal.set(2010, Calendar.AUGUST, 1, 0, 33, 20);
176258 assertEquals(cal.getTime(), h.parse("2010-08-01 12 AM 33:20"));
197279 assertEquals(cal.getTime(), H.parse("2010-08-01 12:33:20"));
198280 }
199281
200 private Calendar getEraStart(int year, final TimeZone zone, final Locale locale) {
201 final Calendar cal = Calendar.getInstance(zone, locale);
202 cal.clear();
203
204 // http://docs.oracle.com/javase/6/docs/technotes/guides/intl/calendar.doc.html
205 if (locale.equals(FastDateParser.JAPANESE_IMPERIAL)) {
206 if (year < 1868) {
207 cal.set(Calendar.ERA, 0);
208 cal.set(Calendar.YEAR, 1868-year);
209 }
210 } else {
211 if (year < 0) {
212 cal.set(Calendar.ERA, GregorianCalendar.BC);
213 year= -year;
214 }
215 cal.set(Calendar.YEAR, year/100 * 100);
216 }
217 return cal;
218 }
219
220 private void validateSdfFormatFdpParseEquality(final String format, final Locale locale, final TimeZone tz, final DateParser fdp, final Date in, final int year, final Date cs) throws ParseException {
221 final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
222 sdf.setTimeZone(tz);
223 if (format.equals(SHORT_FORMAT)) {
224 sdf.set2DigitYearStart( cs );
225 }
226 final String fmt = sdf.format(in);
227 try {
228 final Date out = fdp.parse(fmt);
229 assertEquals(in, out, locale.toString()+" "+in+" "+ format+ " "+tz.getID());
230 } catch (final ParseException pe) {
231 if (year >= 1868 || !locale.getCountry().equals("JP")) {// LANG-978
232 throw pe;
233 }
234 }
235 }
236
237 @Test
238 // Check that all Locales can parse the formats we use
239 public void testParses() throws Exception {
240 for (final String format : new String[]{LONG_FORMAT, SHORT_FORMAT}) {
241 for (final Locale locale : Locale.getAvailableLocales()) {
242 for (final TimeZone tz : new TimeZone[]{NEW_YORK, REYKJAVIK, GMT}) {
243 for (final int year : new int[]{2003, 1940, 1868, 1867, 1, -1, -1940}) {
244 final Calendar cal= getEraStart(year, tz, locale);
245 final Date centuryStart= cal.getTime();
246
247 cal.set(Calendar.MONTH, 1);
248 cal.set(Calendar.DAY_OF_MONTH, 10);
249 final Date in= cal.getTime();
250
251 final FastDateParser fdp= new FastDateParser(format, tz, locale, centuryStart);
252 validateSdfFormatFdpParseEquality(format, locale, tz, fdp, in, year, centuryStart);
253 }
254 }
255 }
256 }
257 }
258
259 // we cannot use historic dates to test timezone parsing, some timezones have second offsets
260 // as well as hours and minutes which makes the z formats a low fidelity round trip
261 @Test
262 public void testTzParses() throws Exception {
263 // Check that all Locales can parse the time formats we use
264 for (final Locale locale : Locale.getAvailableLocales()) {
265 final FastDateParser fdp= new FastDateParser("yyyy/MM/dd z", TimeZone.getDefault(), locale);
266
267 for (final TimeZone tz : new TimeZone[]{NEW_YORK, REYKJAVIK, GMT}) {
268 final Calendar cal= Calendar.getInstance(tz, locale);
269 cal.clear();
270 cal.set(Calendar.YEAR, 2000);
271 cal.set(Calendar.MONTH, 1);
272 cal.set(Calendar.DAY_OF_MONTH, 10);
273 final Date expected= cal.getTime();
274
275 final Date actual = fdp.parse("2000/02/10 "+tz.getDisplayName(locale));
276 assertEquals(expected, actual, "tz:"+tz.getID()+" locale:"+locale.getDisplayName());
277 }
278 }
279 }
280
281
282 @Test
283 public void testLocales_Long_AD() throws Exception {
284 testLocales(LONG_FORMAT, false);
285 }
286
287 @Test
288 public void testLocales_Long_BC() throws Exception {
289 testLocales(LONG_FORMAT, true);
290 }
291
292 @Test
293 public void testLocales_Short_AD() throws Exception {
294 testLocales(SHORT_FORMAT, false);
295 }
296
297 @Test
298 public void testLocales_Short_BC() throws Exception {
299 testLocales(SHORT_FORMAT, true);
300 }
301
302 @Test
303 public void testLocales_LongNoEra_AD() throws Exception {
304 testLocales(LONG_FORMAT_NOERA, false);
305 }
306
307 @Test
308 public void testLocales_LongNoEra_BC() throws Exception {
309 testLocales(LONG_FORMAT_NOERA, true);
310 }
311
312 @Test
313 public void testLocales_ShortNoEra_AD() throws Exception {
314 testLocales(SHORT_FORMAT_NOERA, false);
315 }
316
317 @Test
318 public void testLocales_ShortNoEra_BC() throws Exception {
319 testLocales(SHORT_FORMAT_NOERA, true);
320 }
321
322 private void testLocales(final String format, final boolean eraBC) throws Exception {
323
324 final Calendar cal= Calendar.getInstance(GMT);
282 @Test
283 public void testDayNumberOfWeek() throws ParseException {
284 final DateParser parser = getInstance("u");
285 final Calendar calendar = Calendar.getInstance();
286
287 calendar.setTime(parser.parse("1"));
288 assertEquals(Calendar.MONDAY, calendar.get(Calendar.DAY_OF_WEEK));
289
290 calendar.setTime(parser.parse("6"));
291 assertEquals(Calendar.SATURDAY, calendar.get(Calendar.DAY_OF_WEEK));
292
293 calendar.setTime(parser.parse("7"));
294 assertEquals(Calendar.SUNDAY, calendar.get(Calendar.DAY_OF_WEEK));
295 }
296
297 @ParameterizedTest
298 @MethodSource(DATE_PARSER_PARAMETERS)
299 public void testDayOf(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider) throws ParseException {
300 final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
325301 cal.clear();
326302 cal.set(2003, Calendar.FEBRUARY, 10);
327 if (eraBC) {
328 cal.set(Calendar.ERA, GregorianCalendar.BC);
329 }
330
331 for (final Locale locale : Locale.getAvailableLocales() ) {
332 // ja_JP_JP cannot handle dates before 1868 properly
333 if (eraBC && locale.equals(FastDateParser.JAPANESE_IMPERIAL)) {
334 continue;
335 }
336 final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
337 final DateParser fdf = getInstance(format, locale);
338
339 // If parsing fails, a ParseException will be thrown and the test will fail
340 checkParse(locale, cal, sdf, fdf);
341 }
342 }
343
303
304 final DateParser fdf = getInstance(dpProvider, "W w F D y", NEW_YORK, Locale.US);
305 assertEquals(cal.getTime(), fdf.parse("3 7 2 41 03"));
306 }
307
308 @Test
309 public void testEquals() {
310 final DateParser parser1 = getInstance(YMD_SLASH);
311 final DateParser parser2 = getInstance(YMD_SLASH);
312
313 assertEquals(parser1, parser2);
314 assertEquals(parser1.hashCode(), parser2.hashCode());
315
316 assertNotEquals(parser1, new Object());
317 }
318
319 /**
320 * @throws ParseException
321 */
344322 @Test
345323 public void testJpLocales() throws ParseException {
346324
347 final Calendar cal= Calendar.getInstance(GMT);
325 final Calendar cal = Calendar.getInstance(GMT);
348326 cal.clear();
349327 cal.set(2003, Calendar.FEBRUARY, 10);
350328 cal.set(Calendar.ERA, GregorianCalendar.BC);
359337 checkParse(locale, cal, sdf, fdf);
360338 }
361339
362 private void checkParse(final Locale locale, final Calendar cal, final SimpleDateFormat sdf, final DateParser fdf) throws ParseException {
363 final String formattedDate= sdf.format(cal.getTime());
364 checkParse(locale, sdf, fdf, formattedDate);
365 checkParse(locale, sdf, fdf, formattedDate.toLowerCase(locale));
366 checkParse(locale, sdf, fdf, formattedDate.toUpperCase(locale));
367 }
368
369 private void checkParse(final Locale locale, final SimpleDateFormat sdf, final DateParser fdf, final String formattedDate) throws ParseException {
370 try {
371 final Date expectedTime = sdf.parse(formattedDate);
372 final Date actualTime = fdf.parse(formattedDate);
373 assertEquals(expectedTime, actualTime, "locale : " + locale + " formattedDate : " + formattedDate + "\n");
374 } catch (Exception e) {
375 fail("locale : " + locale + " formattedDate : " + formattedDate + " error : " + e + "\n", e);
376 }
377 }
378
379 @Test
380 public void testParseNumerics() throws ParseException {
381 final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
382 cal.clear();
383 cal.set(2003, Calendar.FEBRUARY, 10, 15, 33, 20);
384 cal.set(Calendar.MILLISECOND, 989);
385
386 final DateParser fdf = getInstance("yyyyMMddHHmmssSSS", NEW_YORK, Locale.US);
387 assertEquals(cal.getTime(), fdf.parse("20030210153320989"));
388 }
389
390 @Test
391 public void testQuotes() throws ParseException {
392 final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
393 cal.clear();
394 cal.set(2003, Calendar.FEBRUARY, 10, 15, 33, 20);
395 cal.set(Calendar.MILLISECOND, 989);
396
397 final DateParser fdf = getInstance("''yyyyMMdd'A''B'HHmmssSSS''", NEW_YORK, Locale.US);
398 assertEquals(cal.getTime(), fdf.parse("'20030210A'B153320989'"));
399 }
400
401 @Test
402 public void testSpecialCharacters() throws Exception {
403 testSdfAndFdp("q", "", true); // bad pattern character (at present)
404 testSdfAndFdp("Q", "", true); // bad pattern character
405 testSdfAndFdp("$", "$", false); // OK
406 testSdfAndFdp("?.d", "?.12", false); // OK
407 testSdfAndFdp("''yyyyMMdd'A''B'HHmmssSSS''", "'20030210A'B153320989'", false); // OK
408 testSdfAndFdp("''''yyyyMMdd'A''B'HHmmssSSS''", "''20030210A'B153320989'", false); // OK
409 testSdfAndFdp("'$\\Ed'", "$\\Ed", false); // OK
410
411 // quoted charaters are case sensitive
412 testSdfAndFdp("'QED'", "QED", false);
413 testSdfAndFdp("'QED'", "qed", true);
414 // case sensitive after insensitive Month field
415 testSdfAndFdp("yyyy-MM-dd 'QED'", "2003-02-10 QED", false);
416 testSdfAndFdp("yyyy-MM-dd 'QED'", "2003-02-10 qed", true);
417 }
418
419 @Test
420 public void testLANG_832() throws Exception {
421 testSdfAndFdp("'d'd", "d3", false); // OK
422 testSdfAndFdp("'d'd'", "d3", true); // should fail (unterminated quote)
423 }
424
425 @Test
426 public void testLANG_831() throws Exception {
427 testSdfAndFdp("M E", "3 Tue", true);
428 }
429
430 private void testSdfAndFdp(final String format, final String date, final boolean shouldFail)
431 throws Exception {
432 Date dfdp = null;
433 Date dsdf = null;
434 Throwable f = null;
435 Throwable s = null;
436
437 try {
438 final SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
439 sdf.setTimeZone(NEW_YORK);
440 dsdf = sdf.parse(date);
441 assertFalse(shouldFail, "Expected SDF failure, but got " + dsdf + " for ["+format+", "+date+"]");
442 } catch (final Exception e) {
443 s = e;
444 if (!shouldFail) {
445 throw e;
446 }
447 }
448
449 try {
450 final DateParser fdp = getInstance(format, NEW_YORK, Locale.US);
451 dfdp = fdp.parse(date);
452 assertFalse(shouldFail, "Expected FDF failure, but got " + dfdp + " for ["+format+", "+date+"]");
453 } catch (final Exception e) {
454 f = e;
455 if (!shouldFail) {
456 throw e;
457 }
458 }
459 // SDF and FDF should produce equivalent results
460 assertEquals((f == null), (s == null), "Should both or neither throw Exceptions");
461 assertEquals(dsdf, dfdp, "Parsed dates should be equal");
462 }
463
464 @Test
465 public void testDayOf() throws ParseException {
466 final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
467 cal.clear();
468 cal.set(2003, Calendar.FEBRUARY, 10);
469
470 final DateParser fdf = getInstance("W w F D y", NEW_YORK, Locale.US);
471 assertEquals(cal.getTime(), fdf.parse("3 7 2 41 03"));
472 }
473
474 /**
475 * Test case for {@link FastDateParser#FastDateParser(String, TimeZone, Locale)}.
476 * @throws ParseException so we don't have to catch it
477 */
478 @Test
479 public void testShortDateStyleWithLocales() throws ParseException {
480 DateParser fdf = getDateInstance(FastDateFormat.SHORT, Locale.US);
340 @ParameterizedTest
341 @MethodSource(DATE_PARSER_PARAMETERS)
342 public void testLANG_831(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider) throws Exception {
343 testSdfAndFdp(dpProvider, "M E", "3 Tue", true);
344 }
345
346 @ParameterizedTest
347 @MethodSource(DATE_PARSER_PARAMETERS)
348 public void testLANG_832(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider) throws Exception {
349 testSdfAndFdp(dpProvider, "'d'd", "d3", false); // OK
350 testSdfAndFdp(dpProvider, "'d'd'", "d3", true); // should fail (unterminated quote)
351 }
352
353 @ParameterizedTest
354 @MethodSource(DATE_PARSER_PARAMETERS)
355 public void testLang1121(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider) throws ParseException {
356 final TimeZone kst = TimeZone.getTimeZone("KST");
357 final DateParser fdp = getInstance(dpProvider, "yyyyMMdd", kst, Locale.KOREA);
358
359 assertThrows(ParseException.class, () -> fdp.parse("2015"));
360
361 // Wed Apr 29 00:00:00 KST 2015
362 Date actual = fdp.parse("20150429");
363 final Calendar cal = Calendar.getInstance(kst, Locale.KOREA);
364 cal.clear();
365 cal.set(2015, 3, 29);
366 Date expected = cal.getTime();
367 assertEquals(expected, actual);
368
369 final SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd", Locale.KOREA);
370 df.setTimeZone(kst);
371 expected = df.parse("20150429113100");
372
373 // Thu Mar 16 00:00:00 KST 81724
374 actual = fdp.parse("20150429113100");
375 assertEquals(expected, actual);
376 }
377
378 @ParameterizedTest
379 @MethodSource(DATE_PARSER_PARAMETERS)
380 public void testLang1380(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider) throws ParseException {
381 final Calendar expected = Calendar.getInstance(GMT, Locale.FRANCE);
382 expected.clear();
383 expected.set(2014, Calendar.APRIL, 14);
384
385 final DateParser fdp = getInstance(dpProvider, "dd MMM yyyy", GMT, Locale.FRANCE);
386 assertEquals(expected.getTime(), fdp.parse("14 avril 2014"));
387 assertEquals(expected.getTime(), fdp.parse("14 avr. 2014"));
388 assertEquals(expected.getTime(), fdp.parse("14 avr 2014"));
389 }
390
391 @Test
392 public void testLang303() throws ParseException {
393 DateParser parser = getInstance(YMD_SLASH);
481394 final Calendar cal = Calendar.getInstance();
482 cal.clear();
483
484 cal.set(2004, Calendar.FEBRUARY, 3);
485 assertEquals(cal.getTime(), fdf.parse("2/3/04"));
486
487 fdf = getDateInstance(FastDateFormat.SHORT, SWEDEN);
488 assertEquals(cal.getTime(), fdf.parse("2004-02-03"));
395 cal.set(2004, Calendar.DECEMBER, 31);
396
397 final Date date = parser.parse("2004/11/31");
398
399 parser = SerializationUtils.deserialize(SerializationUtils.serialize((Serializable) parser));
400 assertEquals(date, parser.parse("2004/11/31"));
401 }
402
403 @Test
404 public void testLang538() throws ParseException {
405 final DateParser parser = getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", GMT);
406
407 final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-8"));
408 cal.clear();
409 cal.set(2009, Calendar.OCTOBER, 16, 8, 42, 16);
410
411 assertEquals(cal.getTime(), parser.parse("2009-10-16T16:42:16.000Z"));
412 }
413
414 @ParameterizedTest
415 @MethodSource(DATE_PARSER_PARAMETERS)
416 public void testLang996(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider) throws ParseException {
417 final Calendar expected = Calendar.getInstance(NEW_YORK, Locale.US);
418 expected.clear();
419 expected.set(2014, Calendar.MAY, 14);
420
421 final DateParser fdp = getInstance(dpProvider, "ddMMMyyyy", NEW_YORK, Locale.US);
422 assertEquals(expected.getTime(), fdp.parse("14may2014"));
423 assertEquals(expected.getTime(), fdp.parse("14MAY2014"));
424 assertEquals(expected.getTime(), fdp.parse("14May2014"));
425 }
426
427 @Test
428 public void testLocaleMatches() {
429 final DateParser parser = getInstance(yMdHmsSZ, SWEDEN);
430 assertEquals(SWEDEN, parser.getLocale());
489431 }
490432
491433 /**
492434 * Tests that pre-1000AD years get padded with yyyy
435 *
493436 * @throws ParseException so we don't have to catch it
494437 */
495438 @Test
518461 assertEquals(cal.getTime(), parser.parse("01.01.1000"));
519462 }
520463
521 @Test
522 public void testLang303() throws ParseException {
523 DateParser parser = getInstance(YMD_SLASH);
524 final Calendar cal = Calendar.getInstance();
525 cal.set(2004, Calendar.DECEMBER, 31);
526
527 final Date date = parser.parse("2004/11/31");
528
529 parser = SerializationUtils.deserialize(SerializationUtils.serialize((Serializable) parser));
530 assertEquals(date, parser.parse("2004/11/31"));
531 }
532
533 @Test
534 public void testLang538() throws ParseException {
535 final DateParser parser = getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", GMT);
536
537 final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-8"));
538 cal.clear();
539 cal.set(2009, Calendar.OCTOBER, 16, 8, 42, 16);
540
541 assertEquals(cal.getTime(), parser.parse("2009-10-16T16:42:16.000Z"));
542 }
543
544 @Test
545 public void testEquals() {
546 final DateParser parser1= getInstance(YMD_SLASH);
547 final DateParser parser2= getInstance(YMD_SLASH);
548
549 assertEquals(parser1, parser2);
550 assertEquals(parser1.hashCode(), parser2.hashCode());
551
552 assertNotEquals(parser1, new Object());
553 }
554
555 @Test
556 public void testToStringContainsName() {
557 final DateParser parser= getInstance(YMD_SLASH);
558 assertTrue(parser.toString().startsWith("FastDate"));
559 }
560
561 @Test
562 public void testPatternMatches() {
563 final DateParser parser= getInstance(yMdHmsSZ);
564 assertEquals(yMdHmsSZ, parser.getPattern());
565 }
566
567 @Test
568 public void testLocaleMatches() {
569 final DateParser parser= getInstance(yMdHmsSZ, SWEDEN);
570 assertEquals(SWEDEN, parser.getLocale());
571 }
572
573 @Test
574 public void testTimeZoneMatches() {
575 final DateParser parser= getInstance(yMdHmsSZ, REYKJAVIK);
576 assertEquals(REYKJAVIK, parser.getTimeZone());
577 }
578
579 @Test
580 public void testLang996() throws ParseException {
581 final Calendar expected = Calendar.getInstance(NEW_YORK, Locale.US);
582 expected.clear();
583 expected.set(2014, Calendar.MAY, 14);
584
585 final DateParser fdp = getInstance("ddMMMyyyy", NEW_YORK, Locale.US);
586 assertEquals(expected.getTime(), fdp.parse("14may2014"));
587 assertEquals(expected.getTime(), fdp.parse("14MAY2014"));
588 assertEquals(expected.getTime(), fdp.parse("14May2014"));
589 }
590
591 @Test
592 public void test1806Argument() {
593 assertThrows(IllegalArgumentException.class, () -> getInstance("XXXX"));
594 }
595
596 private static Calendar initializeCalendar(final TimeZone tz) {
597 final Calendar cal = Calendar.getInstance(tz);
598 cal.set(Calendar.YEAR, 2001);
599 cal.set(Calendar.MONTH, 1); // not daylight savings
600 cal.set(Calendar.DAY_OF_MONTH, 4);
601 cal.set(Calendar.HOUR_OF_DAY, 12);
602 cal.set(Calendar.MINUTE, 8);
603 cal.set(Calendar.SECOND, 56);
604 cal.set(Calendar.MILLISECOND, 235);
605 return cal;
606 }
607
608 private enum Expected1806 {
609 India(INDIA, "+05", "+0530", "+05:30", true),
610 Greenwich(GMT, "Z", "Z", "Z", false),
611 NewYork(NEW_YORK, "-05", "-0500", "-05:00", false);
612
613 Expected1806(final TimeZone zone, final String one, final String two, final String three, final boolean hasHalfHourOffset) {
614 this.zone = zone;
615 this.one = one;
616 this.two = two;
617 this.three = three;
618 this.offset = hasHalfHourOffset ?30*60*1000 :0;
619 }
620
621 final TimeZone zone;
622 final String one;
623 final String two;
624 final String three;
625 final long offset;
626 }
627
628 @Test
629 public void test1806() throws ParseException {
630 final String formatStub = "yyyy-MM-dd'T'HH:mm:ss.SSS";
631 final String dateStub = "2001-02-04T12:08:56.235";
632
633 for (final Expected1806 trial : Expected1806.values()) {
634 final Calendar cal = initializeCalendar(trial.zone);
635
636 final String message = trial.zone.getDisplayName()+";";
637
638 DateParser parser = getInstance(formatStub+"X", trial.zone);
639 assertEquals(cal.getTime().getTime(), parser.parse(dateStub+trial.one).getTime()-trial.offset, message+trial.one);
640
641 parser = getInstance(formatStub+"XX", trial.zone);
642 assertEquals(cal.getTime(), parser.parse(dateStub+trial.two), message+trial.two);
643
644 parser = getInstance(formatStub+"XXX", trial.zone);
645 assertEquals(cal.getTime(), parser.parse(dateStub+trial.three), message+trial.three);
646 }
647 }
648
649 @Test
650 public void testLang1121() throws ParseException {
651 final TimeZone kst = TimeZone.getTimeZone("KST");
652 final DateParser fdp = getInstance("yyyyMMdd", kst, Locale.KOREA);
653
654 assertThrows(ParseException.class, () -> fdp.parse("2015"));
655
656 // Wed Apr 29 00:00:00 KST 2015
657 Date actual = fdp.parse("20150429");
658 final Calendar cal = Calendar.getInstance(kst, Locale.KOREA);
659 cal.clear();
660 cal.set(2015, 3, 29);
661 Date expected = cal.getTime();
662 assertEquals(expected, actual);
663
664 final SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd", Locale.KOREA);
665 df.setTimeZone(kst);
666 expected = df.parse("20150429113100");
667
668 // Thu Mar 16 00:00:00 KST 81724
669 actual = fdp.parse("20150429113100");
670 assertEquals(expected, actual);
464 @ParameterizedTest
465 @MethodSource(DATE_PARSER_PARAMETERS)
466 public void testParseLongShort(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
467 throws ParseException {
468 final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
469 cal.clear();
470 cal.set(2003, Calendar.FEBRUARY, 10, 15, 33, 20);
471 cal.set(Calendar.MILLISECOND, 989);
472 cal.setTimeZone(NEW_YORK);
473
474 DateParser fdf = getInstance(dpProvider, "yyyy GGGG MMMM dddd aaaa EEEE HHHH mmmm ssss SSSS ZZZZ", NEW_YORK,
475 Locale.US);
476
477 assertEquals(cal.getTime(), fdf.parse("2003 AD February 0010 PM Monday 0015 0033 0020 0989 GMT-05:00"));
478 cal.set(Calendar.ERA, GregorianCalendar.BC);
479
480 final Date parse = fdf.parse("2003 BC February 0010 PM Saturday 0015 0033 0020 0989 GMT-05:00");
481 assertEquals(cal.getTime(), parse);
482
483 fdf = getInstance(null, "y G M d a E H m s S Z", NEW_YORK, Locale.US);
484 assertEquals(cal.getTime(), fdf.parse("03 BC 2 10 PM Sat 15 33 20 989 -0500"));
485
486 cal.set(Calendar.ERA, GregorianCalendar.AD);
487 assertEquals(cal.getTime(), fdf.parse("03 AD 2 10 PM Saturday 15 33 20 989 -0500"));
488 }
489
490 @ParameterizedTest
491 @MethodSource(DATE_PARSER_PARAMETERS)
492 public void testParseNumerics(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
493 throws ParseException {
494 final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
495 cal.clear();
496 cal.set(2003, Calendar.FEBRUARY, 10, 15, 33, 20);
497 cal.set(Calendar.MILLISECOND, 989);
498
499 final DateParser fdf = getInstance(dpProvider, "yyyyMMddHHmmssSSS", NEW_YORK, Locale.US);
500 assertEquals(cal.getTime(), fdf.parse("20030210153320989"));
671501 }
672502
673503 @Test
682512 }
683513
684514 @Test
685 public void testDayNumberOfWeek() throws ParseException {
686 final DateParser parser = getInstance("u");
687 final Calendar calendar = Calendar.getInstance();
688
689 calendar.setTime(parser.parse("1"));
690 assertEquals(Calendar.MONDAY, calendar.get(Calendar.DAY_OF_WEEK));
691
692 calendar.setTime(parser.parse("6"));
693 assertEquals(Calendar.SATURDAY, calendar.get(Calendar.DAY_OF_WEEK));
694
695 calendar.setTime(parser.parse("7"));
696 assertEquals(Calendar.SUNDAY, calendar.get(Calendar.DAY_OF_WEEK));
697 }
698
699 @Test
700 public void testLang1380() throws ParseException {
701 final Calendar expected = Calendar.getInstance(GMT, Locale.FRANCE);
702 expected.clear();
703 expected.set(2014, Calendar.APRIL, 14);
704
705 final DateParser fdp = getInstance("dd MMM yyyy", GMT, Locale.FRANCE);
706 assertEquals(expected.getTime(), fdp.parse("14 avril 2014"));
707 assertEquals(expected.getTime(), fdp.parse("14 avr. 2014"));
708 assertEquals(expected.getTime(), fdp.parse("14 avr 2014"));
709 }
710
711 @Test
712 public void java15BuggyLocaleTestAll() throws ParseException {
515 // Check that all Locales can parse the formats we use
516 public void testParses() throws Exception {
517 for (final String format : new String[] {LONG_FORMAT, SHORT_FORMAT}) {
518 for (final Locale locale : Locale.getAvailableLocales()) {
519 for (final TimeZone timeZone : new TimeZone[] {NEW_YORK, REYKJAVIK, GMT}) {
520 for (final int year : new int[] {2003, 1940, 1868, 1867, 1, -1, -1940}) {
521 final Calendar cal = getEraStart(year, timeZone, locale);
522 final Date centuryStart = cal.getTime();
523
524 cal.set(Calendar.MONTH, 1);
525 cal.set(Calendar.DAY_OF_MONTH, 10);
526 final Date in = cal.getTime();
527
528 final FastDateParser fastDateParser = new FastDateParser(format, timeZone, locale,
529 centuryStart);
530 validateSdfFormatFdpParseEquality(format, locale, timeZone, fastDateParser, in, year,
531 centuryStart);
532 }
533 }
534 }
535 }
536 }
537
538 /**
539 * Fails on Java 16 Early Access build 25 and above, last tested with build 36.
540 */
541 @Test
542 public void testParsesKnownJava16Ea25Failure() throws Exception {
543 final String format = LONG_FORMAT;
544 final int year = 2003;
545 final Locale locale = new Locale.Builder().setLanguage("sq").setRegion("MK").build();
546 assertEquals("sq_MK", locale.toString());
547 assertNotNull(locale);
548 final TimeZone timeZone = NEW_YORK;
549 final Calendar cal = getEraStart(year, timeZone, locale);
550 final Date centuryStart = cal.getTime();
551
552 cal.set(Calendar.MONTH, 1);
553 cal.set(Calendar.DAY_OF_MONTH, 10);
554 final Date in = cal.getTime();
555
556 final FastDateParser fastDateParser = new FastDateParser(format, timeZone, locale, centuryStart);
557 validateSdfFormatFdpParseEquality(format, locale, timeZone, fastDateParser, in, year, centuryStart);
558 }
559
560 @ParameterizedTest
561 @MethodSource(DATE_PARSER_PARAMETERS)
562 public void testParseZone(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
563 throws ParseException {
564 final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
565 cal.clear();
566 cal.set(2003, Calendar.JULY, 10, 16, 33, 20);
567
568 final DateParser fdf = getInstance(dpProvider, yMdHmsSZ, NEW_YORK, Locale.US);
569
570 assertEquals(cal.getTime(), fdf.parse("2003-07-10T15:33:20.000 -0500"));
571 assertEquals(cal.getTime(), fdf.parse("2003-07-10T15:33:20.000 GMT-05:00"));
572 assertEquals(cal.getTime(), fdf.parse("2003-07-10T16:33:20.000 Eastern Daylight Time"));
573 assertEquals(cal.getTime(), fdf.parse("2003-07-10T16:33:20.000 EDT"));
574
575 cal.setTimeZone(TimeZone.getTimeZone("GMT-3"));
576 cal.set(2003, Calendar.FEBRUARY, 10, 9, 0, 0);
577
578 assertEquals(cal.getTime(), fdf.parse("2003-02-10T09:00:00.000 -0300"));
579
580 cal.setTimeZone(TimeZone.getTimeZone("GMT+5"));
581 cal.set(2003, Calendar.FEBRUARY, 10, 15, 5, 6);
582
583 assertEquals(cal.getTime(), fdf.parse("2003-02-10T15:05:06.000 +0500"));
584 }
585
586 @Test
587 public void testPatternMatches() {
588 final DateParser parser = getInstance(yMdHmsSZ);
589 assertEquals(yMdHmsSZ, parser.getPattern());
590 }
591
592 @ParameterizedTest
593 @MethodSource(DATE_PARSER_PARAMETERS)
594 public void testQuotes(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider) throws ParseException {
595 final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
596 cal.clear();
597 cal.set(2003, Calendar.FEBRUARY, 10, 15, 33, 20);
598 cal.set(Calendar.MILLISECOND, 989);
599
600 final DateParser fdf = getInstance(dpProvider, "''yyyyMMdd'A''B'HHmmssSSS''", NEW_YORK, Locale.US);
601 assertEquals(cal.getTime(), fdf.parse("'20030210A'B153320989'"));
602 }
603
604 private void testSdfAndFdp(final TriFunction<String, TimeZone, Locale, DateParser> dbProvider, final String format,
605 final String date, final boolean shouldFail) throws Exception {
606 Date dfdp = null;
607 Date dsdf = null;
608 Throwable f = null;
609 Throwable s = null;
610
611 try {
612 final SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
613 sdf.setTimeZone(NEW_YORK);
614 dsdf = sdf.parse(date);
615 assertFalse(shouldFail, "Expected SDF failure, but got " + dsdf + " for [" + format + ", " + date + "]");
616 } catch (final Exception e) {
617 s = e;
618 if (!shouldFail) {
619 throw e;
620 }
621 }
622
623 try {
624 final DateParser fdp = getInstance(dbProvider, format, NEW_YORK, Locale.US);
625 dfdp = fdp.parse(date);
626 assertFalse(shouldFail, "Expected FDF failure, but got " + dfdp + " for [" + format + ", " + date + "]");
627 } catch (final Exception e) {
628 f = e;
629 if (!shouldFail) {
630 throw e;
631 }
632 }
633 // SDF and FDF should produce equivalent results
634 assertEquals((f == null), (s == null), "Should both or neither throw Exceptions");
635 assertEquals(dsdf, dfdp, "Parsed dates should be equal");
636 }
637
638 /**
639 * Test case for {@link FastDateParser#FastDateParser(String, TimeZone, Locale)}.
640 *
641 * @throws ParseException so we don't have to catch it
642 */
643 @Test
644 public void testShortDateStyleWithLocales() throws ParseException {
645 DateParser fdf = getDateInstance(FastDateFormat.SHORT, Locale.US);
646 final Calendar cal = Calendar.getInstance();
647 cal.clear();
648
649 cal.set(2004, Calendar.FEBRUARY, 3);
650 assertEquals(cal.getTime(), fdf.parse("2/3/04"));
651
652 fdf = getDateInstance(FastDateFormat.SHORT, SWEDEN);
653 assertEquals(cal.getTime(), fdf.parse("2004-02-03"));
654 }
655
656 @ParameterizedTest
657 @MethodSource(DATE_PARSER_PARAMETERS)
658 public void testSpecialCharacters(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
659 throws Exception {
660 testSdfAndFdp(dpProvider, "q", "", true); // bad pattern character (at present)
661 testSdfAndFdp(dpProvider, "Q", "", true); // bad pattern character
662 testSdfAndFdp(dpProvider, "$", "$", false); // OK
663 testSdfAndFdp(dpProvider, "?.d", "?.12", false); // OK
664 testSdfAndFdp(dpProvider, "''yyyyMMdd'A''B'HHmmssSSS''", "'20030210A'B153320989'", false); // OK
665 testSdfAndFdp(dpProvider, "''''yyyyMMdd'A''B'HHmmssSSS''", "''20030210A'B153320989'", false); // OK
666 testSdfAndFdp(dpProvider, "'$\\Ed'", "$\\Ed", false); // OK
667
668 // quoted charaters are case sensitive
669 testSdfAndFdp(dpProvider, "'QED'", "QED", false);
670 testSdfAndFdp(dpProvider, "'QED'", "qed", true);
671 // case sensitive after insensitive Month field
672 testSdfAndFdp(dpProvider, "yyyy-MM-dd 'QED'", "2003-02-10 QED", false);
673 testSdfAndFdp(dpProvider, "yyyy-MM-dd 'QED'", "2003-02-10 qed", true);
674 }
675
676 @Test
677 public void testTimeZoneMatches() {
678 final DateParser parser = getInstance(yMdHmsSZ, REYKJAVIK);
679 assertEquals(REYKJAVIK, parser.getTimeZone());
680 }
681
682 @Test
683 public void testToStringContainsName() {
684 final DateParser parser = getInstance(YMD_SLASH);
685 assertTrue(parser.toString().startsWith("FastDate"));
686 }
687
688 // we cannot use historic dates to test time zone parsing, some time zones have second offsets
689 // as well as hours and minutes which makes the z formats a low fidelity round trip
690 @Test
691 public void testTzParses() throws Exception {
692 // Check that all Locales can parse the time formats we use
713693 for (final Locale locale : Locale.getAvailableLocales()) {
714 testSingleLocale(locale);
715 }
716 }
717
718 @Test
719 public void java15BuggyLocaleTest() throws ParseException {
720 final String buggyLocaleName = "ff_LR_#Adlm";
721 Locale buggyLocale = null;
722 for (final Locale locale : Locale.getAvailableLocales()) {
723 if (buggyLocaleName.equals(locale.toString())) {
724 buggyLocale = locale;
725 break;
694 final FastDateParser fdp = new FastDateParser("yyyy/MM/dd z", TimeZone.getDefault(), locale);
695
696 for (final TimeZone timeZone : new TimeZone[] {NEW_YORK, REYKJAVIK, GMT}) {
697 final Calendar cal = Calendar.getInstance(timeZone, locale);
698 cal.clear();
699 cal.set(Calendar.YEAR, 2000);
700 cal.set(Calendar.MONTH, 1);
701 cal.set(Calendar.DAY_OF_MONTH, 10);
702 final Date expected = cal.getTime();
703
704 final Date actual = fdp.parse("2000/02/10 " + timeZone.getDisplayName(locale));
705 assertEquals(expected, actual, "timeZone:" + timeZone.getID() + " locale:" + locale.getDisplayName());
726706 }
727707 }
728 if (buggyLocale == null) {
729 return;
730 }
731 testSingleLocale(buggyLocale);
732 }
733
734 private void testSingleLocale(final Locale locale) throws ParseException {
735 final Calendar cal = Calendar.getInstance(GMT);
736 cal.clear();
737 cal.set(2003, Calendar.FEBRUARY, 10);
738 final SimpleDateFormat sdf = new SimpleDateFormat(LONG_FORMAT, locale);
739 final String formattedDate = sdf.format(cal.getTime());
740 sdf.parse(formattedDate);
741 sdf.parse(formattedDate.toUpperCase(locale));
742 sdf.parse(formattedDate.toLowerCase(locale));
708 }
709
710 private void validateSdfFormatFdpParseEquality(final String formatStr, final Locale locale, final TimeZone timeZone,
711 final FastDateParser dateParser, final Date inDate, final int year, final Date csDate) throws ParseException {
712 final SimpleDateFormat sdf = new SimpleDateFormat(formatStr, locale);
713 sdf.setTimeZone(timeZone);
714 if (formatStr.equals(SHORT_FORMAT)) {
715 sdf.set2DigitYearStart(csDate);
716 }
717 final String fmt = sdf.format(inDate);
718 // System.out.printf("[Java %s] Date: '%s' formated with '%s' -> '%s'%n", SystemUtils.JAVA_RUNTIME_VERSION, inDate,
719 // formatStr, fmt);
720 try {
721 final Date out = dateParser.parse(fmt);
722 assertEquals(inDate, out, "format: '" + formatStr + "', locale: '" + locale + "', time zone: '"
723 + timeZone.getID() + "', year: " + year + ", parse: '" + fmt);
724 } catch (final ParseException pe) {
725 if (year >= 1868 || !locale.getCountry().equals("JP")) {
726 // LANG-978
727 throw pe;
728 }
729 }
743730 }
744731 }
732
3232 private static final TimeZone NEW_YORK = TimeZone.getTimeZone("America/New_York");
3333
3434 @Test
35 public void testInputHasLessCharacters() {
36 final FastDateParser parser = new FastDateParser("MM/dd/yyy", TimeZone.getDefault(), Locale.getDefault());
37 final ParsePosition parsePosition = new ParsePosition(0);
38 assertNull(parser.parse("03/23", parsePosition));
39 assertEquals(5, parsePosition.getErrorIndex());
40 }
41
42 @Test
43 public void testInputHasMoreCharacters() {
44 final FastDateParser parser = new FastDateParser("MM/dd", TimeZone.getDefault(), Locale.getDefault());
45 final ParsePosition parsePosition = new ParsePosition(0);
46 final Date date = parser.parse("3/23/61", parsePosition);
47 assertEquals(4, parsePosition.getIndex());
48
49 final Calendar calendar = Calendar.getInstance();
50 calendar.setTime(date);
51 assertEquals(2, calendar.get(Calendar.MONTH));
52 assertEquals(23, calendar.get(Calendar.DATE));
53 }
54
55 @Test
3556 public void testInputHasPrecedingCharacters() {
3657 final FastDateParser parser = new FastDateParser("MM/dd", TimeZone.getDefault(), Locale.getDefault());
3758 final ParsePosition parsePosition = new ParsePosition(0);
5778 }
5879
5980 @Test
60 public void testInputHasMoreCharacters() {
61 final FastDateParser parser = new FastDateParser("MM/dd", TimeZone.getDefault(), Locale.getDefault());
62 final ParsePosition parsePosition = new ParsePosition(0);
63 final Date date = parser.parse("3/23/61", parsePosition);
64 assertEquals(4, parsePosition.getIndex());
65
66 final Calendar calendar = Calendar.getInstance();
67 calendar.setTime(date);
68 assertEquals(2, calendar.get(Calendar.MONTH));
69 assertEquals(23, calendar.get(Calendar.DATE));
70 }
71
72 @Test
7381 public void testInputHasWrongCharacters() {
7482 final FastDateParser parser = new FastDateParser("MM-dd-yyy", TimeZone.getDefault(), Locale.getDefault());
7583 final ParsePosition parsePosition = new ParsePosition(0);
7886 }
7987
8088 @Test
81 public void testInputHasLessCharacters() {
82 final FastDateParser parser = new FastDateParser("MM/dd/yyy", TimeZone.getDefault(), Locale.getDefault());
89 public void testInputHasWrongDay() {
90 final FastDateParser parser = new FastDateParser("EEEE, MM/dd/yyy", NEW_YORK, Locale.US);
91 final String input = "Thursday, 03/23/61";
8392 final ParsePosition parsePosition = new ParsePosition(0);
84 assertNull(parser.parse("03/23", parsePosition));
85 assertEquals(5, parsePosition.getErrorIndex());
93 assertNotNull(parser.parse(input, parsePosition));
94 assertEquals(input.length(), parsePosition.getIndex());
95
96 parsePosition.setIndex(0);
97 assertNull(parser.parse( "Thorsday, 03/23/61", parsePosition));
98 assertEquals(0, parsePosition.getErrorIndex());
8699 }
87100
88101 @Test
98111 assertNull(parser.parse( "11:23 Pacific Standard ", parsePosition));
99112 assertEquals(6, parsePosition.getErrorIndex());
100113 }
101
102 @Test
103 public void testInputHasWrongDay() {
104 final FastDateParser parser = new FastDateParser("EEEE, MM/dd/yyy", NEW_YORK, Locale.US);
105 final String input = "Thursday, 03/23/61";
106 final ParsePosition parsePosition = new ParsePosition(0);
107 assertNotNull(parser.parse(input, parsePosition));
108 assertEquals(input.length(), parsePosition.getIndex());
109
110 parsePosition.setIndex(0);
111 assertNull(parser.parse( "Thorsday, 03/23/61", parsePosition));
112 assertEquals(0, parsePosition.getErrorIndex());
113 }
114114 }
2929
3030 class FastDateParser_TimeZoneStrategyTest {
3131
32 @Test
33 void testLang1219() throws ParseException {
34 final FastDateParser parser = new FastDateParser("dd.MM.yyyy HH:mm:ss z", TimeZone.getDefault(), Locale.GERMAN);
35
36 final Date summer = parser.parse("26.10.2014 02:00:00 MESZ");
37 final Date standard = parser.parse("26.10.2014 02:00:00 MEZ");
38 assertNotEquals(summer.getTime(), standard.getTime());
39 }
40
3241 @ParameterizedTest
3342 @MethodSource("java.util.Locale#getAvailableLocales")
3443 void testTimeZoneStrategyPattern(final Locale locale) throws ParseException {
4554 }
4655 }
4756 }
48
49 @Test
50 void testLang1219() throws ParseException {
51 final FastDateParser parser = new FastDateParser("dd.MM.yyyy HH:mm:ss z", TimeZone.getDefault(), Locale.GERMAN);
52
53 final Date summer = parser.parse("26.10.2014 02:00:00 MESZ");
54 final Date standard = parser.parse("26.10.2014 02:00:00 MEZ");
55 assertNotEquals(summer.getTime(), standard.getTime());
56 }
5757 }
4141 */
4242 public class FastDatePrinterTest {
4343
44 private enum Expected1806 {
45 India(INDIA, "+05", "+0530", "+05:30"), Greenwich(GMT, "Z", "Z", "Z"), NewYork(
46 NEW_YORK, "-05", "-0500", "-05:00");
47
48 final TimeZone zone;
49
50 final String one;
51 final String two;
52 final String three;
53 Expected1806(final TimeZone zone, final String one, final String two, final String three) {
54 this.zone = zone;
55 this.one = one;
56 this.two = two;
57 this.three = three;
58 }
59 }
4460 private static final String YYYY_MM_DD = "yyyy/MM/dd";
4561 private static final TimeZone NEW_YORK = TimeZone.getTimeZone("America/New_York");
4662 private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
4763 private static final TimeZone INDIA = TimeZone.getTimeZone("Asia/Calcutta");
64
4865 private static final Locale SWEDEN = new Locale("sv", "SE");
49
50 DatePrinter getInstance(final String format) {
51 return getInstance(format, TimeZone.getDefault(), Locale.getDefault());
52 }
53
54 private DatePrinter getDateInstance(final int dateStyle, final Locale locale) {
55 return getInstance(FormatCache.getPatternForStyle(Integer.valueOf(dateStyle), null, locale), TimeZone.getDefault(), Locale.getDefault());
56 }
57
58 private DatePrinter getInstance(final String format, final Locale locale) {
59 return getInstance(format, TimeZone.getDefault(), locale);
60 }
61
62 private DatePrinter getInstance(final String format, final TimeZone timeZone) {
63 return getInstance(format, timeZone, Locale.getDefault());
64 }
65
66 /**
67 * Override this method in derived tests to change the construction of instances
68 * @param format the format string to use
69 * @param timeZone the time zone to use
70 * @param locale the locale to use
71 * @return the DatePrinter to use for testing
72 */
73 protected DatePrinter getInstance(final String format, final TimeZone timeZone, final Locale locale) {
74 return new FastDatePrinter(format, timeZone, locale);
75 }
76
77 @DefaultLocale(language = "en", country = "US")
78 @DefaultTimeZone("America/New_York")
79 @Test
80 public void testFormat() {
81 final GregorianCalendar cal1 = new GregorianCalendar(2003, 0, 10, 15, 33, 20);
82 final GregorianCalendar cal2 = new GregorianCalendar(2003, 6, 10, 9, 0, 0);
83 final Date date1 = cal1.getTime();
84 final Date date2 = cal2.getTime();
85 final long millis1 = date1.getTime();
86 final long millis2 = date2.getTime();
87
88 DatePrinter fdf = getInstance("yyyy-MM-dd'T'HH:mm:ss");
89 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
90 assertEquals(sdf.format(date1), fdf.format(date1));
91 assertEquals("2003-01-10T15:33:20", fdf.format(date1));
92 assertEquals("2003-01-10T15:33:20", fdf.format(cal1));
93 assertEquals("2003-01-10T15:33:20", fdf.format(millis1));
94 assertEquals("2003-07-10T09:00:00", fdf.format(date2));
95 assertEquals("2003-07-10T09:00:00", fdf.format(cal2));
96 assertEquals("2003-07-10T09:00:00", fdf.format(millis2));
97
98 fdf = getInstance("Z");
99 assertEquals("-0500", fdf.format(date1));
100 assertEquals("-0500", fdf.format(cal1));
101 assertEquals("-0500", fdf.format(millis1));
102
103 assertEquals("-0400", fdf.format(date2));
104 assertEquals("-0400", fdf.format(cal2));
105 assertEquals("-0400", fdf.format(millis2));
106
107 fdf = getInstance("ZZ");
108 assertEquals("-05:00", fdf.format(date1));
109 assertEquals("-05:00", fdf.format(cal1));
110 assertEquals("-05:00", fdf.format(millis1));
111
112 assertEquals("-04:00", fdf.format(date2));
113 assertEquals("-04:00", fdf.format(cal2));
114 assertEquals("-04:00", fdf.format(millis2));
115
116 final String pattern = "GGGG GGG GG G yyyy yyy yy y MMMM MMM MM M" +
117 " dddd ddd dd d DDDD DDD DD D EEEE EEE EE E aaaa aaa aa a zzzz zzz zz z";
118 fdf = getInstance(pattern);
119 sdf = new SimpleDateFormat(pattern);
120 // SDF bug fix starting with Java 7
121 assertEquals(sdf.format(date1).replaceAll("2003 03 03 03", "2003 2003 03 2003"), fdf.format(date1));
122 assertEquals(sdf.format(date2).replaceAll("2003 03 03 03", "2003 2003 03 2003"), fdf.format(date2));
123 }
124
125 /**
126 * Test case for {@link FastDateParser#FastDateParser(String, TimeZone, Locale)}.
127 */
128 @Test
129 public void testShortDateStyleWithLocales() {
130 final Locale usLocale = Locale.US;
131 final Locale swedishLocale = new Locale("sv", "SE");
132 final Calendar cal = Calendar.getInstance();
133 cal.set(2004, Calendar.FEBRUARY, 3);
134 DatePrinter fdf = getDateInstance(FastDateFormat.SHORT, usLocale);
135 assertEquals("2/3/04", fdf.format(cal));
136
137 fdf = getDateInstance(FastDateFormat.SHORT, swedishLocale);
138 assertEquals("2004-02-03", fdf.format(cal));
139
140 }
141
142 /**
143 * Tests that pre-1000AD years get padded with yyyy
144 */
145 @Test
146 public void testLowYearPadding() {
147 final Calendar cal = Calendar.getInstance();
148 final DatePrinter format = getInstance(YYYY_MM_DD);
149
150 cal.set(1, Calendar.JANUARY, 1);
151 assertEquals("0001/01/01", format.format(cal));
152 cal.set(10, Calendar.JANUARY, 1);
153 assertEquals("0010/01/01", format.format(cal));
154 cal.set(100, Calendar.JANUARY, 1);
155 assertEquals("0100/01/01", format.format(cal));
156 cal.set(999, Calendar.JANUARY, 1);
157 assertEquals("0999/01/01", format.format(cal));
158 }
159 /**
160 * Show Bug #39410 is solved
161 */
162 @Test
163 public void testMilleniumBug() {
164 final Calendar cal = Calendar.getInstance();
165 final DatePrinter format = getInstance("dd.MM.yyyy");
166
167 cal.set(1000, Calendar.JANUARY, 1);
168 assertEquals("01.01.1000", format.format(cal));
169 }
170
171 /**
172 * testLowYearPadding showed that the date was buggy
173 * This test confirms it, getting 366 back as a date
174 */
175 @Test
176 public void testSimpleDate() {
177 final Calendar cal = Calendar.getInstance();
178 final DatePrinter format = getInstance(YYYY_MM_DD);
179
180 cal.set(2004, Calendar.DECEMBER, 31);
181 assertEquals("2004/12/31", format.format(cal));
182 cal.set(999, Calendar.DECEMBER, 31);
183 assertEquals("0999/12/31", format.format(cal));
184 cal.set(1, Calendar.MARCH, 2);
185 assertEquals("0001/03/02", format.format(cal));
186 }
187
188 @Test
189 public void testLang303() {
190 final Calendar cal = Calendar.getInstance();
191 cal.set(2004, Calendar.DECEMBER, 31);
192
193 DatePrinter format = getInstance(YYYY_MM_DD);
194 final String output = format.format(cal);
195
196 format = SerializationUtils.deserialize(SerializationUtils.serialize((Serializable) format));
197 assertEquals(output, format.format(cal));
198 }
199
200 @Test
201 public void testLang538() {
202 // more commonly constructed with: cal = new GregorianCalendar(2009, 9, 16, 8, 42, 16)
203 // for the unit test to work in any time zone, constructing with GMT-8 rather than default locale time zone
204 final GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT-8"));
205 cal.clear();
206 cal.set(2009, Calendar.OCTOBER, 16, 8, 42, 16);
207
208 final DatePrinter format = getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("GMT"));
209 assertEquals("2009-10-16T16:42:16.000Z", format.format(cal.getTime()), "dateTime");
210 assertEquals("2009-10-16T16:42:16.000Z", format.format(cal), "dateTime");
211 }
212
213 @Test
214 public void testLang645() {
215 final Locale locale = new Locale("sv", "SE");
216
217 final Calendar cal = Calendar.getInstance();
218 cal.set(2010, Calendar.JANUARY, 1, 12, 0, 0);
219 final Date d = cal.getTime();
220
221 final DatePrinter fdf = getInstance("EEEE', week 'ww", locale);
222
223 assertEquals("fredag, week 53", fdf.format(d));
224 }
225
226 @Test
227 public void testEquals() {
228 final DatePrinter printer1= getInstance(YYYY_MM_DD);
229 final DatePrinter printer2= getInstance(YYYY_MM_DD);
230
231 assertEquals(printer1, printer2);
232 assertEquals(printer1.hashCode(), printer2.hashCode());
233
234 assertNotEquals(printer1, new Object());
235 }
236
237 @Test
238 public void testToStringContainsName() {
239 final DatePrinter printer= getInstance(YYYY_MM_DD);
240 assertTrue(printer.toString().startsWith("FastDate"));
241 }
242
243 @Test
244 public void testPatternMatches() {
245 final DatePrinter printer= getInstance(YYYY_MM_DD);
246 assertEquals(YYYY_MM_DD, printer.getPattern());
247 }
248
249 @Test
250 public void testLocaleMatches() {
251 final DatePrinter printer= getInstance(YYYY_MM_DD, SWEDEN);
252 assertEquals(SWEDEN, printer.getLocale());
253 }
254
255 @Test
256 public void testTimeZoneMatches() {
257 final DatePrinter printer= getInstance(YYYY_MM_DD, NEW_YORK);
258 assertEquals(NEW_YORK, printer.getTimeZone());
259 }
260
261 @DefaultTimeZone("UTC")
262 @Test
263 public void testTimeZoneAsZ() {
264 final Calendar c = Calendar.getInstance(FastTimeZone.getGmtTimeZone());
265 final FastDateFormat noColonFormat = FastDateFormat.getInstance("Z");
266 assertEquals("+0000", noColonFormat.format(c));
267
268 final FastDateFormat isoFormat = FastDateFormat.getInstance("ZZ");
269 assertEquals("Z", isoFormat.format(c));
270
271 final FastDateFormat colonFormat = FastDateFormat.getInstance("ZZZ");
272 assertEquals("+00:00", colonFormat.format(c));
273 }
27466
27567 private static Calendar initializeCalendar(final TimeZone tz) {
27668 final Calendar cal = Calendar.getInstance(tz);
28476 return cal;
28577 }
28678
287 @Test
288 public void test1806Argument() {
289 assertThrows(IllegalArgumentException.class, () -> getInstance("XXXX"));
290 }
291
292 private enum Expected1806 {
293 India(INDIA, "+05", "+0530", "+05:30"), Greenwich(GMT, "Z", "Z", "Z"), NewYork(
294 NEW_YORK, "-05", "-0500", "-05:00");
295
296 Expected1806(final TimeZone zone, final String one, final String two, final String three) {
297 this.zone = zone;
298 this.one = one;
299 this.two = two;
300 this.three = three;
301 }
302
303 final TimeZone zone;
304 final String one;
305 final String two;
306 final String three;
79 private DatePrinter getDateInstance(final int dateStyle, final Locale locale) {
80 return getInstance(FormatCache.getPatternForStyle(Integer.valueOf(dateStyle), null, locale), TimeZone.getDefault(), Locale.getDefault());
81 }
82
83 DatePrinter getInstance(final String format) {
84 return getInstance(format, TimeZone.getDefault(), Locale.getDefault());
85 }
86
87 private DatePrinter getInstance(final String format, final Locale locale) {
88 return getInstance(format, TimeZone.getDefault(), locale);
89 }
90
91 private DatePrinter getInstance(final String format, final TimeZone timeZone) {
92 return getInstance(format, timeZone, Locale.getDefault());
93 }
94
95 /**
96 * Override this method in derived tests to change the construction of instances
97 * @param format the format string to use
98 * @param timeZone the time zone to use
99 * @param locale the locale to use
100 * @return the DatePrinter to use for testing
101 */
102 protected DatePrinter getInstance(final String format, final TimeZone timeZone, final Locale locale) {
103 return new FastDatePrinter(format, timeZone, locale);
307104 }
308105
309106 @Test
320117 printer = getInstance("XXX", trial.zone);
321118 assertEquals(trial.three, printer.format(cal));
322119 }
120 }
121 @Test
122 public void test1806Argument() {
123 assertThrows(IllegalArgumentException.class, () -> getInstance("XXXX"));
124 }
125
126 @Test
127 public void testAppendableOptions() {
128 final DatePrinter format = getInstance("yyyy-MM-dd HH:mm:ss.SSS Z", TimeZone.getTimeZone("GMT"));
129 final Calendar calendar = Calendar.getInstance();
130 final StringBuilder sb = new StringBuilder();
131 final String expected = format.format(calendar, sb).toString();
132 sb.setLength(0);
133
134 final Date date = calendar.getTime();
135 assertEquals(expected, format.format(date, sb).toString());
136 sb.setLength(0);
137
138 final long epoch = date.getTime();
139 assertEquals(expected, format.format(epoch, sb).toString());
140 }
141
142 @Test
143 public void testDayNumberOfWeek() {
144 final DatePrinter printer = getInstance("u");
145 final Calendar calendar = Calendar.getInstance();
146
147 calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
148 assertEquals("1", printer.format(calendar.getTime()));
149
150 calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
151 assertEquals("6", printer.format(calendar.getTime()));
152
153 calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
154 assertEquals("7", printer.format(calendar.getTime()));
155 }
156
157 @Test
158 public void testEquals() {
159 final DatePrinter printer1= getInstance(YYYY_MM_DD);
160 final DatePrinter printer2= getInstance(YYYY_MM_DD);
161
162 assertEquals(printer1, printer2);
163 assertEquals(printer1.hashCode(), printer2.hashCode());
164
165 assertNotEquals(printer1, new Object());
166 }
167
168 @DefaultLocale(language = "en", country = "US")
169 @DefaultTimeZone("America/New_York")
170 @Test
171 public void testFormat() {
172 final GregorianCalendar cal1 = new GregorianCalendar(2003, 0, 10, 15, 33, 20);
173 final GregorianCalendar cal2 = new GregorianCalendar(2003, 6, 10, 9, 0, 0);
174 final Date date1 = cal1.getTime();
175 final Date date2 = cal2.getTime();
176 final long millis1 = date1.getTime();
177 final long millis2 = date2.getTime();
178
179 DatePrinter fdf = getInstance("yyyy-MM-dd'T'HH:mm:ss");
180 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
181 assertEquals(sdf.format(date1), fdf.format(date1));
182 assertEquals("2003-01-10T15:33:20", fdf.format(date1));
183 assertEquals("2003-01-10T15:33:20", fdf.format(cal1));
184 assertEquals("2003-01-10T15:33:20", fdf.format(millis1));
185 assertEquals("2003-07-10T09:00:00", fdf.format(date2));
186 assertEquals("2003-07-10T09:00:00", fdf.format(cal2));
187 assertEquals("2003-07-10T09:00:00", fdf.format(millis2));
188
189 fdf = getInstance("Z");
190 assertEquals("-0500", fdf.format(date1));
191 assertEquals("-0500", fdf.format(cal1));
192 assertEquals("-0500", fdf.format(millis1));
193
194 assertEquals("-0400", fdf.format(date2));
195 assertEquals("-0400", fdf.format(cal2));
196 assertEquals("-0400", fdf.format(millis2));
197
198 fdf = getInstance("ZZ");
199 assertEquals("-05:00", fdf.format(date1));
200 assertEquals("-05:00", fdf.format(cal1));
201 assertEquals("-05:00", fdf.format(millis1));
202
203 assertEquals("-04:00", fdf.format(date2));
204 assertEquals("-04:00", fdf.format(cal2));
205 assertEquals("-04:00", fdf.format(millis2));
206
207 final String pattern = "GGGG GGG GG G yyyy yyy yy y MMMM MMM MM M" +
208 " dddd ddd dd d DDDD DDD DD D EEEE EEE EE E aaaa aaa aa a zzzz zzz zz z";
209 fdf = getInstance(pattern);
210 sdf = new SimpleDateFormat(pattern);
211 // SDF bug fix starting with Java 7
212 assertEquals(sdf.format(date1).replaceAll("2003 03 03 03", "2003 2003 03 2003"), fdf.format(date1));
213 assertEquals(sdf.format(date2).replaceAll("2003 03 03 03", "2003 2003 03 2003"), fdf.format(date2));
214 }
215
216 @Test
217 public void testHourFormats() {
218 final Calendar calendar = Calendar.getInstance();
219 calendar.clear();
220 final DatePrinter printer = getInstance("K k H h");
221
222 calendar.set(Calendar.HOUR_OF_DAY, 0);
223 assertEquals("0 24 0 12", printer.format(calendar));
224
225 calendar.set(Calendar.HOUR_OF_DAY, 12);
226 assertEquals("0 12 12 12", printer.format(calendar));
227
228 calendar.set(Calendar.HOUR_OF_DAY, 23);
229 assertEquals("11 23 23 11", printer.format(calendar));
323230 }
324231
325232 @Test
332239 assertEquals("002", getInstance("ddd", SWEDEN).format(cal));
333240 assertEquals("0002", getInstance("dddd", SWEDEN).format(cal));
334241 assertEquals("00002", getInstance("ddddd", SWEDEN).format(cal));
242 }
243
244 @Test
245 public void testLang303() {
246 final Calendar cal = Calendar.getInstance();
247 cal.set(2004, Calendar.DECEMBER, 31);
248
249 DatePrinter format = getInstance(YYYY_MM_DD);
250 final String output = format.format(cal);
251
252 format = SerializationUtils.deserialize(SerializationUtils.serialize((Serializable) format));
253 assertEquals(output, format.format(cal));
254 }
255
256 @Test
257 public void testLang538() {
258 // more commonly constructed with: cal = new GregorianCalendar(2009, 9, 16, 8, 42, 16)
259 // for the unit test to work in any time zone, constructing with GMT-8 rather than default locale time zone
260 final GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT-8"));
261 cal.clear();
262 cal.set(2009, Calendar.OCTOBER, 16, 8, 42, 16);
263
264 final DatePrinter format = getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("GMT"));
265 assertEquals("2009-10-16T16:42:16.000Z", format.format(cal.getTime()), "dateTime");
266 assertEquals("2009-10-16T16:42:16.000Z", format.format(cal), "dateTime");
267 }
268
269 @Test
270 public void testLang645() {
271 final Locale locale = new Locale("sv", "SE");
272
273 final Calendar cal = Calendar.getInstance();
274 cal.set(2010, Calendar.JANUARY, 1, 12, 0, 0);
275 final Date d = cal.getTime();
276
277 final DatePrinter fdf = getInstance("EEEE', week 'ww", locale);
278
279 assertEquals("fredag, week 53", fdf.format(d));
335280 }
336281
337282 /**
363308 }
364309
365310 @Test
366 public void testHourFormats() {
367 final Calendar calendar = Calendar.getInstance();
368 calendar.clear();
369 final DatePrinter printer = getInstance("K k H h");
370
371 calendar.set(Calendar.HOUR_OF_DAY, 0);
372 assertEquals("0 24 0 12", printer.format(calendar));
373
374 calendar.set(Calendar.HOUR_OF_DAY, 12);
375 assertEquals("0 12 12 12", printer.format(calendar));
376
377 calendar.set(Calendar.HOUR_OF_DAY, 23);
378 assertEquals("11 23 23 11", printer.format(calendar));
311 public void testLocaleMatches() {
312 final DatePrinter printer= getInstance(YYYY_MM_DD, SWEDEN);
313 assertEquals(SWEDEN, printer.getLocale());
314 }
315
316 /**
317 * Tests that pre-1000AD years get padded with yyyy
318 */
319 @Test
320 public void testLowYearPadding() {
321 final Calendar cal = Calendar.getInstance();
322 final DatePrinter format = getInstance(YYYY_MM_DD);
323
324 cal.set(1, Calendar.JANUARY, 1);
325 assertEquals("0001/01/01", format.format(cal));
326 cal.set(10, Calendar.JANUARY, 1);
327 assertEquals("0010/01/01", format.format(cal));
328 cal.set(100, Calendar.JANUARY, 1);
329 assertEquals("0100/01/01", format.format(cal));
330 cal.set(999, Calendar.JANUARY, 1);
331 assertEquals("0999/01/01", format.format(cal));
332 }
333
334 /**
335 * Show Bug #39410 is solved
336 */
337 @Test
338 public void testMilleniumBug() {
339 final Calendar cal = Calendar.getInstance();
340 final DatePrinter format = getInstance("dd.MM.yyyy");
341
342 cal.set(1000, Calendar.JANUARY, 1);
343 assertEquals("01.01.1000", format.format(cal));
344 }
345
346 @Test
347 public void testPatternMatches() {
348 final DatePrinter printer= getInstance(YYYY_MM_DD);
349 assertEquals(YYYY_MM_DD, printer.getPattern());
350 }
351
352 /**
353 * Test case for {@link FastDateParser#FastDateParser(String, TimeZone, Locale)}.
354 */
355 @Test
356 public void testShortDateStyleWithLocales() {
357 final Locale usLocale = Locale.US;
358 final Locale swedishLocale = new Locale("sv", "SE");
359 final Calendar cal = Calendar.getInstance();
360 cal.set(2004, Calendar.FEBRUARY, 3);
361 DatePrinter fdf = getDateInstance(FastDateFormat.SHORT, usLocale);
362 assertEquals("2/3/04", fdf.format(cal));
363
364 fdf = getDateInstance(FastDateFormat.SHORT, swedishLocale);
365 assertEquals("2004-02-03", fdf.format(cal));
366
367 }
368
369 /**
370 * testLowYearPadding showed that the date was buggy
371 * This test confirms it, getting 366 back as a date
372 */
373 @Test
374 public void testSimpleDate() {
375 final Calendar cal = Calendar.getInstance();
376 final DatePrinter format = getInstance(YYYY_MM_DD);
377
378 cal.set(2004, Calendar.DECEMBER, 31);
379 assertEquals("2004/12/31", format.format(cal));
380 cal.set(999, Calendar.DECEMBER, 31);
381 assertEquals("0999/12/31", format.format(cal));
382 cal.set(1, Calendar.MARCH, 2);
383 assertEquals("0001/03/02", format.format(cal));
379384 }
380385
381386 @SuppressWarnings("deprecation")
401406 assertEquals(expected, format.format(epoch, sb).toString());
402407 }
403408
404 @Test
405 public void testAppendableOptions() {
406 final DatePrinter format = getInstance("yyyy-MM-dd HH:mm:ss.SSS Z", TimeZone.getTimeZone("GMT"));
407 final Calendar calendar = Calendar.getInstance();
408 final StringBuilder sb = new StringBuilder();
409 final String expected = format.format(calendar, sb).toString();
410 sb.setLength(0);
411
412 final Date date = calendar.getTime();
413 assertEquals(expected, format.format(date, sb).toString());
414 sb.setLength(0);
415
416 final long epoch = date.getTime();
417 assertEquals(expected, format.format(epoch, sb).toString());
418 }
419
420 @Test
421 public void testDayNumberOfWeek() {
422 final DatePrinter printer = getInstance("u");
423 final Calendar calendar = Calendar.getInstance();
424
425 calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
426 assertEquals("1", printer.format(calendar.getTime()));
427
428 calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
429 assertEquals("6", printer.format(calendar.getTime()));
430
431 calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
432 assertEquals("7", printer.format(calendar.getTime()));
409 @DefaultTimeZone("UTC")
410 @Test
411 public void testTimeZoneAsZ() {
412 final Calendar c = Calendar.getInstance(FastTimeZone.getGmtTimeZone());
413 final FastDateFormat noColonFormat = FastDateFormat.getInstance("Z");
414 assertEquals("+0000", noColonFormat.format(c));
415
416 final FastDateFormat isoFormat = FastDateFormat.getInstance("ZZ");
417 assertEquals("Z", isoFormat.format(c));
418
419 final FastDateFormat colonFormat = FastDateFormat.getInstance("ZZZ");
420 assertEquals("+00:00", colonFormat.format(c));
421 }
422
423 @Test
424 public void testTimeZoneMatches() {
425 final DatePrinter printer= getInstance(YYYY_MM_DD, NEW_YORK);
426 assertEquals(NEW_YORK, printer.getTimeZone());
427 }
428
429 @Test
430 public void testToStringContainsName() {
431 final DatePrinter printer= getInstance(YYYY_MM_DD);
432 assertTrue(printer.toString().startsWith("FastDate"));
433 }
434
435 @DefaultLocale(language = "en", country = "US")
436 @DefaultTimeZone("America/New_York")
437 @Test
438 public void testWeekYear() {
439 final GregorianCalendar cal = new GregorianCalendar(2020, 12, 31, 0, 0, 0);
440 final DatePrinter printer4Digits = getInstance("YYYY");
441 final DatePrinter printer4DigitsFallback = getInstance("YYY");
442 final DatePrinter printer2Digits = getInstance("YY");
443 final DatePrinter printer4DigitAnotherFallback = getInstance("Y");
444 assertEquals("2021", printer4Digits.format(cal));
445 assertEquals("2021", printer4DigitsFallback.format(cal));
446 assertEquals("2021", printer4DigitAnotherFallback.format(cal));
447 assertEquals("21", printer2Digits.format(cal));
433448 }
434449 }
3232 private static final int MINUTES_5 = 5 * 60 * 1000;
3333
3434 @Test
35 public void testGetGmtTimeZone() {
36 assertEquals(0, FastTimeZone.getGmtTimeZone().getRawOffset());
37 }
38
39 @Test
4035 public void testBareGmt() {
4136 assertEquals(FastTimeZone.getGmtTimeZone(), FastTimeZone.getTimeZone("GMT"));
4237 }
4338
4439 @Test
45 public void testZ() {
46 assertEquals(FastTimeZone.getGmtTimeZone(), FastTimeZone.getTimeZone("Z"));
47 }
48
49 @Test
50 public void testUTC() {
51 assertEquals(FastTimeZone.getGmtTimeZone(), FastTimeZone.getTimeZone("UTC"));
52 }
53
54 @Test
55 public void testZeroOffsetsReturnSingleton() {
56 assertEquals(FastTimeZone.getGmtTimeZone(), FastTimeZone.getTimeZone("+0"));
57 assertEquals(FastTimeZone.getGmtTimeZone(), FastTimeZone.getTimeZone("-0"));
58 }
59
60 @Test
61 public void testOlson() {
62 assertEquals(TimeZone.getTimeZone("America/New_York"), FastTimeZone.getTimeZone("America/New_York"));
40 public void testGetGmtTimeZone() {
41 assertEquals(0, FastTimeZone.getGmtTimeZone().getRawOffset());
6342 }
6443
6544 @Test
6645 public void testGmtPrefix() {
6746 assertEquals(HOURS_23, FastTimeZone.getGmtTimeZone("GMT+23:00").getRawOffset());
6847 assertEquals(-HOURS_23, FastTimeZone.getGmtTimeZone("GMT-23:00").getRawOffset());
69 }
70
71 @Test
72 public void testSign() {
73 assertEquals(HOURS_23, FastTimeZone.getGmtTimeZone("+23:00").getRawOffset());
74 assertEquals(HOURS_2, FastTimeZone.getGmtTimeZone("+2:00").getRawOffset());
75 assertEquals(-HOURS_23, FastTimeZone.getGmtTimeZone("-23:00").getRawOffset());
76 assertEquals(-HOURS_2, FastTimeZone.getGmtTimeZone("-2:00").getRawOffset());
7748 }
7849
7950 @Test
9667 assertEquals(HOURS_2+MINUTES_5, FastTimeZone.getGmtTimeZone("0205").getRawOffset());
9768 }
9869
70 @Test
71 public void testOlson() {
72 assertEquals(TimeZone.getTimeZone("America/New_York"), FastTimeZone.getTimeZone("America/New_York"));
73 }
74
75 @Test
76 public void testSign() {
77 assertEquals(HOURS_23, FastTimeZone.getGmtTimeZone("+23:00").getRawOffset());
78 assertEquals(HOURS_2, FastTimeZone.getGmtTimeZone("+2:00").getRawOffset());
79 assertEquals(-HOURS_23, FastTimeZone.getGmtTimeZone("-23:00").getRawOffset());
80 assertEquals(-HOURS_2, FastTimeZone.getGmtTimeZone("-2:00").getRawOffset());
81 }
82
83 @Test
84 public void testUTC() {
85 assertEquals(FastTimeZone.getGmtTimeZone(), FastTimeZone.getTimeZone("UTC"));
86 }
87
88 @Test
89 public void testZ() {
90 assertEquals(FastTimeZone.getGmtTimeZone(), FastTimeZone.getTimeZone("Z"));
91 }
92
93 @Test
94 public void testZeroOffsetsReturnSingleton() {
95 assertEquals(FastTimeZone.getGmtTimeZone(), FastTimeZone.getTimeZone("+0"));
96 assertEquals(FastTimeZone.getGmtTimeZone(), FastTimeZone.getTimeZone("-0"));
97 }
98
9999 }
2727 public class GmtTimeZoneTest {
2828
2929 @Test
30 public void hoursOutOfRange() {
31 assertThrows(IllegalArgumentException.class, () -> new GmtTimeZone(false, 24, 0));
32 }
33
34 @Test
35 public void hoursInRange() {
36 assertEquals(23 * 60 * 60 * 1000, new GmtTimeZone(false, 23, 0).getRawOffset());
37 }
38
39 @Test
40 public void minutesOutOfRange() {
41 assertThrows(IllegalArgumentException.class, () -> new GmtTimeZone(false, 0, 60));
42 }
43
44 @Test
45 public void minutesInRange() {
46 assertEquals(59 * 60 * 1000, new GmtTimeZone(false, 0, 59).getRawOffset());
47 }
48
49 @Test
50 public void getOffset() {
51 assertEquals(0, new GmtTimeZone(false, 0, 0).getOffset(234304));
52 }
53
54 @Test
55 public void setRawOffset() {
56 assertThrows(UnsupportedOperationException.class, () -> new GmtTimeZone(false, 0, 0).setRawOffset(0));
57 }
58
59 @Test
60 public void getRawOffset() {
61 assertEquals(0, new GmtTimeZone(false, 0, 0).getRawOffset());
62 }
63
64 @Test
6530 public void getID() {
6631 assertEquals("GMT+00:00", new GmtTimeZone(false, 0, 0).getID());
6732 assertEquals("GMT+01:02", new GmtTimeZone(false, 1, 2).getID());
7136 }
7237
7338 @Test
74 public void useDaylightTime() {
75 assertFalse(new GmtTimeZone(false, 0, 0).useDaylightTime());
39 public void getOffset() {
40 assertEquals(0, new GmtTimeZone(false, 0, 0).getOffset(234304));
41 }
42
43 @Test
44 public void getRawOffset() {
45 assertEquals(0, new GmtTimeZone(false, 0, 0).getRawOffset());
46 }
47
48 @Test
49 public void hoursInRange() {
50 assertEquals(23 * 60 * 60 * 1000, new GmtTimeZone(false, 23, 0).getRawOffset());
51 }
52
53 @Test
54 public void hoursOutOfRange() {
55 assertThrows(IllegalArgumentException.class, () -> new GmtTimeZone(false, 24, 0));
7656 }
7757
7858 @Test
7959 public void inDaylightTime() {
8060 assertFalse(new GmtTimeZone(false, 0, 0).useDaylightTime());
61 }
62
63 @Test
64 public void minutesInRange() {
65 assertEquals(59 * 60 * 1000, new GmtTimeZone(false, 0, 59).getRawOffset());
66 }
67
68 @Test
69 public void minutesOutOfRange() {
70 assertThrows(IllegalArgumentException.class, () -> new GmtTimeZone(false, 0, 60));
71 }
72
73 @Test
74 public void setRawOffset() {
75 assertThrows(UnsupportedOperationException.class, () -> new GmtTimeZone(false, 0, 0).setRawOffset(0));
76 }
77
78 @Test
79 public void testGetOffset() {
80 assertEquals(-(6 * 60 + 30) * 60 * 1000,
81 new GmtTimeZone(true, 6, 30).getOffset(1, 1, 1, 1, 1, 1));
8182 }
8283
8384 @Test
8788 }
8889
8990 @Test
90 public void testGetOffset() {
91 assertEquals(-(6 * 60 + 30) * 60 * 1000,
92 new GmtTimeZone(true, 6, 30).getOffset(1, 1, 1, 1, 1, 1));
91 public void useDaylightTime() {
92 assertFalse(new GmtTimeZone(false, 0, 0).useDaylightTime());
9393 }
9494 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.commons.lang3.time;
18
19 import java.text.ParseException;
20 import java.text.SimpleDateFormat;
21 import java.util.Calendar;
22 import java.util.GregorianCalendar;
23 import java.util.Locale;
24 import java.util.TimeZone;
25
26 import org.apache.commons.lang3.function.TriFunction;
27 import org.junit.jupiter.api.Test;
28 import org.junit.jupiter.params.ParameterizedTest;
29 import org.junit.jupiter.params.provider.MethodSource;
30
31 /**
32 * These tests fail on Java 15 due to a bug which was only fixed for Java 16.
33 * <ul>
34 * <li>https://bugs.openjdk.java.net/browse/JDK-8248434</li>
35 * <li>https://bugs.openjdk.java.net/browse/JDK-8248655</li>
36 * </ul>
37 */
38 public class Java15BugFastDateParserTest {
39
40 /** @see org.apache.commons.lang3.time.FastDateParserTest#dateParserParameters() */
41 private static final String DATE_PARSER_PARAMETERS = "org.apache.commons.lang3.time.FastDateParserTest#dateParserParameters()";
42
43 @Test
44 public void java15BuggyLocaleTest() throws ParseException {
45 final String buggyLocaleName = "ff_LR_#Adlm";
46 Locale buggyLocale = null;
47 for (final Locale locale : Locale.getAvailableLocales()) {
48 if (buggyLocaleName.equals(locale.toString())) {
49 buggyLocale = locale;
50 break;
51 }
52 }
53 if (buggyLocale == null) {
54 return;
55 }
56 testSingleLocale(buggyLocale);
57 }
58
59 @Test
60 public void java15BuggyLocaleTestAll() throws ParseException {
61 for (final Locale locale : Locale.getAvailableLocales()) {
62 testSingleLocale(locale);
63 }
64 }
65
66 private void testLocales(final TriFunction<String, TimeZone, Locale, DateParser> dbProvider, final String format,
67 final boolean eraBC) throws Exception {
68
69 final Calendar cal = Calendar.getInstance(FastDateParserTest.GMT);
70 cal.clear();
71 cal.set(2003, Calendar.FEBRUARY, 10);
72 if (eraBC) {
73 cal.set(Calendar.ERA, GregorianCalendar.BC);
74 }
75
76 for (final Locale locale : Locale.getAvailableLocales()) {
77 // ja_JP_JP cannot handle dates before 1868 properly
78 if (eraBC && locale.equals(FastDateParser.JAPANESE_IMPERIAL)) {
79 continue;
80 }
81 final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
82 final DateParser fdf = dbProvider.apply(format, TimeZone.getDefault(), locale);
83
84 // If parsing fails, a ParseException will be thrown and the test will fail
85 FastDateParserTest.checkParse(locale, cal, sdf, fdf);
86 }
87 }
88
89 @ParameterizedTest
90 @MethodSource(DATE_PARSER_PARAMETERS)
91 public void testLocales_Long_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
92 throws Exception {
93 testLocales(dpProvider, FastDateParserTest.LONG_FORMAT, false);
94 }
95
96 @ParameterizedTest
97 @MethodSource(DATE_PARSER_PARAMETERS)
98 public void testLocales_Long_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
99 throws Exception {
100 testLocales(dpProvider, FastDateParserTest.LONG_FORMAT, true);
101 }
102
103 @ParameterizedTest
104 @MethodSource(DATE_PARSER_PARAMETERS)
105 public void testLocales_LongNoEra_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
106 throws Exception {
107 testLocales(dpProvider, FastDateParserTest.LONG_FORMAT_NOERA, false);
108 }
109
110 @ParameterizedTest
111 @MethodSource(DATE_PARSER_PARAMETERS)
112 public void testLocales_LongNoEra_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
113 throws Exception {
114 testLocales(dpProvider, FastDateParserTest.LONG_FORMAT_NOERA, true);
115 }
116
117 @ParameterizedTest
118 @MethodSource(DATE_PARSER_PARAMETERS)
119 public void testLocales_Short_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
120 throws Exception {
121 testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT, false);
122 }
123
124 @ParameterizedTest
125 @MethodSource(DATE_PARSER_PARAMETERS)
126 public void testLocales_Short_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
127 throws Exception {
128 testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT, true);
129 }
130
131 @ParameterizedTest
132 @MethodSource(DATE_PARSER_PARAMETERS)
133 public void testLocales_ShortNoEra_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
134 throws Exception {
135 testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT_NOERA, false);
136 }
137
138 @ParameterizedTest
139 @MethodSource(DATE_PARSER_PARAMETERS)
140 public void testLocales_ShortNoEra_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
141 throws Exception {
142 testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT_NOERA, true);
143 }
144
145 private void testSingleLocale(final Locale locale) throws ParseException {
146 final Calendar cal = Calendar.getInstance(FastDateParserTest.GMT);
147 cal.clear();
148 cal.set(2003, Calendar.FEBRUARY, 10);
149 final SimpleDateFormat sdf = new SimpleDateFormat(FastDateParserTest.LONG_FORMAT, locale);
150 final String formattedDate = sdf.format(cal.getTime());
151 sdf.parse(formattedDate);
152 sdf.parse(formattedDate.toUpperCase(locale));
153 sdf.parse(formattedDate.toLowerCase(locale));
154 }
155
156 }
2222 import static org.junit.jupiter.api.Assertions.assertThrows;
2323 import static org.junit.jupiter.api.Assertions.assertTrue;
2424
25 import java.time.Duration;
2526 import java.util.concurrent.TimeUnit;
2627
28 import org.apache.commons.lang3.ThreadUtils;
2729 import org.apache.commons.lang3.reflect.FieldUtils;
2830 import org.junit.jupiter.api.Test;
2931
3234 */
3335 public class StopWatchTest {
3436
37 private static final Duration MILLIS_200 = Duration.ofMillis(200);
38 private static final Duration MILLIS_550 = Duration.ofMillis(550);
3539 private static final String MESSAGE = "Baking cookies";
3640 private static final int MIN_SLEEP_MILLISECONDS = 20;
3741 private static final String ZERO_HOURS_PREFIX = "00:";
3943
4044 /**
4145 * <p>
42 * Creates a suspended StopWatch object which appears to have elapsed
43 * for the requested amount of time in nanoseconds.
46 * Creates a suspended StopWatch object which appears to have elapsed for the requested amount of time in
47 * nanoseconds.
4448 * <p>
4549 * <p>
50 *
4651 * <pre>
4752 * // Create a mock StopWatch with a time of 2:59:01.999
4853 * final long nanos = TimeUnit.HOURS.toNanos(2)
6065 watch.suspend();
6166 try {
6267 final long currentNanos = System.nanoTime();
63 FieldUtils.writeField(watch, "startTime", currentNanos - nanos, true);
64 FieldUtils.writeField(watch, "stopTime", currentNanos, true);
68 FieldUtils.writeField(watch, "startTimeNanos", currentNanos - nanos, true);
69 FieldUtils.writeField(watch, "stopTimeNanos", currentNanos, true);
6570 } catch (final IllegalAccessException e) {
6671 return null;
6772 }
6873 return watch;
6974 }
7075
76 private void sleepQuietly(final Duration duration) throws InterruptedException {
77 ThreadUtils.sleep(duration);
78 }
79
7180 // test bad states
7281 @Test
7382 public void testBadStates() {
7483 final StopWatch watch = new StopWatch();
75 assertThrows(
76 IllegalStateException.class,
77 watch::stop,
78 "Calling stop on an unstarted StopWatch should throw an exception. ");
79
80 assertThrows(
81 IllegalStateException.class,
82 watch::suspend,
83 "Calling suspend on an unstarted StopWatch should throw an exception. ");
84
85 assertThrows(
86 IllegalStateException.class,
87 watch::split,
88 "Calling split on a non-running StopWatch should throw an exception. ");
89
90 assertThrows(
91 IllegalStateException.class,
92 watch::unsplit,
93 "Calling unsplit on an unsplit StopWatch should throw an exception. ");
94
95 assertThrows(
96 IllegalStateException.class,
97 watch::resume,
98 "Calling resume on an unsuspended StopWatch should throw an exception. ");
99
100 watch.start();
101
102 assertThrows(
103 IllegalStateException.class,
104 watch::start,
105 "Calling start on a started StopWatch should throw an exception. ");
106
107 assertThrows(
108 IllegalStateException.class,
109 watch::unsplit,
110 "Calling unsplit on an unsplit StopWatch should throw an exception. ");
111
112 assertThrows(
113 IllegalStateException.class,
114 watch::getSplitTime,
115 "Calling getSplitTime on an unsplit StopWatch should throw an exception. ");
116
117 assertThrows(
118 IllegalStateException.class,
119 watch::resume,
120 "Calling resume on an unsuspended StopWatch should throw an exception. ");
121
122 watch.stop();
123
124 assertThrows(
125 IllegalStateException.class,
126 watch::start,
127 "Calling start on a stopped StopWatch should throw an exception as it needs to be reset. ");
84 assertThrows(IllegalStateException.class, watch::stop,
85 "Calling stop on an unstarted StopWatch should throw an exception. ");
86
87 assertThrows(IllegalStateException.class, watch::suspend,
88 "Calling suspend on an unstarted StopWatch should throw an exception. ");
89
90 assertThrows(IllegalStateException.class, watch::split,
91 "Calling split on a non-running StopWatch should throw an exception. ");
92
93 assertThrows(IllegalStateException.class, watch::unsplit,
94 "Calling unsplit on an unsplit StopWatch should throw an exception. ");
95
96 assertThrows(IllegalStateException.class, watch::resume,
97 "Calling resume on an unsuspended StopWatch should throw an exception. ");
98
99 watch.start();
100
101 assertThrows(IllegalStateException.class, watch::start,
102 "Calling start on a started StopWatch should throw an exception. ");
103
104 assertThrows(IllegalStateException.class, watch::unsplit,
105 "Calling unsplit on an unsplit StopWatch should throw an exception. ");
106
107 assertThrows(IllegalStateException.class, watch::getSplitTime,
108 "Calling getSplitTime on an unsplit StopWatch should throw an exception. ");
109
110 assertThrows(IllegalStateException.class, watch::resume,
111 "Calling resume on an unsuspended StopWatch should throw an exception. ");
112
113 watch.stop();
114
115 assertThrows(IllegalStateException.class, watch::start,
116 "Calling start on a stopped StopWatch should throw an exception as it needs to be reset. ");
128117 }
129118
130119 @Test
188177
189178 @Test
190179 public void testGetStartTime() {
191 final long beforeStopWatch = System.currentTimeMillis();
180 final long beforeStopWatchMillis = System.currentTimeMillis();
192181 final StopWatch watch = new StopWatch();
193 assertThrows(
194 IllegalStateException.class,
195 watch::getStartTime,
196 "Calling getStartTime on an unstarted StopWatch should throw an exception");
182 assertThrows(IllegalStateException.class, watch::getStartTime,
183 "Calling getStartTime on an unstarted StopWatch should throw an exception");
197184 watch.start();
198185
199186 watch.getStartTime();
200 assertTrue(watch.getStartTime() >= beforeStopWatch);
187 assertTrue(watch.getStartTime() >= beforeStopWatchMillis);
201188
202189 watch.reset();
203 assertThrows(
204 IllegalStateException.class,
205 watch::getStartTime,
206 "Calling getStartTime on a reset, but unstarted StopWatch should throw an exception");
207 }
208
209 @Test
210 public void testLang315() {
211 final StopWatch watch = StopWatch.createStarted();
212 try {
213 Thread.sleep(200);
214 } catch (final InterruptedException ex) {
215 // ignore
216 }
190 assertThrows(IllegalStateException.class, watch::getStartTime,
191 "Calling getStartTime on a reset, but unstarted StopWatch should throw an exception");
192 }
193
194 @Test
195 public void testLang315() throws InterruptedException {
196 final StopWatch watch = StopWatch.createStarted();
197 sleepQuietly(MILLIS_200);
217198 watch.suspend();
218199 final long suspendTime = watch.getTime();
219 try {
220 Thread.sleep(200);
221 } catch (final InterruptedException ex) {
222 // ignore
223 }
200 sleepQuietly(MILLIS_200);
224201 watch.stop();
225202 final long totalTime = watch.getTime();
226203 assertEquals(suspendTime, totalTime);
238215 }
239216
240217 @Test
218 public void testStopTimeSimple() throws InterruptedException {
219 final StopWatch watch = StopWatch.createStarted();
220 final long testStartMillis = System.currentTimeMillis();
221 sleepQuietly(MILLIS_550);
222 watch.stop();
223 final long testEndMillis = System.currentTimeMillis();
224 final long stopTime = watch.getStopTime();
225 assertEquals(stopTime, watch.getStopTime());
226
227 assertTrue(stopTime >= testStartMillis);
228 assertTrue(stopTime <= testEndMillis);
229 }
230
231 @Test
241232 public void testStopWatchGetWithTimeUnit() {
242233 // Create a mock StopWatch with a time of 2:59:01.999
234 // @formatter:off
243235 final StopWatch watch = createMockStopWatch(
244 TimeUnit.HOURS.toNanos(2)
245 + TimeUnit.MINUTES.toNanos(59)
246 + TimeUnit.SECONDS.toNanos(1)
247 + TimeUnit.MILLISECONDS.toNanos(999));
236 TimeUnit.HOURS.toNanos(2)
237 + TimeUnit.MINUTES.toNanos(59)
238 + TimeUnit.SECONDS.toNanos(1)
239 + TimeUnit.MILLISECONDS.toNanos(999));
240 // @formatter:on
248241
249242 assertEquals(2L, watch.getTime(TimeUnit.HOURS));
250243 assertEquals(179L, watch.getTime(TimeUnit.MINUTES));
253246 }
254247
255248 @Test
256 public void testStopWatchSimple() {
257 final StopWatch watch = StopWatch.createStarted();
258 try {
259 Thread.sleep(550);
260 } catch (final InterruptedException ex) {
261 // ignore
262 }
249 public void testStopWatchSimple() throws InterruptedException {
250 final StopWatch watch = StopWatch.createStarted();
251 sleepQuietly(MILLIS_550);
263252 watch.stop();
264253 final long time = watch.getTime();
265254 assertEquals(time, watch.getTime());
272261 }
273262
274263 @Test
275 public void testStopWatchSimpleGet() {
264 public void testStopWatchSimpleGet() throws InterruptedException {
276265 final StopWatch watch = new StopWatch();
277266 assertEquals(0, watch.getTime());
278267 assertEquals(ZERO_TIME_ELAPSED, watch.toString());
279268
280269 watch.start();
281 try {
282 Thread.sleep(500);
283 } catch (final InterruptedException ex) {
284 // ignore
285 }
270 sleepQuietly(MILLIS_550);
286271 assertTrue(watch.getTime() < 2000);
287272 }
288273
289274 @Test
290 public void testStopWatchSplit() {
291 final StopWatch watch = StopWatch.createStarted();
292 try {
293 Thread.sleep(550);
294 } catch (final InterruptedException ex) {
295 // ignore
296 }
275 public void testStopWatchSplit() throws InterruptedException {
276 final StopWatch watch = StopWatch.createStarted();
277 sleepQuietly(MILLIS_550);
297278 watch.split();
298279 final long splitTime = watch.getSplitTime();
299280 final String splitStr = watch.toSplitString();
300 try {
301 Thread.sleep(550);
302 } catch (final InterruptedException ex) {
303 // ignore
304 }
281 sleepQuietly(MILLIS_550);
305282 watch.unsplit();
306 try {
307 Thread.sleep(550);
308 } catch (final InterruptedException ex) {
309 // ignore
310 }
283 sleepQuietly(MILLIS_550);
311284 watch.stop();
312285 final long totalTime = watch.getTime();
313286
325298 }
326299
327300 @Test
328 public void testStopWatchSuspend() {
329 final StopWatch watch = StopWatch.createStarted();
330 try {
331 Thread.sleep(550);
332 } catch (final InterruptedException ex) {
333 // ignore
334 }
301 public void testStopWatchSuspend() throws InterruptedException {
302 final StopWatch watch = StopWatch.createStarted();
303 final long testStartMillis = System.currentTimeMillis();
304 sleepQuietly(MILLIS_550);
335305 watch.suspend();
306 final long testSuspendMillis = System.currentTimeMillis();
336307 final long suspendTime = watch.getTime();
337 try {
338 Thread.sleep(550);
339 } catch (final InterruptedException ex) {
340 // ignore
341 }
308 final long stopTime = watch.getStopTime();
309
310 assertTrue(testStartMillis <= stopTime);
311 assertTrue(testSuspendMillis <= stopTime);
312
313 sleepQuietly(MILLIS_550);
342314 watch.resume();
343 try {
344 Thread.sleep(550);
345 } catch (final InterruptedException ex) {
346 // ignore
347 }
315 sleepQuietly(MILLIS_550);
348316 watch.stop();
349317 final long totalTime = watch.getTime();
350318
355323 }
356324
357325 @Test
358 public void testToSplitString() {
359 final StopWatch watch = StopWatch.createStarted();
360 try {
361 Thread.sleep(550);
362 } catch (final InterruptedException ex) {
363 // ignore
364 }
326 public void testToSplitString() throws InterruptedException {
327 final StopWatch watch = StopWatch.createStarted();
328 sleepQuietly(MILLIS_550);
365329 watch.split();
366330 final String splitStr = watch.toSplitString();
367331 assertEquals(splitStr.length(), 12, "Formatted split string not the correct length");
368332 }
369333
370334 @Test
371 public void testToSplitStringWithMessage() {
335 public void testToSplitStringWithMessage() throws InterruptedException {
372336 final StopWatch watch = new StopWatch(MESSAGE);
373337 watch.start();
374 try {
375 Thread.sleep(550);
376 } catch (final InterruptedException ex) {
377 // ignore
378 }
338 sleepQuietly(MILLIS_550);
379339 watch.split();
380340 final String splitStr = watch.toSplitString();
381341 assertEquals(splitStr.length(), 12 + MESSAGE.length() + 1, "Formatted split string not the correct length");
382342 }
383343
384344 @Test
385 public void testToString() {
345 public void testToString() throws InterruptedException {
386346 //
387347 final StopWatch watch = StopWatch.createStarted();
388 try {
389 Thread.sleep(550);
390 } catch (final InterruptedException ex) {
391 // ignore
392 }
348 sleepQuietly(MILLIS_550);
393349 watch.split();
394350 final String splitStr = watch.toString();
395351 assertEquals(splitStr.length(), 12, "Formatted split string not the correct length");
396352 }
397353
398354 @Test
399 public void testToStringWithMessage() {
355 public void testToStringWithMessage() throws InterruptedException {
400356 assertTrue(new StopWatch(MESSAGE).toString().startsWith(MESSAGE));
401357 //
402358 final StopWatch watch = new StopWatch(MESSAGE);
403359 watch.start();
404 try {
405 Thread.sleep(550);
406 } catch (final InterruptedException ex) {
407 // ignore
408 }
360 sleepQuietly(MILLIS_550);
409361 watch.split();
410362 final String splitStr = watch.toString();
411363 assertEquals(splitStr.length(), 12 + MESSAGE.length() + 1, "Formatted split string not the correct length");
2222 import static org.junit.jupiter.api.Assertions.assertSame;
2323 import static org.junit.jupiter.api.Assertions.assertTrue;
2424
25 import java.io.ByteArrayInputStream;
26 import java.io.ByteArrayOutputStream;
27 import java.io.ObjectInputStream;
28 import java.io.ObjectOutputStream;
2925 import java.util.ArrayList;
3026 import java.util.HashMap;
3127 import java.util.Iterator;
3228 import java.util.Map.Entry;
3329 import java.util.TreeMap;
3430
31 import org.apache.commons.lang3.SerializationUtils;
3532 import org.junit.jupiter.api.Test;
3633
3734 /**
3835 * Test the Pair class.
3936 */
4037 public class ImmutablePairTest {
41
42 @Test
43 public void testEmptyArrayLength() {
44 @SuppressWarnings("unchecked")
45 final ImmutablePair<Integer, String>[] empty = (ImmutablePair<Integer, String>[]) ImmutablePair.EMPTY_ARRAY;
46 assertEquals(0, empty.length);
47 }
48
49 @Test
50 public void testEmptyArrayGenerics() {
51 final ImmutablePair<Integer, String>[] empty = ImmutablePair.emptyArray();
52 assertEquals(0, empty.length);
53 }
5438
5539 @Test
5640 public void testBasic() {
7963 }
8064
8165 @Test
66 public void testComparableLeftOnly() {
67 final Pair<String, String> pair1 = ImmutablePair.left("A");
68 final Pair<String, String> pair2 = ImmutablePair.left("B");
69 assertEquals("A", pair1.getLeft());
70 assertEquals("B", pair2.getLeft());
71 assertEquals(0, pair1.compareTo(pair1));
72 assertTrue(pair1.compareTo(pair2) < 0);
73 assertEquals(0, pair2.compareTo(pair2));
74 assertTrue(pair2.compareTo(pair1) > 0);
75 }
76
77 @Test
78 public void testComparableRightOnly() {
79 final Pair<String, String> pair1 = ImmutablePair.right("A");
80 final Pair<String, String> pair2 = ImmutablePair.right("B");
81 assertEquals("A", pair1.getRight());
82 assertEquals("B", pair2.getRight());
83 assertEquals(0, pair1.compareTo(pair1));
84 assertTrue(pair1.compareTo(pair2) < 0);
85 assertEquals(0, pair2.compareTo(pair2));
86 assertTrue(pair2.compareTo(pair1) > 0);
87 }
88
89 @Test
90 public void testEmptyArrayGenerics() {
91 final ImmutablePair<Integer, String>[] empty = ImmutablePair.emptyArray();
92 assertEquals(0, empty.length);
93 }
94
95 @Test
96 public void testEmptyArrayLength() {
97 @SuppressWarnings("unchecked")
98 final ImmutablePair<Integer, String>[] empty = (ImmutablePair<Integer, String>[]) ImmutablePair.EMPTY_ARRAY;
99 assertEquals(0, empty.length);
100 }
101
102 @Test
82103 public void testEquals() {
83104 assertEquals(ImmutablePair.of(null, "foo"), ImmutablePair.of(null, "foo"));
84105 assertNotEquals(ImmutablePair.of("foo", 0), ImmutablePair.of("foo", null));
154175 assertNull(pair2.getLeft());
155176 assertEquals("bar", pair2.right);
156177 assertEquals("bar", pair2.getRight());
157 final ImmutablePair pair3 = ImmutablePair.of(null, null);
178 final ImmutablePair<?, ?> pair3 = ImmutablePair.of(null, null);
158179 assertNull(pair3.left);
159180 assertNull(pair3.right);
160181 }
163184 @SuppressWarnings("unchecked")
164185 public void testSerialization() throws Exception {
165186 final ImmutablePair<Integer, String> origPair = ImmutablePair.of(0, "foo");
166 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
167 final ObjectOutputStream out = new ObjectOutputStream(baos);
168 out.writeObject(origPair);
169 final ImmutablePair<Integer, String> deserializedPair = (ImmutablePair<Integer, String>) new ObjectInputStream(
170 new ByteArrayInputStream(baos.toByteArray())).readObject();
187 final ImmutablePair<Integer, String> deserializedPair = SerializationUtils.roundtrip(origPair);
171188 assertEquals(origPair, deserializedPair);
172189 assertEquals(origPair.hashCode(), deserializedPair.hashCode());
173190 }
178195 assertEquals("(null,two)", ImmutablePair.of(null, "two").toString());
179196 assertEquals("(one,null)", ImmutablePair.of("one", null).toString());
180197 assertEquals("(one,two)", ImmutablePair.of("one", "two").toString());
198 }
199
200 @Test
201 public void testToStringLeft() {
202 final Pair<String, String> pair = ImmutablePair.left("Key");
203 assertEquals("(Key,null)", pair.toString());
204 }
205
206 @Test
207 public void testToStringRight() {
208 final Pair<String, String> pair = ImmutablePair.right("Value");
209 assertEquals("(null,Value)", pair.toString());
181210 }
182211
183212 @Test
209238 assertEquals(item.getLeft() + "" + item.getRight(), entry.getValue());
210239 }
211240 }
212
213 @Test
214 public void testComparableLeftOnly() {
215 final Pair<String, String> pair1 = ImmutablePair.left("A");
216 final Pair<String, String> pair2 = ImmutablePair.left("B");
217 assertEquals("A", pair1.getLeft());
218 assertEquals("B", pair2.getLeft());
219 assertEquals(0, pair1.compareTo(pair1));
220 assertTrue(pair1.compareTo(pair2) < 0);
221 assertEquals(0, pair2.compareTo(pair2));
222 assertTrue(pair2.compareTo(pair1) > 0);
223 }
224
225 @Test
226 public void testComparableRightOnly() {
227 final Pair<String, String> pair1 = ImmutablePair.right("A");
228 final Pair<String, String> pair2 = ImmutablePair.right("B");
229 assertEquals("A", pair1.getRight());
230 assertEquals("B", pair2.getRight());
231 assertEquals(0, pair1.compareTo(pair1));
232 assertTrue(pair1.compareTo(pair2) < 0);
233 assertEquals(0, pair2.compareTo(pair2));
234 assertTrue(pair2.compareTo(pair1) > 0);
235 }
236
237 @Test
238 public void testToStringLeft() {
239 final Pair<String, String> pair = ImmutablePair.left("Key");
240 assertEquals("(Key,null)", pair.toString());
241 }
242
243 @Test
244 public void testToStringRight() {
245 final Pair<String, String> pair = ImmutablePair.right("Value");
246 assertEquals("(null,Value)", pair.toString());
247 }
248241 }
2121 import static org.junit.jupiter.api.Assertions.assertNull;
2222 import static org.junit.jupiter.api.Assertions.assertSame;
2323
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.ObjectInputStream;
27 import java.io.ObjectOutputStream;
2824 import java.util.ArrayList;
2925 import java.util.HashMap;
3026 import java.util.Iterator;
3127 import java.util.Map.Entry;
3228 import java.util.TreeMap;
3329
30 import org.apache.commons.lang3.SerializationUtils;
3431 import org.junit.jupiter.api.Test;
3532
3633 /**
3734 * Test the Triple class.
3835 */
3936 public class ImmutableTripleTest {
40
41 @Test
42 public void testEmptyArrayLength() {
43 @SuppressWarnings("unchecked")
44 final ImmutableTriple<Integer, String, Boolean>[] empty = (ImmutableTriple<Integer, String, Boolean>[]) ImmutableTriple.EMPTY_ARRAY;
45 assertEquals(0, empty.length);
46 }
47
48 @Test
49 public void testEmptyArrayGenerics() {
50 final ImmutableTriple<Integer, String, Boolean>[] empty = ImmutableTriple.emptyArray();
51 assertEquals(0, empty.length);
52 }
5337
5438 @Test
5539 public void testBasic() {
6751 assertEquals("bar", triple2.getMiddle());
6852 assertEquals(new Integer(42), triple2.right);
6953 assertEquals(new Integer(42), triple2.getRight());
54 }
55
56 @Test
57 public void testEmptyArrayGenerics() {
58 final ImmutableTriple<Integer, String, Boolean>[] empty = ImmutableTriple.emptyArray();
59 assertEquals(0, empty.length);
60 }
61
62 @Test
63 public void testEmptyArrayLength() {
64 @SuppressWarnings("unchecked")
65 final ImmutableTriple<Integer, String, Boolean>[] empty = (ImmutableTriple<Integer, String, Boolean>[]) ImmutableTriple.EMPTY_ARRAY;
66 assertEquals(0, empty.length);
7067 }
7168
7269 @Test
122119 @SuppressWarnings("unchecked")
123120 public void testSerialization() throws Exception {
124121 final ImmutableTriple<Integer, String, Boolean> origTriple = ImmutableTriple.of(0, "foo", Boolean.TRUE);
125 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
126 final ObjectOutputStream out = new ObjectOutputStream(baos);
127 out.writeObject(origTriple);
128 final ImmutableTriple<Integer, String, Boolean> deserializedTriple = (ImmutableTriple<Integer, String, Boolean>) new ObjectInputStream(
129 new ByteArrayInputStream(baos.toByteArray())).readObject();
122 final ImmutableTriple<Integer, String, Boolean> deserializedTriple = SerializationUtils.roundtrip(origTriple);
130123 assertEquals(origTriple, deserializedTriple);
131124 assertEquals(origTriple.hashCode(), deserializedTriple.hashCode());
132125 }
1919 import static org.junit.jupiter.api.Assertions.assertNotEquals;
2020 import static org.junit.jupiter.api.Assertions.assertNull;
2121
22 import java.io.ByteArrayInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.ObjectInputStream;
25 import java.io.ObjectOutputStream;
2622 import java.util.HashMap;
2723 import java.util.Map.Entry;
2824
25 import org.apache.commons.lang3.SerializationUtils;
2926 import org.junit.jupiter.api.Test;
3027
3128 /**
3229 * Test the MutablePair class.
3330 */
3431 public class MutablePairTest {
35
36 @Test
37 public void testEmptyArrayLength() {
38 @SuppressWarnings("unchecked")
39 final MutablePair<Integer, String>[] empty = (MutablePair<Integer, String>[]) MutablePair.EMPTY_ARRAY;
40 assertEquals(0, empty.length);
41 }
42
43 @Test
44 public void testEmptyArrayGenerics() {
45 final MutablePair<Integer, String>[] empty = MutablePair.emptyArray();
46 assertEquals(0, empty.length);
47 }
4832
4933 @Test
5034 public void testBasic() {
7761 final MutablePair<Integer, String> pair = new MutablePair<>();
7862 assertNull(pair.getLeft());
7963 assertNull(pair.getRight());
64 }
65
66 @Test
67 public void testEmptyArrayGenerics() {
68 final MutablePair<Integer, String>[] empty = MutablePair.emptyArray();
69 assertEquals(0, empty.length);
70 }
71
72 @Test
73 public void testEmptyArrayLength() {
74 @SuppressWarnings("unchecked")
75 final MutablePair<Integer, String>[] empty = (MutablePair<Integer, String>[]) MutablePair.EMPTY_ARRAY;
76 assertEquals(0, empty.length);
8077 }
8178
8279 @Test
122119 final MutablePair<Object, String> pair2 = MutablePair.of(null, "bar");
123120 assertNull(pair2.getLeft());
124121 assertEquals("bar", pair2.getRight());
125 final MutablePair pair3 = MutablePair.of(null, null);
122 final MutablePair<?, ?> pair3 = MutablePair.of(null, null);
126123 assertNull(pair3.left);
127124 assertNull(pair3.right);
128125 }
129126
130127 @Test
131 @SuppressWarnings("unchecked")
132128 public void testSerialization() throws Exception {
133129 final MutablePair<Integer, String> origPair = MutablePair.of(0, "foo");
134 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
135 final ObjectOutputStream out = new ObjectOutputStream(baos);
136 out.writeObject(origPair);
137 final MutablePair<Integer, String> deserializedPair = (MutablePair<Integer, String>) new ObjectInputStream(
138 new ByteArrayInputStream(baos.toByteArray())).readObject();
130 final MutablePair<Integer, String> deserializedPair = SerializationUtils.roundtrip(origPair);
139131 assertEquals(origPair, deserializedPair);
140132 assertEquals(origPair.hashCode(), deserializedPair.hashCode());
141133 }
1919 import static org.junit.jupiter.api.Assertions.assertNotEquals;
2020 import static org.junit.jupiter.api.Assertions.assertNull;
2121
22 import java.io.ByteArrayInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.ObjectInputStream;
25 import java.io.ObjectOutputStream;
26
22 import org.apache.commons.lang3.SerializationUtils;
2723 import org.junit.jupiter.api.Test;
2824
2925 /**
3026 * Test the MutableTriple class.
3127 */
3228 public class MutableTripleTest {
33
34 @Test
35 public void testEmptyArrayLength() {
36 @SuppressWarnings("unchecked")
37 final MutableTriple<Integer, String, Boolean>[] empty = (MutableTriple<Integer, String, Boolean>[]) MutableTriple.EMPTY_ARRAY;
38 assertEquals(0, empty.length);
39 }
40
41 @Test
42 public void testEmptyArrayGenerics() {
43 final MutableTriple<Integer, String, Boolean>[] empty = MutableTriple.emptyArray();
44 assertEquals(0, empty.length);
45 }
4629
4730 @Test
4831 public void testBasic() {
6245 assertNull(triple.getLeft());
6346 assertNull(triple.getMiddle());
6447 assertNull(triple.getRight());
48 }
49
50 @Test
51 public void testEmptyArrayGenerics() {
52 final MutableTriple<Integer, String, Boolean>[] empty = MutableTriple.emptyArray();
53 assertEquals(0, empty.length);
54 }
55
56 @Test
57 public void testEmptyArrayLength() {
58 @SuppressWarnings("unchecked")
59 final MutableTriple<Integer, String, Boolean>[] empty = (MutableTriple<Integer, String, Boolean>[]) MutableTriple.EMPTY_ARRAY;
60 assertEquals(0, empty.length);
6561 }
6662
6763 @Test
9692 @SuppressWarnings("unchecked")
9793 public void testSerialization() throws Exception {
9894 final MutableTriple<Integer, String, Boolean> origTriple = MutableTriple.of(0, "foo", Boolean.TRUE);
99 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
100 final ObjectOutputStream out = new ObjectOutputStream(baos);
101 out.writeObject(origTriple);
102 final MutableTriple<Integer, String, Boolean> deserializedTriple = (MutableTriple<Integer, String, Boolean>) new ObjectInputStream(
103 new ByteArrayInputStream(baos.toByteArray())).readObject();
95 final MutableTriple<Integer, String, Boolean> deserializedTriple = SerializationUtils.roundtrip(origTriple);
10496 assertEquals(origTriple, deserializedTriple);
10597 assertEquals(origTriple.hashCode(), deserializedTriple.hashCode());
10698 }
3333 public class PairTest {
3434
3535 @Test
36 public void testEmptyArrayLength() {
37 @SuppressWarnings("unchecked")
38 final Pair<Integer, String>[] empty = (Pair<Integer, String>[]) Pair.EMPTY_ARRAY;
39 assertEquals(0, empty.length);
40 }
41
42 @Test
43 public void testEmptyArrayGenerics() {
44 final Pair<Integer, String>[] empty = Pair.emptyArray();
45 assertEquals(0, empty.length);
46 }
47
48 @Test
4936 public void testComparable1() {
5037 final Pair<String, String> pair1 = Pair.of("A", "D");
5138 final Pair<String, String> pair2 = Pair.of("B", "C");
7865 pair2.setValue("bar");
7966 assertNotEquals(pair, pair2);
8067 assertNotEquals(pair.hashCode(), pair2.hashCode());
68 }
69
70 @Test
71 public void testEmptyArrayGenerics() {
72 final Pair<Integer, String>[] empty = Pair.emptyArray();
73 assertEquals(0, empty.length);
74 }
75
76 @Test
77 public void testEmptyArrayLength() {
78 @SuppressWarnings("unchecked")
79 final Pair<Integer, String>[] empty = (Pair<Integer, String>[]) Pair.EMPTY_ARRAY;
80 assertEquals(0, empty.length);
8181 }
8282
8383 @Test
2828 * Test the Triple class.
2929 */
3030 public class TripleTest {
31
32 @Test
33 public void testEmptyArrayLength() {
34 @SuppressWarnings("unchecked")
35 final Triple<Integer, String, Boolean>[] empty = (Triple<Integer, String, Boolean>[]) Triple.EMPTY_ARRAY;
36 assertEquals(0, empty.length);
37 }
38
39 @Test
40 public void testEmptyArrayGenerics() {
41 final Triple<Integer, String, Boolean>[] empty = Triple.emptyArray();
42 assertEquals(0, empty.length);
43 }
4431
4532 @Test
4633 public void testComparable1() {
9481 }
9582
9683 @Test
84 public void testEmptyArrayGenerics() {
85 final Triple<Integer, String, Boolean>[] empty = Triple.emptyArray();
86 assertEquals(0, empty.length);
87 }
88
89 @Test
90 public void testEmptyArrayLength() {
91 @SuppressWarnings("unchecked")
92 final Triple<Integer, String, Boolean>[] empty = (Triple<Integer, String, Boolean>[]) Triple.EMPTY_ARRAY;
93 assertEquals(0, empty.length);
94 }
95
96 @Test
9797 public void testFormattable_padded() {
9898 final Triple<String, String, String> triple = Triple.of("Key", "Something", "Value");
9999 assertEquals(" (Key,Something,Value)", String.format("%1$30s", triple));