clone of Guava 28.1
This commit is contained in:
commit
3ab350bb93
569 changed files with 162570 additions and 0 deletions
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
/data
|
||||
/work
|
||||
/logs
|
||||
/.idea
|
||||
/target
|
||||
.DS_Store
|
||||
*.iml
|
||||
/.settings
|
||||
/.classpath
|
||||
/.project
|
||||
/.gradle
|
||||
/build
|
3
.travis.yml
Normal file
3
.travis.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
language: java
|
||||
jdk:
|
||||
- openjdk11
|
202
LICENSE.txt
Normal file
202
LICENSE.txt
Normal file
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
29
README.adoc
Normal file
29
README.adoc
Normal file
|
@ -0,0 +1,29 @@
|
|||
# xbib Guava
|
||||
|
||||
This is xbib Guava, a build of Google Guava with the following differences to the
|
||||
original [Google Guava Library](https://github.com/google/guava):
|
||||
|
||||
- forked master branch on November 21, 2019 ("28.1+")
|
||||
- removed all external annotations, so this library does not have any dependencies
|
||||
- removed duplicate JDK classes (LongAdder, Striped64)
|
||||
- replaced sun.misc.Unsafe dependent classes with safe versions (LongAdders, UnsignedBytes, LittleEndianByteArray, AbstractFuture)
|
||||
- the guava failureaccess dependency is included
|
||||
- removed listenablefuture empty dependency hack
|
||||
- compiled under and for Java 11 and with a module info for JPMS (module org.xbib.guava)
|
||||
- Gradle as build system
|
||||
|
||||
All credits belong to the original authors
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
163
build.gradle
Normal file
163
build.gradle
Normal file
|
@ -0,0 +1,163 @@
|
|||
plugins {
|
||||
id "io.codearte.nexus-staging" version "0.21.1"
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
compileJava {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
compileTestJava {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs << "-Xlint:all"
|
||||
}
|
||||
|
||||
test {
|
||||
testLogging {
|
||||
showStandardStreams = false
|
||||
exceptionFormat = 'full'
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||
classifier 'javadoc'
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar, javadocJar
|
||||
}
|
||||
|
||||
ext {
|
||||
user = 'xbib'
|
||||
projectName = 'guava'
|
||||
projectDescription = 'Guava for Java'
|
||||
scmUrl = 'https://github.com/xbib/guava'
|
||||
scmConnection = 'scm:git:git://github.com/xbib/guava.git'
|
||||
scmDeveloperConnection = 'scm:git:git://github.com/xbib/guava.git'
|
||||
}
|
||||
|
||||
task sonatypeUpload(type: Upload) {
|
||||
group = 'publish'
|
||||
configuration = configurations.archives
|
||||
uploadDescriptor = true
|
||||
repositories {
|
||||
if (project.hasProperty('ossrhUsername')) {
|
||||
mavenDeployer {
|
||||
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
|
||||
repository(url: uri(ossrhReleaseUrl)) {
|
||||
authentication(userName: ossrhUsername, password: ossrhPassword)
|
||||
}
|
||||
snapshotRepository(url: uri(ossrhSnapshotUrl)) {
|
||||
authentication(userName: ossrhUsername, password: ossrhPassword)
|
||||
}
|
||||
pom.project {
|
||||
groupId project.group
|
||||
artifactId project.name
|
||||
version project.version
|
||||
name project.name
|
||||
description projectDescription
|
||||
packaging 'jar'
|
||||
inceptionYear '2019'
|
||||
url scmUrl
|
||||
organization {
|
||||
name 'xbib'
|
||||
url 'http://xbib.org'
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id user
|
||||
name 'Jörg Prante'
|
||||
email 'joergprante@gmail.com'
|
||||
url 'https://github.com/jprante'
|
||||
}
|
||||
}
|
||||
scm {
|
||||
url scmUrl
|
||||
connection scmConnection
|
||||
developerConnection scmDeveloperConnection
|
||||
}
|
||||
licenses {
|
||||
license {
|
||||
name 'The Apache License, Version 2.0'
|
||||
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nexusStaging {
|
||||
packageGroup = "org.xbib"
|
||||
}
|
||||
|
||||
/*
|
||||
spotbugs {
|
||||
effort = "max"
|
||||
reportLevel = "low"
|
||||
}
|
||||
|
||||
tasks.withType(com.github.spotbugs.SpotBugsTask) {
|
||||
ignoreFailures = true
|
||||
reports {
|
||||
xml.enabled = false
|
||||
html.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
pmd {
|
||||
toolVersion = '6.11.0'
|
||||
ruleSets = ['category/java/bestpractices.xml']
|
||||
}
|
||||
|
||||
tasks.withType(Pmd) {
|
||||
ignoreFailures = true
|
||||
reports {
|
||||
xml.enabled = true
|
||||
html.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = '8.26'
|
||||
configFile = rootProject.file('config/checkstyle/checkstyle.xml')
|
||||
ignoreFailures = true
|
||||
checkstyleMain {
|
||||
source = sourceSets.main.allSource
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(Checkstyle) {
|
||||
ignoreFailures = true
|
||||
reports {
|
||||
xml.enabled = true
|
||||
html.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
sonarqube {
|
||||
properties {
|
||||
property "sonar.projectName", "${project.group} ${project.name}"
|
||||
property "sonar.sourceEncoding", "UTF-8"
|
||||
property "sonar.tests", "src/test/java"
|
||||
property "sonar.scm.provider", "git"
|
||||
}
|
||||
}
|
||||
*/
|
177
config/checkstyle/checkstyle.xml
Normal file
177
config/checkstyle/checkstyle.xml
Normal file
|
@ -0,0 +1,177 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
<module name="Checker">
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${config_loc}/suppressions.xml"/>
|
||||
</module>
|
||||
|
||||
<module name="SuppressWarningsFilter"/>
|
||||
|
||||
<module name="SeverityMatchFilter">
|
||||
<property name="severity" value="info"/>
|
||||
<property name="acceptOnMatch" value="false"/>
|
||||
</module>
|
||||
|
||||
<module name="FileTabCharacter">
|
||||
<property name="eachLine" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="LineLength">
|
||||
<property name="max" value="120"/>
|
||||
<property name="ignorePattern" value="^[ \t]*\*.*@.*$"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<property name="tabWidth" value="4"/>
|
||||
|
||||
<module name="SuppressWarningsHolder"/>
|
||||
|
||||
<module name="Indentation">
|
||||
<property name="forceStrictCondition" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="ConstantName"/>
|
||||
|
||||
<module name="FinalParameters">
|
||||
<property name="tokens" value="METHOD_DEF, CTOR_DEF, LITERAL_CATCH, FOR_EACH_CLAUSE"/>
|
||||
</module>
|
||||
|
||||
<module name="FinalLocalVariable">
|
||||
<property name="validateEnhancedForLoopVariable" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="LocalFinalVariableName"/>
|
||||
|
||||
<module name="LocalVariableName"/>
|
||||
|
||||
<module name="MemberName">
|
||||
<property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
|
||||
</module>
|
||||
|
||||
<module name="MethodName"/>
|
||||
|
||||
<module name="PackageName"/>
|
||||
|
||||
<module name="ParameterName"/>
|
||||
|
||||
<module name="StaticVariableName"/>
|
||||
|
||||
<module name="TypeName"/>
|
||||
|
||||
<module name="RedundantImport"/>
|
||||
|
||||
<module name="UnusedImports"/>
|
||||
|
||||
<module name="MethodLength">
|
||||
<property name="tokens" value="METHOD_DEF"/>
|
||||
<property name="max" value="100"/>
|
||||
</module>
|
||||
|
||||
<module name="EmptyForInitializerPad"/>
|
||||
|
||||
<module name="MethodParamPad"/>
|
||||
|
||||
<module name="NoWhitespaceBefore"/>
|
||||
|
||||
<module name="WhitespaceAfter">
|
||||
<property name="tokens" value="COMMA, SEMI, LITERAL_IF, LITERAL_ELSE, LITERAL_WHILE, LITERAL_DO, LITERAL_FOR, DO_WHILE"/>
|
||||
</module>
|
||||
|
||||
<module name="NoWhitespaceAfter">
|
||||
<property name="tokens" value="INC, DEC, UNARY_MINUS, UNARY_PLUS, BNOT, LNOT, DOT, TYPECAST, ARRAY_DECLARATOR, INDEX_OP, METHOD_REF"/>
|
||||
<property name="allowLineBreaks" value="false"/>
|
||||
</module>
|
||||
|
||||
<module name="WhitespaceAround">
|
||||
<property name="allowEmptyLambdas" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="SingleSpaceSeparator"/>
|
||||
|
||||
<module name="OperatorWrap">
|
||||
<property name="option" value="eol"/>
|
||||
</module>
|
||||
|
||||
<module name="NeedBraces"/>
|
||||
|
||||
<module name="ParenPad"/>
|
||||
|
||||
<module name="TypecastParenPad"/>
|
||||
|
||||
<module name="ModifierOrder"/>
|
||||
|
||||
<module name="RedundantModifier"/>
|
||||
|
||||
<module name="NestedTryDepth">
|
||||
<property name="max" value="2"/>
|
||||
</module>
|
||||
|
||||
<module name="CovariantEquals"/>
|
||||
|
||||
<module name="LeftCurly">
|
||||
<property name="option" value="nl"/>
|
||||
</module>
|
||||
|
||||
<module name="RightCurly">
|
||||
<property name="option" value="alone"/>
|
||||
<property name="tokens" value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO, STATIC_INIT, INSTANCE_INIT"/>
|
||||
</module>
|
||||
|
||||
<module name="EmptyStatement"/>
|
||||
|
||||
<module name="EqualsHashCode"/>
|
||||
|
||||
<module name="DefaultComesLast"/>
|
||||
|
||||
<module name="SimplifyBooleanExpression"/>
|
||||
|
||||
<module name="SimplifyBooleanReturn"/>
|
||||
|
||||
<module name="StringLiteralEquality"/>
|
||||
|
||||
<module name="PackageDeclaration"/>
|
||||
|
||||
<module name="FallThrough"/>
|
||||
|
||||
<module name="FinalClass"/>
|
||||
|
||||
<module name="MutableException"/>
|
||||
|
||||
<module name="EmptyLineSeparator">
|
||||
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
||||
<property name="tokens" value="IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF, STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF"/>
|
||||
</module>
|
||||
|
||||
<module name="TodoComment">
|
||||
<property name="severity" value="info"/>
|
||||
<property name="format" value="TODO"/>
|
||||
</module>
|
||||
|
||||
<module name="UpperEll"/>
|
||||
|
||||
<module name="IllegalType">
|
||||
<property name="legalAbstractClassNames"
|
||||
value="AbstractBeanDefinition, AbstractEntry"/>
|
||||
<property name="illegalClassNames"
|
||||
value="java.util.GregorianCalendar, java.util.Vector"/>
|
||||
</module>
|
||||
|
||||
<module name="DescendantToken">
|
||||
<property name="tokens" value="LITERAL_ASSERT"/>
|
||||
<property name="limitedTokens"
|
||||
value="ASSIGN,DEC,INC,POST_DEC,POST_INC,PLUS_ASSIGN,MINUS_ASSIGN,STAR_ASSIGN,DIV_ASSIGN,MOD_ASSIGN,BSR_ASSIGN,SR_ASSIGN,SL_ASSIGN,BAND_ASSIGN,BXOR_ASSIGN,BOR_ASSIGN,METHOD_CALL"/>
|
||||
<property name="maximumNumber" value="2"/>
|
||||
</module>
|
||||
|
||||
<module name="Regexp">
|
||||
<property name="format" value="[ \t]+$"/>
|
||||
<property name="illegalPattern" value="true"/>
|
||||
<property name="message" value="Trailing whitespace"/>
|
||||
</module>
|
||||
|
||||
<module name="JavadocMethod">
|
||||
<property name="allowUndeclaredRTE" value="true"/>
|
||||
</module>
|
||||
</module>
|
||||
</module>
|
7
config/checkstyle/suppressions.xml
Normal file
7
config/checkstyle/suppressions.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Puppy Crawl//DTD Suppressions 1.0//EN"
|
||||
"https://checkstyle.org/dtds/suppressions_1_0.dtd">
|
||||
<suppressions>
|
||||
<suppress files=".*generated-src.*" checks="."/>
|
||||
</suppressions>
|
3
gradle.properties
Normal file
3
gradle.properties
Normal file
|
@ -0,0 +1,3 @@
|
|||
group = org.xbib
|
||||
name = guava
|
||||
version = 28.1
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
#Sat Nov 23 21:29:06 CET 2019
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
188
gradlew
vendored
Executable file
188
gradlew
vendored
Executable file
|
@ -0,0 +1,188 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
100
gradlew.bat
vendored
Normal file
100
gradlew.bat
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
1
settings.gradle
Normal file
1
settings.gradle
Normal file
|
@ -0,0 +1 @@
|
|||
rootProject.name = name
|
47
src/main/java/com/google/common/annotations/Beta.java
Normal file
47
src/main/java/com/google/common/annotations/Beta.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Signifies that a public API (public class, method or field) is subject to incompatible changes,
|
||||
* or even removal, in a future release. An API bearing this annotation is exempt from any
|
||||
* compatibility guarantees made by its containing library. Note that the presence of this
|
||||
* annotation implies nothing about the quality or performance of the API in question, only the fact
|
||||
* that it is not "API-frozen."
|
||||
*
|
||||
* <p>It is generally safe for <i>applications</i> to depend on beta APIs, at the cost of some extra
|
||||
* work during upgrades. However it is generally inadvisable for <i>libraries</i> (which get
|
||||
* included on users' CLASSPATHs, outside the library developers' control) to do so.
|
||||
*
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
*/
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({
|
||||
ElementType.ANNOTATION_TYPE,
|
||||
ElementType.CONSTRUCTOR,
|
||||
ElementType.FIELD,
|
||||
ElementType.METHOD,
|
||||
ElementType.TYPE
|
||||
})
|
||||
@Documented
|
||||
@GwtCompatible
|
||||
public @interface Beta {}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (C) 2009 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* The presence of this annotation on a type indicates that the type may be used with the <a
|
||||
* href="http://code.google.com/webtoolkit/">Google Web Toolkit</a> (GWT). When applied to a method,
|
||||
* the return type of the method is GWT compatible. It's useful to indicate that an instance created
|
||||
* by factory methods has a GWT serializable type. In the following example,
|
||||
*
|
||||
* <pre>
|
||||
* {@literal @}GwtCompatible
|
||||
* class Lists {
|
||||
* ...
|
||||
* {@literal @}GwtCompatible(serializable = true)
|
||||
* {@literal static <E> List<E>} newArrayList(E... elements) {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>The return value of {@code Lists.newArrayList(E[])} has GWT serializable type. It is also
|
||||
* useful in specifying contracts of interface methods. In the following example,
|
||||
*
|
||||
* <pre>
|
||||
* {@literal @}GwtCompatible
|
||||
* interface ListFactory {
|
||||
* ...
|
||||
* {@literal @}GwtCompatible(serializable = true)
|
||||
* {@literal <E> List<E>} newArrayList(E... elements);
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>The {@code newArrayList(E[])} method of all implementations of {@code ListFactory} is expected
|
||||
* to return a value with a GWT serializable type.
|
||||
*
|
||||
* <p>Note that a {@code GwtCompatible} type may have some {@link GwtIncompatible} methods.
|
||||
*
|
||||
*
|
||||
* @author Charles Fry
|
||||
* @author Hayward Chan
|
||||
*/
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Documented
|
||||
@GwtCompatible
|
||||
public @interface GwtCompatible {
|
||||
|
||||
/**
|
||||
* When {@code true}, the annotated type or the type of the method return value is GWT
|
||||
* serializable.
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://code.google.com/webtoolkit/doc/latest/DevGuideServerCommunication.html#DevGuideSerializableTypes">
|
||||
* Documentation about GWT serialization</a>
|
||||
*/
|
||||
boolean serializable() default false;
|
||||
|
||||
/**
|
||||
* When {@code true}, the annotated type is emulated in GWT. The emulated source (also known as
|
||||
* super-source) is different from the implementation used by the JVM.
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModules">
|
||||
* Documentation about GWT emulated source</a>
|
||||
*/
|
||||
boolean emulated() default false;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2009 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* The presence of this annotation on an API indicates that the method may <em>not</em> be used with
|
||||
* the <a href="http://www.gwtproject.org/">Google Web Toolkit</a> (GWT).
|
||||
*
|
||||
* <p>This annotation behaves identically to <a href=
|
||||
* "http://www.gwtproject.org/javadoc/latest/com/google/gwt/core/shared/GwtIncompatible.html">the
|
||||
* {@code @GwtIncompatible} annotation in GWT itself</a>.
|
||||
*
|
||||
* @author Charles Fry
|
||||
*/
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
|
||||
@Documented
|
||||
@GwtCompatible
|
||||
public @interface GwtIncompatible {
|
||||
/**
|
||||
* Describes why the annotated element is incompatible with GWT. Since this is generally due to a
|
||||
* dependence on a type/method which GWT doesn't support, it is sufficient to simply reference the
|
||||
* unsupported type/method. E.g. "Class.isInstance".
|
||||
*
|
||||
* <p>As of Guava 20.0, this value is optional. We encourage authors who wish to describe why an
|
||||
* API is {@code @GwtIncompatible} to instead leave an implementation comment.
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.annotations;
|
||||
|
||||
/**
|
||||
* Annotates a program element that exists, or is more widely visible than otherwise necessary, only
|
||||
* for use in test code.
|
||||
*
|
||||
* @author Johannes Henkel
|
||||
*/
|
||||
@GwtCompatible
|
||||
public @interface VisibleForTesting {
|
||||
}
|
98
src/main/java/com/google/common/base/Absent.java
Normal file
98
src/main/java/com/google/common/base/Absent.java
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/** Implementation of an {@link Optional} not containing a reference. */
|
||||
@GwtCompatible
|
||||
final class Absent<T> extends Optional<T> {
|
||||
static final Absent<Object> INSTANCE = new Absent<>();
|
||||
|
||||
@SuppressWarnings("unchecked") // implementation is "fully variant"
|
||||
static <T> Optional<T> withType() {
|
||||
return (Optional<T>) INSTANCE;
|
||||
}
|
||||
|
||||
private Absent() {}
|
||||
|
||||
@Override
|
||||
public boolean isPresent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
throw new IllegalStateException("Optional.get() cannot be called on an absent value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public T or(T defaultValue) {
|
||||
return checkNotNull(defaultValue, "use Optional.orNull() instead of Optional.or(null)");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // safe covariant cast
|
||||
@Override
|
||||
public Optional<T> or(Optional<? extends T> secondChoice) {
|
||||
return (Optional<T>) checkNotNull(secondChoice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T or(Supplier<? extends T> supplier) {
|
||||
return checkNotNull(
|
||||
supplier.get(), "use Optional.orNull() instead of a Supplier that returns null");
|
||||
}
|
||||
|
||||
@Override
|
||||
public T orNull() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<T> asSet() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Optional<V> transform(Function<? super T, V> function) {
|
||||
checkNotNull(function);
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return object == this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 0x79a31aac;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Optional.absent()";
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
87
src/main/java/com/google/common/base/AbstractIterator.java
Normal file
87
src/main/java/com/google/common/base/AbstractIterator.java
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Note this class is a copy of {@link com.google.common.collect.AbstractIterator} (for dependency
|
||||
* reasons).
|
||||
*/
|
||||
@GwtCompatible
|
||||
abstract class AbstractIterator<T> implements Iterator<T> {
|
||||
private State state = State.NOT_READY;
|
||||
|
||||
protected AbstractIterator() {}
|
||||
|
||||
private enum State {
|
||||
READY,
|
||||
NOT_READY,
|
||||
DONE,
|
||||
FAILED,
|
||||
}
|
||||
|
||||
private T next;
|
||||
|
||||
protected abstract T computeNext();
|
||||
|
||||
protected final T endOfData() {
|
||||
state = State.DONE;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean hasNext() {
|
||||
checkState(state != State.FAILED);
|
||||
switch (state) {
|
||||
case DONE:
|
||||
return false;
|
||||
case READY:
|
||||
return true;
|
||||
default:
|
||||
}
|
||||
return tryToComputeNext();
|
||||
}
|
||||
|
||||
private boolean tryToComputeNext() {
|
||||
state = State.FAILED; // temporary pessimism
|
||||
next = computeNext();
|
||||
if (state != State.DONE) {
|
||||
state = State.READY;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final T next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
state = State.NOT_READY;
|
||||
T result = next;
|
||||
next = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
635
src/main/java/com/google/common/base/Ascii.java
Normal file
635
src/main/java/com/google/common/base/Ascii.java
Normal file
|
@ -0,0 +1,635 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* Static methods pertaining to ASCII characters (those in the range of values {@code 0x00} through
|
||||
* {@code 0x7F}), and to strings containing such characters.
|
||||
*
|
||||
* <p>ASCII utilities also exist in other classes of this package:
|
||||
*
|
||||
* <ul>
|
||||
* <!-- TODO(kevinb): how can we make this not produce a warning when building gwt javadoc? -->
|
||||
* <li>{@link Charsets#US_ASCII} specifies the {@code Charset} of ASCII characters.
|
||||
* <li>{@link CharMatcher#ascii} matches ASCII characters and provides text processing methods
|
||||
* which operate only on the ASCII characters of a string.
|
||||
* </ul>
|
||||
*
|
||||
* @author Catherine Berry
|
||||
* @author Gregory Kick
|
||||
* @since 7.0
|
||||
*/
|
||||
@GwtCompatible
|
||||
public final class Ascii {
|
||||
|
||||
private Ascii() {}
|
||||
|
||||
/* The ASCII control characters, per RFC 20. */
|
||||
/**
|
||||
* Null ('\0'): The all-zeros character which may serve to accomplish time fill and media fill.
|
||||
* Normally used as a C string terminator.
|
||||
*
|
||||
* <p>Although RFC 20 names this as "Null", note that it is distinct from the C/C++ "NULL"
|
||||
* pointer.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte NUL = 0;
|
||||
|
||||
/**
|
||||
* Start of Heading: A communication control character used at the beginning of a sequence of
|
||||
* characters which constitute a machine-sensible address or routing information. Such a sequence
|
||||
* is referred to as the "heading." An STX character has the effect of terminating a heading.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte SOH = 1;
|
||||
|
||||
/**
|
||||
* Start of Text: A communication control character which precedes a sequence of characters that
|
||||
* is to be treated as an entity and entirely transmitted through to the ultimate destination.
|
||||
* Such a sequence is referred to as "text." STX may be used to terminate a sequence of characters
|
||||
* started by SOH.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte STX = 2;
|
||||
|
||||
/**
|
||||
* End of Text: A communication control character used to terminate a sequence of characters
|
||||
* started with STX and transmitted as an entity.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte ETX = 3;
|
||||
|
||||
/**
|
||||
* End of Transmission: A communication control character used to indicate the conclusion of a
|
||||
* transmission, which may have contained one or more texts and any associated headings.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte EOT = 4;
|
||||
|
||||
/**
|
||||
* Enquiry: A communication control character used in data communication systems as a request for
|
||||
* a response from a remote station. It may be used as a "Who Are You" (WRU) to obtain
|
||||
* identification, or may be used to obtain station status, or both.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte ENQ = 5;
|
||||
|
||||
/**
|
||||
* Acknowledge: A communication control character transmitted by a receiver as an affirmative
|
||||
* response to a sender.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte ACK = 6;
|
||||
|
||||
/**
|
||||
* Bell ('\a'): A character for use when there is a need to call for human attention. It may
|
||||
* control alarm or attention devices.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte BEL = 7;
|
||||
|
||||
/**
|
||||
* Backspace ('\b'): A format effector which controls the movement of the printing position one
|
||||
* printing space backward on the same printing line. (Applicable also to display devices.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte BS = 8;
|
||||
|
||||
/**
|
||||
* Horizontal Tabulation ('\t'): A format effector which controls the movement of the printing
|
||||
* position to the next in a series of predetermined positions along the printing line.
|
||||
* (Applicable also to display devices and the skip function on punched cards.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte HT = 9;
|
||||
|
||||
/**
|
||||
* Line Feed ('\n'): A format effector which controls the movement of the printing position to the
|
||||
* next printing line. (Applicable also to display devices.) Where appropriate, this character may
|
||||
* have the meaning "New Line" (NL), a format effector which controls the movement of the printing
|
||||
* point to the first printing position on the next printing line. Use of this convention requires
|
||||
* agreement between sender and recipient of data.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte LF = 10;
|
||||
|
||||
/**
|
||||
* Alternate name for {@link #LF}. ({@code LF} is preferred.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte NL = 10;
|
||||
|
||||
/**
|
||||
* Vertical Tabulation ('\v'): A format effector which controls the movement of the printing
|
||||
* position to the next in a series of predetermined printing lines. (Applicable also to display
|
||||
* devices.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte VT = 11;
|
||||
|
||||
/**
|
||||
* Form Feed ('\f'): A format effector which controls the movement of the printing position to the
|
||||
* first pre-determined printing line on the next form or page. (Applicable also to display
|
||||
* devices.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte FF = 12;
|
||||
|
||||
/**
|
||||
* Carriage Return ('\r'): A format effector which controls the movement of the printing position
|
||||
* to the first printing position on the same printing line. (Applicable also to display devices.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte CR = 13;
|
||||
|
||||
/**
|
||||
* Shift Out: A control character indicating that the code combinations which follow shall be
|
||||
* interpreted as outside of the character set of the standard code table until a Shift In
|
||||
* character is reached.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte SO = 14;
|
||||
|
||||
/**
|
||||
* Shift In: A control character indicating that the code combinations which follow shall be
|
||||
* interpreted according to the standard code table.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte SI = 15;
|
||||
|
||||
/**
|
||||
* Data Link Escape: A communication control character which will change the meaning of a limited
|
||||
* number of contiguously following characters. It is used exclusively to provide supplementary
|
||||
* controls in data communication networks.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte DLE = 16;
|
||||
|
||||
/**
|
||||
* Device Control 1. Characters for the control of ancillary devices associated with data
|
||||
* processing or telecommunication systems, more especially switching devices "on" or "off." (If a
|
||||
* single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the
|
||||
* preferred assignment.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte DC1 = 17; // aka XON
|
||||
|
||||
/**
|
||||
* Transmission On: Although originally defined as DC1, this ASCII control character is now better
|
||||
* known as the XON code used for software flow control in serial communications. The main use is
|
||||
* restarting the transmission after the communication has been stopped by the XOFF control code.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte XON = 17; // aka DC1
|
||||
|
||||
/**
|
||||
* Device Control 2. Characters for the control of ancillary devices associated with data
|
||||
* processing or telecommunication systems, more especially switching devices "on" or "off." (If a
|
||||
* single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the
|
||||
* preferred assignment.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte DC2 = 18;
|
||||
|
||||
/**
|
||||
* Device Control 3. Characters for the control of ancillary devices associated with data
|
||||
* processing or telecommunication systems, more especially switching devices "on" or "off." (If a
|
||||
* single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the
|
||||
* preferred assignment.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte DC3 = 19; // aka XOFF
|
||||
|
||||
/**
|
||||
* Transmission off. See {@link #XON} for explanation.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte XOFF = 19; // aka DC3
|
||||
|
||||
/**
|
||||
* Device Control 4. Characters for the control of ancillary devices associated with data
|
||||
* processing or telecommunication systems, more especially switching devices "on" or "off." (If a
|
||||
* single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the
|
||||
* preferred assignment.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte DC4 = 20;
|
||||
|
||||
/**
|
||||
* Negative Acknowledge: A communication control character transmitted by a receiver as a negative
|
||||
* response to the sender.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte NAK = 21;
|
||||
|
||||
/**
|
||||
* Synchronous Idle: A communication control character used by a synchronous transmission system
|
||||
* in the absence of any other character to provide a signal from which synchronism may be
|
||||
* achieved or retained.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte SYN = 22;
|
||||
|
||||
/**
|
||||
* End of Transmission Block: A communication control character used to indicate the end of a
|
||||
* block of data for communication purposes. ETB is used for blocking data where the block
|
||||
* structure is not necessarily related to the processing format.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte ETB = 23;
|
||||
|
||||
/**
|
||||
* Cancel: A control character used to indicate that the data with which it is sent is in error or
|
||||
* is to be disregarded.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte CAN = 24;
|
||||
|
||||
/**
|
||||
* End of Medium: A control character associated with the sent data which may be used to identify
|
||||
* the physical end of the medium, or the end of the used, or wanted, portion of information
|
||||
* recorded on a medium. (The position of this character does not necessarily correspond to the
|
||||
* physical end of the medium.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte EM = 25;
|
||||
|
||||
/**
|
||||
* Substitute: A character that may be substituted for a character which is determined to be
|
||||
* invalid or in error.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte SUB = 26;
|
||||
|
||||
/**
|
||||
* Escape: A control character intended to provide code extension (supplementary characters) in
|
||||
* general information interchange. The Escape character itself is a prefix affecting the
|
||||
* interpretation of a limited number of contiguously following characters.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte ESC = 27;
|
||||
|
||||
/**
|
||||
* File Separator: These four information separators may be used within data in optional fashion,
|
||||
* except that their hierarchical relationship shall be: FS is the most inclusive, then GS, then
|
||||
* RS, and US is least inclusive. (The content and length of a File, Group, Record, or Unit are
|
||||
* not specified.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte FS = 28;
|
||||
|
||||
/**
|
||||
* Group Separator: These four information separators may be used within data in optional fashion,
|
||||
* except that their hierarchical relationship shall be: FS is the most inclusive, then GS, then
|
||||
* RS, and US is least inclusive. (The content and length of a File, Group, Record, or Unit are
|
||||
* not specified.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte GS = 29;
|
||||
|
||||
/**
|
||||
* Record Separator: These four information separators may be used within data in optional
|
||||
* fashion, except that their hierarchical relationship shall be: FS is the most inclusive, then
|
||||
* GS, then RS, and US is least inclusive. (The content and length of a File, Group, Record, or
|
||||
* Unit are not specified.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte RS = 30;
|
||||
|
||||
/**
|
||||
* Unit Separator: These four information separators may be used within data in optional fashion,
|
||||
* except that their hierarchical relationship shall be: FS is the most inclusive, then GS, then
|
||||
* RS, and US is least inclusive. (The content and length of a File, Group, Record, or Unit are
|
||||
* not specified.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte US = 31;
|
||||
|
||||
/**
|
||||
* Space: A normally non-printing graphic character used to separate words. It is also a format
|
||||
* effector which controls the movement of the printing position, one printing position forward.
|
||||
* (Applicable also to display devices.)
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte SP = 32;
|
||||
|
||||
/**
|
||||
* Alternate name for {@link #SP}.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte SPACE = 32;
|
||||
|
||||
/**
|
||||
* Delete: This character is used primarily to "erase" or "obliterate" erroneous or unwanted
|
||||
* characters in perforated tape.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public static final byte DEL = 127;
|
||||
|
||||
/**
|
||||
* The minimum value of an ASCII character.
|
||||
*
|
||||
* @since 9.0 (was type {@code int} before 12.0)
|
||||
*/
|
||||
public static final char MIN = 0;
|
||||
|
||||
/**
|
||||
* The maximum value of an ASCII character.
|
||||
*
|
||||
* @since 9.0 (was type {@code int} before 12.0)
|
||||
*/
|
||||
public static final char MAX = 127;
|
||||
|
||||
/** A bit mask which selects the bit encoding ASCII character case. */
|
||||
private static final char CASE_MASK = 0x20;
|
||||
|
||||
/**
|
||||
* Returns a copy of the input string in which all {@linkplain #isUpperCase(char) uppercase ASCII
|
||||
* characters} have been converted to lowercase. All other characters are copied without
|
||||
* modification.
|
||||
*/
|
||||
public static String toLowerCase(String string) {
|
||||
int length = string.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (isUpperCase(string.charAt(i))) {
|
||||
char[] chars = string.toCharArray();
|
||||
for (; i < length; i++) {
|
||||
char c = chars[i];
|
||||
if (isUpperCase(c)) {
|
||||
chars[i] = (char) (c ^ CASE_MASK);
|
||||
}
|
||||
}
|
||||
return String.valueOf(chars);
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the input character sequence in which all {@linkplain #isUpperCase(char)
|
||||
* uppercase ASCII characters} have been converted to lowercase. All other characters are copied
|
||||
* without modification.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
public static String toLowerCase(CharSequence chars) {
|
||||
if (chars instanceof String) {
|
||||
return toLowerCase((String) chars);
|
||||
}
|
||||
char[] newChars = new char[chars.length()];
|
||||
for (int i = 0; i < newChars.length; i++) {
|
||||
newChars[i] = toLowerCase(chars.charAt(i));
|
||||
}
|
||||
return String.valueOf(newChars);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the argument is an {@linkplain #isUpperCase(char) uppercase ASCII character} returns the
|
||||
* lowercase equivalent. Otherwise returns the argument.
|
||||
*/
|
||||
public static char toLowerCase(char c) {
|
||||
return isUpperCase(c) ? (char) (c ^ CASE_MASK) : c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the input string in which all {@linkplain #isLowerCase(char) lowercase ASCII
|
||||
* characters} have been converted to uppercase. All other characters are copied without
|
||||
* modification.
|
||||
*/
|
||||
public static String toUpperCase(String string) {
|
||||
int length = string.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (isLowerCase(string.charAt(i))) {
|
||||
char[] chars = string.toCharArray();
|
||||
for (; i < length; i++) {
|
||||
char c = chars[i];
|
||||
if (isLowerCase(c)) {
|
||||
chars[i] = (char) (c ^ CASE_MASK);
|
||||
}
|
||||
}
|
||||
return String.valueOf(chars);
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the input character sequence in which all {@linkplain #isLowerCase(char)
|
||||
* lowercase ASCII characters} have been converted to uppercase. All other characters are copied
|
||||
* without modification.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
public static String toUpperCase(CharSequence chars) {
|
||||
if (chars instanceof String) {
|
||||
return toUpperCase((String) chars);
|
||||
}
|
||||
char[] newChars = new char[chars.length()];
|
||||
for (int i = 0; i < newChars.length; i++) {
|
||||
newChars[i] = toUpperCase(chars.charAt(i));
|
||||
}
|
||||
return String.valueOf(newChars);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the argument is a {@linkplain #isLowerCase(char) lowercase ASCII character} returns the
|
||||
* uppercase equivalent. Otherwise returns the argument.
|
||||
*/
|
||||
public static char toUpperCase(char c) {
|
||||
return isLowerCase(c) ? (char) (c ^ CASE_MASK) : c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether {@code c} is one of the twenty-six lowercase ASCII alphabetic characters
|
||||
* between {@code 'a'} and {@code 'z'} inclusive. All others (including non-ASCII characters)
|
||||
* return {@code false}.
|
||||
*/
|
||||
public static boolean isLowerCase(char c) {
|
||||
// Note: This was benchmarked against the alternate expression "(char)(c - 'a') < 26" (Nov '13)
|
||||
// and found to perform at least as well, or better.
|
||||
return (c >= 'a') && (c <= 'z');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether {@code c} is one of the twenty-six uppercase ASCII alphabetic characters
|
||||
* between {@code 'A'} and {@code 'Z'} inclusive. All others (including non-ASCII characters)
|
||||
* return {@code false}.
|
||||
*/
|
||||
public static boolean isUpperCase(char c) {
|
||||
return (c >= 'A') && (c <= 'Z');
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the given character sequence to the given maximum length. If the length of the
|
||||
* sequence is greater than {@code maxLength}, the returned string will be exactly {@code
|
||||
* maxLength} chars in length and will end with the given {@code truncationIndicator}. Otherwise,
|
||||
* the sequence will be returned as a string with no changes to the content.
|
||||
*
|
||||
* <p>Examples:
|
||||
*
|
||||
* <pre>{@code
|
||||
* Ascii.truncate("foobar", 7, "..."); // returns "foobar"
|
||||
* Ascii.truncate("foobar", 5, "..."); // returns "fo..."
|
||||
* }</pre>
|
||||
*
|
||||
* <p><b>Note:</b> This method <i>may</i> work with certain non-ASCII text but is not safe for use
|
||||
* with arbitrary Unicode text. It is mostly intended for use with text that is known to be safe
|
||||
* for use with it (such as all-ASCII text) and for simple debugging text. When using this method,
|
||||
* consider the following:
|
||||
*
|
||||
* <ul>
|
||||
* <li>it may split surrogate pairs
|
||||
* <li>it may split characters and combining characters
|
||||
* <li>it does not consider word boundaries
|
||||
* <li>if truncating for display to users, there are other considerations that must be taken
|
||||
* into account
|
||||
* <li>the appropriate truncation indicator may be locale-dependent
|
||||
* <li>it is safe to use non-ASCII characters in the truncation indicator
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code maxLength} is less than the length of {@code
|
||||
* truncationIndicator}
|
||||
* @since 16.0
|
||||
*/
|
||||
public static String truncate(CharSequence seq, int maxLength, String truncationIndicator) {
|
||||
checkNotNull(seq);
|
||||
|
||||
// length to truncate the sequence to, not including the truncation indicator
|
||||
int truncationLength = maxLength - truncationIndicator.length();
|
||||
|
||||
// in this worst case, this allows a maxLength equal to the length of the truncationIndicator,
|
||||
// meaning that a string will be truncated to just the truncation indicator itself
|
||||
checkArgument(
|
||||
truncationLength >= 0,
|
||||
"maxLength (%s) must be >= length of the truncation indicator (%s)",
|
||||
maxLength,
|
||||
truncationIndicator.length());
|
||||
|
||||
if (seq.length() <= maxLength) {
|
||||
String string = seq.toString();
|
||||
if (string.length() <= maxLength) {
|
||||
return string;
|
||||
}
|
||||
// if the length of the toString() result was > maxLength for some reason, truncate that
|
||||
seq = string;
|
||||
}
|
||||
|
||||
return new StringBuilder(maxLength)
|
||||
.append(seq, 0, truncationLength)
|
||||
.append(truncationIndicator)
|
||||
.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the contents of the given character sequences {@code s1} and {@code s2} are
|
||||
* equal, ignoring the case of any ASCII alphabetic characters between {@code 'a'} and {@code 'z'}
|
||||
* or {@code 'A'} and {@code 'Z'} inclusive.
|
||||
*
|
||||
* <p>This method is significantly faster than {@link String#equalsIgnoreCase} and should be used
|
||||
* in preference if at least one of the parameters is known to contain only ASCII characters.
|
||||
*
|
||||
* <p>Note however that this method does not always behave identically to expressions such as:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@code string.toUpperCase().equals("UPPER CASE ASCII")}
|
||||
* <li>{@code string.toLowerCase().equals("lower case ascii")}
|
||||
* </ul>
|
||||
*
|
||||
* <p>due to case-folding of some non-ASCII characters (which does not occur in {@link
|
||||
* String#equalsIgnoreCase}). However in almost all cases that ASCII strings are used, the author
|
||||
* probably wanted the behavior provided by this method rather than the subtle and sometimes
|
||||
* surprising behavior of {@code toUpperCase()} and {@code toLowerCase()}.
|
||||
*
|
||||
* @since 16.0
|
||||
*/
|
||||
public static boolean equalsIgnoreCase(CharSequence s1, CharSequence s2) {
|
||||
// Calling length() is the null pointer check (so do it before we can exit early).
|
||||
int length = s1.length();
|
||||
if (s1 == s2) {
|
||||
return true;
|
||||
}
|
||||
if (length != s2.length()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
char c1 = s1.charAt(i);
|
||||
char c2 = s2.charAt(i);
|
||||
if (c1 == c2) {
|
||||
continue;
|
||||
}
|
||||
int alphaIndex = getAlphaIndex(c1);
|
||||
// This was also benchmarked using '&' to avoid branching (but always evaluate the rhs),
|
||||
// however this showed no obvious improvement.
|
||||
if (alphaIndex < 26 && alphaIndex == getAlphaIndex(c2)) {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the non-negative index value of the alpha character {@code c}, regardless of case. Ie,
|
||||
* 'a'/'A' returns 0 and 'z'/'Z' returns 25. Non-alpha characters return a value of 26 or greater.
|
||||
*/
|
||||
private static int getAlphaIndex(char c) {
|
||||
// Fold upper-case ASCII to lower-case and make zero-indexed and unsigned (by casting to char).
|
||||
return (char) ((c | CASE_MASK) - 'a');
|
||||
}
|
||||
}
|
213
src/main/java/com/google/common/base/CaseFormat.java
Normal file
213
src/main/java/com/google/common/base/CaseFormat.java
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Utility class for converting between various ASCII case formats. Behavior is undefined for
|
||||
* non-ASCII input.
|
||||
*
|
||||
* @author Mike Bostock
|
||||
* @since 1.0
|
||||
*/
|
||||
@GwtCompatible
|
||||
public enum CaseFormat {
|
||||
/** Hyphenated variable naming convention, e.g., "lower-hyphen". */
|
||||
LOWER_HYPHEN(CharMatcher.is('-'), "-") {
|
||||
@Override
|
||||
String normalizeWord(String word) {
|
||||
return Ascii.toLowerCase(word);
|
||||
}
|
||||
|
||||
@Override
|
||||
String convert(CaseFormat format, String s) {
|
||||
if (format == LOWER_UNDERSCORE) {
|
||||
return s.replace('-', '_');
|
||||
}
|
||||
if (format == UPPER_UNDERSCORE) {
|
||||
return Ascii.toUpperCase(s.replace('-', '_'));
|
||||
}
|
||||
return super.convert(format, s);
|
||||
}
|
||||
},
|
||||
|
||||
/** C++ variable naming convention, e.g., "lower_underscore". */
|
||||
LOWER_UNDERSCORE(CharMatcher.is('_'), "_") {
|
||||
@Override
|
||||
String normalizeWord(String word) {
|
||||
return Ascii.toLowerCase(word);
|
||||
}
|
||||
|
||||
@Override
|
||||
String convert(CaseFormat format, String s) {
|
||||
if (format == LOWER_HYPHEN) {
|
||||
return s.replace('_', '-');
|
||||
}
|
||||
if (format == UPPER_UNDERSCORE) {
|
||||
return Ascii.toUpperCase(s);
|
||||
}
|
||||
return super.convert(format, s);
|
||||
}
|
||||
},
|
||||
|
||||
/** Java variable naming convention, e.g., "lowerCamel". */
|
||||
LOWER_CAMEL(CharMatcher.inRange('A', 'Z'), "") {
|
||||
@Override
|
||||
String normalizeWord(String word) {
|
||||
return firstCharOnlyToUpper(word);
|
||||
}
|
||||
|
||||
@Override
|
||||
String normalizeFirstWord(String word) {
|
||||
return Ascii.toLowerCase(word);
|
||||
}
|
||||
},
|
||||
|
||||
/** Java and C++ class naming convention, e.g., "UpperCamel". */
|
||||
UPPER_CAMEL(CharMatcher.inRange('A', 'Z'), "") {
|
||||
@Override
|
||||
String normalizeWord(String word) {
|
||||
return firstCharOnlyToUpper(word);
|
||||
}
|
||||
},
|
||||
|
||||
/** Java and C++ constant naming convention, e.g., "UPPER_UNDERSCORE". */
|
||||
UPPER_UNDERSCORE(CharMatcher.is('_'), "_") {
|
||||
@Override
|
||||
String normalizeWord(String word) {
|
||||
return Ascii.toUpperCase(word);
|
||||
}
|
||||
|
||||
@Override
|
||||
String convert(CaseFormat format, String s) {
|
||||
if (format == LOWER_HYPHEN) {
|
||||
return Ascii.toLowerCase(s.replace('_', '-'));
|
||||
}
|
||||
if (format == LOWER_UNDERSCORE) {
|
||||
return Ascii.toLowerCase(s);
|
||||
}
|
||||
return super.convert(format, s);
|
||||
}
|
||||
};
|
||||
|
||||
private final CharMatcher wordBoundary;
|
||||
private final String wordSeparator;
|
||||
|
||||
CaseFormat(CharMatcher wordBoundary, String wordSeparator) {
|
||||
this.wordBoundary = wordBoundary;
|
||||
this.wordSeparator = wordSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified {@code String str} from this format to the specified {@code format}. A
|
||||
* "best effort" approach is taken; if {@code str} does not conform to the assumed format, then
|
||||
* the behavior of this method is undefined but we make a reasonable effort at converting anyway.
|
||||
*/
|
||||
public final String to(CaseFormat format, String str) {
|
||||
checkNotNull(format);
|
||||
checkNotNull(str);
|
||||
return (format == this) ? str : convert(format, str);
|
||||
}
|
||||
|
||||
/** Enum values can override for performance reasons. */
|
||||
String convert(CaseFormat format, String s) {
|
||||
// deal with camel conversion
|
||||
StringBuilder out = null;
|
||||
int i = 0;
|
||||
int j = -1;
|
||||
while ((j = wordBoundary.indexIn(s, ++j)) != -1) {
|
||||
if (i == 0) {
|
||||
// include some extra space for separators
|
||||
out = new StringBuilder(s.length() + 4 * wordSeparator.length());
|
||||
out.append(format.normalizeFirstWord(s.substring(i, j)));
|
||||
} else {
|
||||
out.append(format.normalizeWord(s.substring(i, j)));
|
||||
}
|
||||
out.append(format.wordSeparator);
|
||||
i = j + wordSeparator.length();
|
||||
}
|
||||
return (i == 0)
|
||||
? format.normalizeFirstWord(s)
|
||||
: out.append(format.normalizeWord(s.substring(i))).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Converter} that converts strings from this format to {@code targetFormat}.
|
||||
*
|
||||
* @since 16.0
|
||||
*/
|
||||
public Converter<String, String> converterTo(CaseFormat targetFormat) {
|
||||
return new StringConverter(this, targetFormat);
|
||||
}
|
||||
|
||||
private static final class StringConverter extends Converter<String, String>
|
||||
implements Serializable {
|
||||
|
||||
private final CaseFormat sourceFormat;
|
||||
private final CaseFormat targetFormat;
|
||||
|
||||
StringConverter(CaseFormat sourceFormat, CaseFormat targetFormat) {
|
||||
this.sourceFormat = checkNotNull(sourceFormat);
|
||||
this.targetFormat = checkNotNull(targetFormat);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doForward(String s) {
|
||||
return sourceFormat.to(targetFormat, s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doBackward(String s) {
|
||||
return targetFormat.to(sourceFormat, s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof StringConverter) {
|
||||
StringConverter that = (StringConverter) object;
|
||||
return sourceFormat.equals(that.sourceFormat) && targetFormat.equals(that.targetFormat);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return sourceFormat.hashCode() ^ targetFormat.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return sourceFormat + ".converterTo(" + targetFormat + ")";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
}
|
||||
|
||||
abstract String normalizeWord(String word);
|
||||
|
||||
String normalizeFirstWord(String word) {
|
||||
return normalizeWord(word);
|
||||
}
|
||||
|
||||
private static String firstCharOnlyToUpper(String word) {
|
||||
return word.isEmpty()
|
||||
? word
|
||||
: Ascii.toUpperCase(word.charAt(0)) + Ascii.toLowerCase(word.substring(1));
|
||||
}
|
||||
}
|
1818
src/main/java/com/google/common/base/CharMatcher.java
Normal file
1818
src/main/java/com/google/common/base/CharMatcher.java
Normal file
File diff suppressed because it is too large
Load diff
102
src/main/java/com/google/common/base/Charsets.java
Normal file
102
src/main/java/com/google/common/base/Charsets.java
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* Contains constant definitions for the six standard {@link Charset} instances, which are
|
||||
* guaranteed to be supported by all Java platform implementations.
|
||||
*
|
||||
* <p>Assuming you're free to choose, note that <b>{@link #UTF_8} is widely preferred</b>.
|
||||
*
|
||||
* <p>See the Guava User Guide article on <a
|
||||
* href="https://github.com/google/guava/wiki/StringsExplained#charsets">{@code Charsets}</a>.
|
||||
*
|
||||
* @author Mike Bostock
|
||||
* @since 1.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class Charsets {
|
||||
private Charsets() {}
|
||||
|
||||
/**
|
||||
* US-ASCII: seven-bit ASCII, the Basic Latin block of the Unicode character set (ISO646-US).
|
||||
*
|
||||
* <p><b>Note for Java 7 and later:</b> this constant should be treated as deprecated; use {@link
|
||||
* java.nio.charset.StandardCharsets#US_ASCII} instead.
|
||||
*
|
||||
*/
|
||||
@GwtIncompatible // Charset not supported by GWT
|
||||
public static final Charset US_ASCII = Charset.forName("US-ASCII");
|
||||
|
||||
/**
|
||||
* ISO-8859-1: ISO Latin Alphabet Number 1 (ISO-LATIN-1).
|
||||
*
|
||||
* <p><b>Note for Java 7 and later:</b> this constant should be treated as deprecated; use {@link
|
||||
* java.nio.charset.StandardCharsets#ISO_8859_1} instead.
|
||||
*
|
||||
*/
|
||||
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||
|
||||
/**
|
||||
* UTF-8: eight-bit UCS Transformation Format.
|
||||
*
|
||||
* <p><b>Note for Java 7 and later:</b> this constant should be treated as deprecated; use {@link
|
||||
* java.nio.charset.StandardCharsets#UTF_8} instead.
|
||||
*
|
||||
*/
|
||||
public static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
|
||||
/**
|
||||
* UTF-16BE: sixteen-bit UCS Transformation Format, big-endian byte order.
|
||||
*
|
||||
* <p><b>Note for Java 7 and later:</b> this constant should be treated as deprecated; use {@link
|
||||
* java.nio.charset.StandardCharsets#UTF_16BE} instead.
|
||||
*
|
||||
*/
|
||||
@GwtIncompatible // Charset not supported by GWT
|
||||
public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
|
||||
|
||||
/**
|
||||
* UTF-16LE: sixteen-bit UCS Transformation Format, little-endian byte order.
|
||||
*
|
||||
* <p><b>Note for Java 7 and later:</b> this constant should be treated as deprecated; use {@link
|
||||
* java.nio.charset.StandardCharsets#UTF_16LE} instead.
|
||||
*
|
||||
*/
|
||||
@GwtIncompatible // Charset not supported by GWT
|
||||
public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
|
||||
|
||||
/**
|
||||
* UTF-16: sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order
|
||||
* mark.
|
||||
*
|
||||
* <p><b>Note for Java 7 and later:</b> this constant should be treated as deprecated; use {@link
|
||||
* java.nio.charset.StandardCharsets#UTF_16} instead.
|
||||
*
|
||||
*/
|
||||
@GwtIncompatible // Charset not supported by GWT
|
||||
public static final Charset UTF_16 = Charset.forName("UTF-16");
|
||||
|
||||
/*
|
||||
* Please do not add new Charset references to this class, unless those character encodings are
|
||||
* part of the set required to be supported by all Java platform implementations! Any Charsets
|
||||
* initialized here may cause unexpected delays when this class is loaded. See the Charset
|
||||
* Javadocs for the list of built-in character encodings.
|
||||
*/
|
||||
}
|
37
src/main/java/com/google/common/base/CommonMatcher.java
Normal file
37
src/main/java/com/google/common/base/CommonMatcher.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* The subset of the {@link java.util.regex.Matcher} API which is used by this package, and also
|
||||
* shared with the {@code re2j} library. For internal use only. Please refer to the {@code Matcher}
|
||||
* javadoc for details.
|
||||
*/
|
||||
@GwtCompatible
|
||||
abstract class CommonMatcher {
|
||||
public abstract boolean matches();
|
||||
|
||||
public abstract boolean find();
|
||||
|
||||
public abstract boolean find(int index);
|
||||
|
||||
public abstract String replaceAll(String replacement);
|
||||
|
||||
public abstract int end();
|
||||
|
||||
public abstract int start();
|
||||
}
|
43
src/main/java/com/google/common/base/CommonPattern.java
Normal file
43
src/main/java/com/google/common/base/CommonPattern.java
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* The subset of the {@link java.util.regex.Pattern} API which is used by this package, and also
|
||||
* shared with the {@code re2j} library. For internal use only. Please refer to the {@code Pattern}
|
||||
* javadoc for details.
|
||||
*/
|
||||
@GwtCompatible
|
||||
abstract class CommonPattern {
|
||||
public abstract CommonMatcher matcher(CharSequence t);
|
||||
|
||||
public abstract String pattern();
|
||||
|
||||
public abstract int flags();
|
||||
|
||||
// Re-declare this as abstract to force subclasses to override.
|
||||
@Override
|
||||
public abstract String toString();
|
||||
|
||||
public static CommonPattern compile(String pattern) {
|
||||
return Platform.compilePattern(pattern);
|
||||
}
|
||||
|
||||
public static boolean isPcreLike() {
|
||||
return Platform.patternCompilerIsPcreLike();
|
||||
}
|
||||
}
|
506
src/main/java/com/google/common/base/Converter.java
Normal file
506
src/main/java/com/google/common/base/Converter.java
Normal file
|
@ -0,0 +1,506 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* A function from {@code A} to {@code B} with an associated <i>reverse</i> function from {@code B}
|
||||
* to {@code A}; used for converting back and forth between <i>different representations of the same
|
||||
* information</i>.
|
||||
*
|
||||
* <h3>Invertibility</h3>
|
||||
*
|
||||
* <p>The reverse operation <b>may</b> be a strict <i>inverse</i> (meaning that {@code
|
||||
* converter.reverse().convert(converter.convert(a)).equals(a)} is always true). However, it is very
|
||||
* common (perhaps <i>more</i> common) for round-trip conversion to be <i>lossy</i>. Consider an
|
||||
* example round-trip using {@link com.google.common.primitives.Doubles#stringConverter}:
|
||||
*
|
||||
* <ol>
|
||||
* <li>{@code stringConverter().convert("1.00")} returns the {@code Double} value {@code 1.0}
|
||||
* <li>{@code stringConverter().reverse().convert(1.0)} returns the string {@code "1.0"} --
|
||||
* <i>not</i> the same string ({@code "1.00"}) we started with
|
||||
* </ol>
|
||||
*
|
||||
* <p>Note that it should still be the case that the round-tripped and original objects are
|
||||
* <i>similar</i>.
|
||||
*
|
||||
* <h3>Nullability</h3>
|
||||
*
|
||||
* <p>A converter always converts {@code null} to {@code null} and non-null references to non-null
|
||||
* references. It would not make sense to consider {@code null} and a non-null reference to be
|
||||
* "different representations of the same information", since one is distinguishable from
|
||||
* <i>missing</i> information and the other is not. The {@link #convert} method handles this null
|
||||
* behavior for all converters; implementations of {@link #doForward} and {@link #doBackward} are
|
||||
* guaranteed to never be passed {@code null}, and must never return {@code null}.
|
||||
*
|
||||
*
|
||||
* <h3>Common ways to use</h3>
|
||||
*
|
||||
* <p>Getting a converter:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Use a provided converter implementation, such as {@link Enums#stringConverter}, {@link
|
||||
* com.google.common.primitives.Ints#stringConverter Ints.stringConverter} or the {@linkplain
|
||||
* #reverse reverse} views of these.
|
||||
* <li>Convert between specific preset values using {@link
|
||||
* com.google.common.collect.Maps#asConverter Maps.asConverter}. For example, use this to
|
||||
* create a "fake" converter for a unit test. It is unnecessary (and confusing) to <i>mock</i>
|
||||
* the {@code Converter} type using a mocking framework.
|
||||
* <li>Extend this class and implement its {@link #doForward} and {@link #doBackward} methods.
|
||||
* <li><b>Java 8 users:</b> you may prefer to pass two lambda expressions or method references to
|
||||
* the {@link #from from} factory method.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Using a converter:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Convert one instance in the "forward" direction using {@code converter.convert(a)}.
|
||||
* <li>Convert multiple instances "forward" using {@code converter.convertAll(as)}.
|
||||
* <li>Convert in the "backward" direction using {@code converter.reverse().convert(b)} or {@code
|
||||
* converter.reverse().convertAll(bs)}.
|
||||
* <li>Use {@code converter} or {@code converter.reverse()} anywhere a {@link
|
||||
* java.util.function.Function} is accepted (for example {@link java.util.stream.Stream#map
|
||||
* Stream.map}).
|
||||
* <li><b>Do not</b> call {@link #doForward} or {@link #doBackward} directly; these exist only to
|
||||
* be overridden.
|
||||
* </ul>
|
||||
*
|
||||
* <h3>Example</h3>
|
||||
*
|
||||
* <pre>
|
||||
* return new Converter<Integer, String>() {
|
||||
* protected String doForward(Integer i) {
|
||||
* return Integer.toHexString(i);
|
||||
* }
|
||||
*
|
||||
* protected Integer doBackward(String s) {
|
||||
* return parseUnsignedInt(s, 16);
|
||||
* }
|
||||
* };</pre>
|
||||
*
|
||||
* <p>An alternative using Java 8:
|
||||
*
|
||||
* <pre>{@code
|
||||
* return Converter.from(
|
||||
* Integer::toHexString,
|
||||
* s -> parseUnsignedInt(s, 16));
|
||||
* }</pre>
|
||||
*
|
||||
* @author Mike Ward
|
||||
* @author Kurt Alfred Kluever
|
||||
* @author Gregory Kick
|
||||
* @since 16.0
|
||||
*/
|
||||
@GwtCompatible
|
||||
public abstract class Converter<A, B> implements Function<A, B> {
|
||||
private final boolean handleNullAutomatically;
|
||||
|
||||
// We lazily cache the reverse view to avoid allocating on every call to reverse().
|
||||
private transient Converter<B, A> reverse;
|
||||
|
||||
/** Constructor for use by subclasses. */
|
||||
protected Converter() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
/** Constructor used only by {@code LegacyConverter} to suspend automatic null-handling. */
|
||||
Converter(boolean handleNullAutomatically) {
|
||||
this.handleNullAutomatically = handleNullAutomatically;
|
||||
}
|
||||
|
||||
// SPI methods (what subclasses must implement)
|
||||
|
||||
/**
|
||||
* Returns a representation of {@code a} as an instance of type {@code B}. If {@code a} cannot be
|
||||
* converted, an unchecked exception (such as {@link IllegalArgumentException}) should be thrown.
|
||||
*
|
||||
* @param a the instance to convert; will never be null
|
||||
* @return the converted instance; <b>must not</b> be null
|
||||
*/
|
||||
protected abstract B doForward(A a);
|
||||
|
||||
/**
|
||||
* Returns a representation of {@code b} as an instance of type {@code A}. If {@code b} cannot be
|
||||
* converted, an unchecked exception (such as {@link IllegalArgumentException}) should be thrown.
|
||||
*
|
||||
* @param b the instance to convert; will never be null
|
||||
* @return the converted instance; <b>must not</b> be null
|
||||
* @throws UnsupportedOperationException if backward conversion is not implemented; this should be
|
||||
* very rare. Note that if backward conversion is not only unimplemented but
|
||||
* unimplement<i>able</i> (for example, consider a {@code Converter<Chicken, ChickenNugget>}),
|
||||
* then this is not logically a {@code Converter} at all, and should just implement {@link
|
||||
* Function}.
|
||||
*/
|
||||
protected abstract A doBackward(B b);
|
||||
|
||||
// API (consumer-side) methods
|
||||
|
||||
/**
|
||||
* Returns a representation of {@code a} as an instance of type {@code B}.
|
||||
*
|
||||
* @return the converted value; is null <i>if and only if</i> {@code a} is null
|
||||
*/
|
||||
public final B convert(A a) {
|
||||
return correctedDoForward(a);
|
||||
}
|
||||
|
||||
B correctedDoForward(A a) {
|
||||
if (handleNullAutomatically) {
|
||||
// TODO(kevinb): we shouldn't be checking for a null result at runtime. Assert?
|
||||
return a == null ? null : checkNotNull(doForward(a));
|
||||
} else {
|
||||
return doForward(a);
|
||||
}
|
||||
}
|
||||
|
||||
A correctedDoBackward(B b) {
|
||||
if (handleNullAutomatically) {
|
||||
// TODO(kevinb): we shouldn't be checking for a null result at runtime. Assert?
|
||||
return b == null ? null : checkNotNull(doBackward(b));
|
||||
} else {
|
||||
return doBackward(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterable that applies {@code convert} to each element of {@code fromIterable}. The
|
||||
* conversion is done lazily.
|
||||
*
|
||||
* <p>The returned iterable's iterator supports {@code remove()} if the input iterator does. After
|
||||
* a successful {@code remove()} call, {@code fromIterable} no longer contains the corresponding
|
||||
* element.
|
||||
*/
|
||||
public Iterable<B> convertAll(final Iterable<? extends A> fromIterable) {
|
||||
checkNotNull(fromIterable, "fromIterable");
|
||||
return new Iterable<B>() {
|
||||
@Override
|
||||
public Iterator<B> iterator() {
|
||||
return new Iterator<B>() {
|
||||
private final Iterator<? extends A> fromIterator = fromIterable.iterator();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return fromIterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public B next() {
|
||||
return convert(fromIterator.next());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
fromIterator.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reversed view of this converter, which converts {@code this.convert(a)} back to a
|
||||
* value roughly equivalent to {@code a}.
|
||||
*
|
||||
* <p>The returned converter is serializable if {@code this} converter is.
|
||||
*
|
||||
* <p><b>Note:</b> you should not override this method. It is non-final for legacy reasons.
|
||||
*/
|
||||
public Converter<B, A> reverse() {
|
||||
Converter<B, A> result = reverse;
|
||||
return (result == null) ? reverse = new ReverseConverter<>(this) : result;
|
||||
}
|
||||
|
||||
private static final class ReverseConverter<A, B> extends Converter<B, A>
|
||||
implements Serializable {
|
||||
final Converter<A, B> original;
|
||||
|
||||
ReverseConverter(Converter<A, B> original) {
|
||||
this.original = original;
|
||||
}
|
||||
|
||||
/*
|
||||
* These gymnastics are a little confusing. Basically this class has neither legacy nor
|
||||
* non-legacy behavior; it just needs to let the behavior of the backing converter shine
|
||||
* through. So, we override the correctedDo* methods, after which the do* methods should never
|
||||
* be reached.
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected A doForward(B b) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected B doBackward(A a) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
A correctedDoForward(B b) {
|
||||
return original.correctedDoBackward(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
B correctedDoBackward(A a) {
|
||||
return original.correctedDoForward(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Converter<A, B> reverse() {
|
||||
return original;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof ReverseConverter) {
|
||||
ReverseConverter<?, ?> that = (ReverseConverter<?, ?>) object;
|
||||
return this.original.equals(that.original);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ~original.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return original + ".reverse()";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a converter whose {@code convert} method applies {@code secondConverter} to the result
|
||||
* of this converter. Its {@code reverse} method applies the converters in reverse order.
|
||||
*
|
||||
* <p>The returned converter is serializable if {@code this} converter and {@code secondConverter}
|
||||
* are.
|
||||
*/
|
||||
public final <C> Converter<A, C> andThen(Converter<B, C> secondConverter) {
|
||||
return doAndThen(secondConverter);
|
||||
}
|
||||
|
||||
/** Package-private non-final implementation of andThen() so only we can override it. */
|
||||
<C> Converter<A, C> doAndThen(Converter<B, C> secondConverter) {
|
||||
return new ConverterComposition<>(this, checkNotNull(secondConverter));
|
||||
}
|
||||
|
||||
private static final class ConverterComposition<A, B, C> extends Converter<A, C>
|
||||
implements Serializable {
|
||||
final Converter<A, B> first;
|
||||
final Converter<B, C> second;
|
||||
|
||||
ConverterComposition(Converter<A, B> first, Converter<B, C> second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
/*
|
||||
* These gymnastics are a little confusing. Basically this class has neither legacy nor
|
||||
* non-legacy behavior; it just needs to let the behaviors of the backing converters shine
|
||||
* through (which might even differ from each other!). So, we override the correctedDo* methods,
|
||||
* after which the do* methods should never be reached.
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected C doForward(A a) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected A doBackward(C c) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
C correctedDoForward(A a) {
|
||||
return second.correctedDoForward(first.correctedDoForward(a));
|
||||
}
|
||||
|
||||
@Override
|
||||
A correctedDoBackward(C c) {
|
||||
return first.correctedDoBackward(second.correctedDoBackward(c));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof ConverterComposition) {
|
||||
ConverterComposition<?, ?, ?> that = (ConverterComposition<?, ?, ?>) object;
|
||||
return this.first.equals(that.first) && this.second.equals(that.second);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * first.hashCode() + second.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return first + ".andThen(" + second + ")";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Provided to satisfy the {@code Function} interface; use {@link #convert} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public final B apply(A a) {
|
||||
return convert(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether another object is equal to this converter.
|
||||
*
|
||||
* <p>Most implementations will have no reason to override the behavior of {@link Object#equals}.
|
||||
* However, an implementation may also choose to return {@code true} whenever {@code object} is a
|
||||
* {@link Converter} that it considers <i>interchangeable</i> with this one. "Interchangeable"
|
||||
* <i>typically</i> means that {@code Objects.equal(this.convert(a), that.convert(a))} is true for
|
||||
* all {@code a} of type {@code A} (and similarly for {@code reverse}). Note that a {@code false}
|
||||
* result from this method does not imply that the converters are known <i>not</i> to be
|
||||
* interchangeable.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
// Static converters
|
||||
|
||||
/**
|
||||
* Returns a converter based on separate forward and backward functions. This is useful if the
|
||||
* function instances already exist, or so that you can supply lambda expressions. If those
|
||||
* circumstances don't apply, you probably don't need to use this; subclass {@code Converter} and
|
||||
* implement its {@link #doForward} and {@link #doBackward} methods directly.
|
||||
*
|
||||
* <p>These functions will never be passed {@code null} and must not under any circumstances
|
||||
* return {@code null}. If a value cannot be converted, the function should throw an unchecked
|
||||
* exception (typically, but not necessarily, {@link IllegalArgumentException}).
|
||||
*
|
||||
* <p>The returned converter is serializable if both provided functions are.
|
||||
*
|
||||
* @since 17.0
|
||||
*/
|
||||
public static <A, B> Converter<A, B> from(
|
||||
Function<? super A, ? extends B> forwardFunction,
|
||||
Function<? super B, ? extends A> backwardFunction) {
|
||||
return new FunctionBasedConverter<>(forwardFunction, backwardFunction);
|
||||
}
|
||||
|
||||
private static final class FunctionBasedConverter<A, B> extends Converter<A, B>
|
||||
implements Serializable {
|
||||
private final Function<? super A, ? extends B> forwardFunction;
|
||||
private final Function<? super B, ? extends A> backwardFunction;
|
||||
|
||||
private FunctionBasedConverter(
|
||||
Function<? super A, ? extends B> forwardFunction,
|
||||
Function<? super B, ? extends A> backwardFunction) {
|
||||
this.forwardFunction = checkNotNull(forwardFunction);
|
||||
this.backwardFunction = checkNotNull(backwardFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected B doForward(A a) {
|
||||
return forwardFunction.apply(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected A doBackward(B b) {
|
||||
return backwardFunction.apply(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof FunctionBasedConverter) {
|
||||
FunctionBasedConverter<?, ?> that = (FunctionBasedConverter<?, ?>) object;
|
||||
return this.forwardFunction.equals(that.forwardFunction)
|
||||
&& this.backwardFunction.equals(that.backwardFunction);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return forwardFunction.hashCode() * 31 + backwardFunction.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Converter.from(" + forwardFunction + ", " + backwardFunction + ")";
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a serializable converter that always converts or reverses an object to itself. */
|
||||
@SuppressWarnings("unchecked") // implementation is "fully variant"
|
||||
public static <T> Converter<T, T> identity() {
|
||||
return (IdentityConverter<T>) IdentityConverter.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* A converter that always converts or reverses an object to itself. Note that T is now a
|
||||
* "pass-through type".
|
||||
*/
|
||||
private static final class IdentityConverter<T> extends Converter<T, T> implements Serializable {
|
||||
static final IdentityConverter<?> INSTANCE = new IdentityConverter<>();
|
||||
|
||||
@Override
|
||||
protected T doForward(T t) {
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T doBackward(T t) {
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentityConverter<T> reverse() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
<S> Converter<T, S> doAndThen(Converter<T, S> otherConverter) {
|
||||
return checkNotNull(otherConverter, "otherConverter");
|
||||
}
|
||||
|
||||
/*
|
||||
* We *could* override convertAll() to return its input, but it's a rather pointless
|
||||
* optimization and opened up a weird type-safety problem.
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Converter.identity()";
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
}
|
||||
}
|
62
src/main/java/com/google/common/base/Defaults.java
Normal file
62
src/main/java/com/google/common/base/Defaults.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
|
||||
/**
|
||||
* This class provides default values for all Java types, as defined by the JLS.
|
||||
*
|
||||
* @author Ben Yu
|
||||
* @since 1.0
|
||||
*/
|
||||
@GwtIncompatible
|
||||
public final class Defaults {
|
||||
private Defaults() {}
|
||||
|
||||
private static final Double DOUBLE_DEFAULT = Double.valueOf(0d);
|
||||
private static final Float FLOAT_DEFAULT = Float.valueOf(0f);
|
||||
|
||||
/**
|
||||
* Returns the default value of {@code type} as defined by JLS --- {@code 0} for numbers, {@code
|
||||
* false} for {@code boolean} and {@code '\0'} for {@code char}. For non-primitive types and
|
||||
* {@code void}, {@code null} is returned.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T defaultValue(Class<T> type) {
|
||||
checkNotNull(type);
|
||||
if (type == boolean.class) {
|
||||
return (T) Boolean.FALSE;
|
||||
} else if (type == char.class) {
|
||||
return (T) Character.valueOf('\0');
|
||||
} else if (type == byte.class) {
|
||||
return (T) Byte.valueOf((byte) 0);
|
||||
} else if (type == short.class) {
|
||||
return (T) Short.valueOf((short) 0);
|
||||
} else if (type == int.class) {
|
||||
return (T) Integer.valueOf(0);
|
||||
} else if (type == long.class) {
|
||||
return (T) Long.valueOf(0L);
|
||||
} else if (type == float.class) {
|
||||
return (T) FLOAT_DEFAULT;
|
||||
} else if (type == double.class) {
|
||||
return (T) DOUBLE_DEFAULT;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
150
src/main/java/com/google/common/base/Enums.java
Normal file
150
src/main/java/com/google/common/base/Enums.java
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import java.io.Serializable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Utility methods for working with {@link Enum} instances.
|
||||
*
|
||||
* @author Steve McKay
|
||||
* @since 9.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class Enums {
|
||||
|
||||
private Enums() {}
|
||||
|
||||
/**
|
||||
* Returns the {@link Field} in which {@code enumValue} is defined. For example, to get the {@code
|
||||
* Description} annotation on the {@code GOLF} constant of enum {@code Sport}, use {@code
|
||||
* Enums.getField(Sport.GOLF).getAnnotation(Description.class)}.
|
||||
*
|
||||
* @since 12.0
|
||||
*/
|
||||
@GwtIncompatible // reflection
|
||||
public static Field getField(Enum<?> enumValue) {
|
||||
Class<?> clazz = enumValue.getDeclaringClass();
|
||||
try {
|
||||
return clazz.getDeclaredField(enumValue.name());
|
||||
} catch (NoSuchFieldException impossible) {
|
||||
throw new AssertionError(impossible);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an optional enum constant for the given type, using {@link Enum#valueOf}. If the
|
||||
* constant does not exist, {@link Optional#absent} is returned. A common use case is for parsing
|
||||
* user input or falling back to a default enum constant. For example, {@code
|
||||
* Enums.getIfPresent(Country.class, countryInput).or(Country.DEFAULT);}
|
||||
*
|
||||
* @since 12.0
|
||||
*/
|
||||
public static <T extends Enum<T>> Optional<T> getIfPresent(Class<T> enumClass, String value) {
|
||||
checkNotNull(enumClass);
|
||||
checkNotNull(value);
|
||||
return Platform.getEnumIfPresent(enumClass, value);
|
||||
}
|
||||
|
||||
@GwtIncompatible // java.lang.ref.WeakReference
|
||||
private static final Map<Class<? extends Enum<?>>, Map<String, WeakReference<? extends Enum<?>>>>
|
||||
enumConstantCache = new WeakHashMap<>();
|
||||
|
||||
@GwtIncompatible // java.lang.ref.WeakReference
|
||||
private static <T extends Enum<T>> Map<String, WeakReference<? extends Enum<?>>> populateCache(
|
||||
Class<T> enumClass) {
|
||||
Map<String, WeakReference<? extends Enum<?>>> result = new HashMap<>();
|
||||
for (T enumInstance : EnumSet.allOf(enumClass)) {
|
||||
result.put(enumInstance.name(), new WeakReference<Enum<?>>(enumInstance));
|
||||
}
|
||||
enumConstantCache.put(enumClass, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@GwtIncompatible // java.lang.ref.WeakReference
|
||||
static <T extends Enum<T>> Map<String, WeakReference<? extends Enum<?>>> getEnumConstants(
|
||||
Class<T> enumClass) {
|
||||
synchronized (enumConstantCache) {
|
||||
Map<String, WeakReference<? extends Enum<?>>> constants = enumConstantCache.get(enumClass);
|
||||
if (constants == null) {
|
||||
constants = populateCache(enumClass);
|
||||
}
|
||||
return constants;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a converter that converts between strings and {@code enum} values of type {@code
|
||||
* enumClass} using {@link Enum#valueOf(Class, String)} and {@link Enum#name()}. The converter
|
||||
* will throw an {@code IllegalArgumentException} if the argument is not the name of any enum
|
||||
* constant in the specified enum.
|
||||
*
|
||||
* @since 16.0
|
||||
*/
|
||||
public static <T extends Enum<T>> Converter<String, T> stringConverter(final Class<T> enumClass) {
|
||||
return new StringConverter<T>(enumClass);
|
||||
}
|
||||
|
||||
private static final class StringConverter<T extends Enum<T>> extends Converter<String, T>
|
||||
implements Serializable {
|
||||
|
||||
private final Class<T> enumClass;
|
||||
|
||||
StringConverter(Class<T> enumClass) {
|
||||
this.enumClass = checkNotNull(enumClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T doForward(String value) {
|
||||
return Enum.valueOf(enumClass, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doBackward(T enumValue) {
|
||||
return enumValue.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof StringConverter) {
|
||||
StringConverter<?> that = (StringConverter<?>) object;
|
||||
return this.enumClass.equals(that.enumClass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return enumClass.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Enums.stringConverter(" + enumClass.getName() + ".class)";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
}
|
||||
}
|
374
src/main/java/com/google/common/base/Equivalence.java
Normal file
374
src/main/java/com/google/common/base/Equivalence.java
Normal file
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.io.Serializable;
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
/**
|
||||
* A strategy for determining whether two instances are considered equivalent, and for computing
|
||||
* hash codes in a manner consistent with that equivalence. Two examples of equivalences are the
|
||||
* {@linkplain #identity() identity equivalence} and the {@linkplain #equals "equals" equivalence}.
|
||||
*
|
||||
* @author Bob Lee
|
||||
* @author Ben Yu
|
||||
* @author Gregory Kick
|
||||
* @since 10.0 (<a href="https://github.com/google/guava/wiki/Compatibility">mostly
|
||||
* source-compatible</a> since 4.0)
|
||||
*/
|
||||
@GwtCompatible
|
||||
public abstract class Equivalence<T> implements BiPredicate<T, T> {
|
||||
/** Constructor for use by subclasses. */
|
||||
protected Equivalence() {}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the given objects are considered equivalent.
|
||||
*
|
||||
* <p>This method describes an <i>equivalence relation</i> on object references, meaning that for
|
||||
* all references {@code x}, {@code y}, and {@code z} (any of which may be null):
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@code equivalent(x, x)} is true (<i>reflexive</i> property)
|
||||
* <li>{@code equivalent(x, y)} and {@code equivalent(y, x)} each return the same result
|
||||
* (<i>symmetric</i> property)
|
||||
* <li>If {@code equivalent(x, y)} and {@code equivalent(y, z)} are both true, then {@code
|
||||
* equivalent(x, z)} is also true (<i>transitive</i> property)
|
||||
* </ul>
|
||||
*
|
||||
* <p>Note that all calls to {@code equivalent(x, y)} are expected to return the same result as
|
||||
* long as neither {@code x} nor {@code y} is modified.
|
||||
*/
|
||||
public final boolean equivalent(T a, T b) {
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
if (a == null || b == null) {
|
||||
return false;
|
||||
}
|
||||
return doEquivalent(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Provided only to satisfy the {@link BiPredicate} interface; use {@link #equivalent}
|
||||
* instead.
|
||||
* @since 21.0
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public final boolean test(T t, T u) {
|
||||
return equivalent(t, u);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented by the user to determine whether {@code a} and {@code b} are considered equivalent,
|
||||
* subject to the requirements specified in {@link #equivalent}.
|
||||
*
|
||||
* <p>This method should not be called except by {@link #equivalent}. When {@link #equivalent}
|
||||
* calls this method, {@code a} and {@code b} are guaranteed to be distinct, non-null instances.
|
||||
*
|
||||
* @since 10.0 (previously, subclasses would override equivalent())
|
||||
*/
|
||||
protected abstract boolean doEquivalent(T a, T b);
|
||||
|
||||
/**
|
||||
* Returns a hash code for {@code t}.
|
||||
*
|
||||
* <p>The {@code hash} has the following properties:
|
||||
*
|
||||
* <ul>
|
||||
* <li>It is <i>consistent</i>: for any reference {@code x}, multiple invocations of {@code
|
||||
* hash(x}} consistently return the same value provided {@code x} remains unchanged
|
||||
* according to the definition of the equivalence. The hash need not remain consistent from
|
||||
* one execution of an application to another execution of the same application.
|
||||
* <li>It is <i>distributable across equivalence</i>: for any references {@code x} and {@code
|
||||
* y}, if {@code equivalent(x, y)}, then {@code hash(x) == hash(y)}. It is <i>not</i>
|
||||
* necessary that the hash be distributable across <i>inequivalence</i>. If {@code
|
||||
* equivalence(x, y)} is false, {@code hash(x) == hash(y)} may still be true.
|
||||
* <li>{@code hash(null)} is {@code 0}.
|
||||
* </ul>
|
||||
*/
|
||||
public final int hash(T t) {
|
||||
if (t == null) {
|
||||
return 0;
|
||||
}
|
||||
return doHash(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented by the user to return a hash code for {@code t}, subject to the requirements
|
||||
* specified in {@link #hash}.
|
||||
*
|
||||
* <p>This method should not be called except by {@link #hash}. When {@link #hash} calls this
|
||||
* method, {@code t} is guaranteed to be non-null.
|
||||
*
|
||||
* @since 10.0 (previously, subclasses would override hash())
|
||||
*/
|
||||
protected abstract int doHash(T t);
|
||||
|
||||
/**
|
||||
* Returns a new equivalence relation for {@code F} which evaluates equivalence by first applying
|
||||
* {@code function} to the argument, then evaluating using {@code this}. That is, for any pair of
|
||||
* non-null objects {@code x} and {@code y}, {@code equivalence.onResultOf(function).equivalent(a,
|
||||
* b)} is true if and only if {@code equivalence.equivalent(function.apply(a), function.apply(b))}
|
||||
* is true.
|
||||
*
|
||||
* <p>For example:
|
||||
*
|
||||
* <pre>{@code
|
||||
* Equivalence<Person> SAME_AGE = Equivalence.equals().onResultOf(GET_PERSON_AGE);
|
||||
* }</pre>
|
||||
*
|
||||
* <p>{@code function} will never be invoked with a null value.
|
||||
*
|
||||
* <p>Note that {@code function} must be consistent according to {@code this} equivalence
|
||||
* relation. That is, invoking {@link Function#apply} multiple times for a given value must return
|
||||
* equivalent results. For example, {@code
|
||||
* Equivalence.identity().onResultOf(Functions.toStringFunction())} is broken because it's not
|
||||
* guaranteed that {@link Object#toString}) always returns the same string instance.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public final <F> Equivalence<F> onResultOf(Function<F, ? extends T> function) {
|
||||
return new FunctionalEquivalence<>(function, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a wrapper of {@code reference} that implements {@link Wrapper#equals(Object)
|
||||
* Object.equals()} such that {@code wrap(a).equals(wrap(b))} if and only if {@code equivalent(a,
|
||||
* b)}.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public final <S extends T> Wrapper<S> wrap(S reference) {
|
||||
return new Wrapper<S>(this, reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an object so that {@link #equals(Object)} and {@link #hashCode()} delegate to an {@link
|
||||
* Equivalence}.
|
||||
*
|
||||
* <p>For example, given an {@link Equivalence} for {@link String strings} named {@code equiv}
|
||||
* that tests equivalence using their lengths:
|
||||
*
|
||||
* <pre>{@code
|
||||
* equiv.wrap("a").equals(equiv.wrap("b")) // true
|
||||
* equiv.wrap("a").equals(equiv.wrap("hello")) // false
|
||||
* }</pre>
|
||||
*
|
||||
* <p>Note in particular that an equivalence wrapper is never equal to the object it wraps.
|
||||
*
|
||||
* <pre>{@code
|
||||
* equiv.wrap(obj).equals(obj) // always false
|
||||
* }</pre>
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public static final class Wrapper<T> implements Serializable {
|
||||
private final Equivalence<? super T> equivalence;
|
||||
private final T reference;
|
||||
|
||||
private Wrapper(Equivalence<? super T> equivalence, T reference) {
|
||||
this.equivalence = checkNotNull(equivalence);
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
/** Returns the (possibly null) reference wrapped by this instance. */
|
||||
public T get() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@link Equivalence#equivalent(Object, Object)} applied to the wrapped
|
||||
* references is {@code true} and both wrappers use the {@link Object#equals(Object) same}
|
||||
* equivalence.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof Wrapper) {
|
||||
Wrapper<?> that = (Wrapper<?>) obj; // note: not necessarily a Wrapper<T>
|
||||
|
||||
if (this.equivalence.equals(that.equivalence)) {
|
||||
/*
|
||||
* We'll accept that as sufficient "proof" that either equivalence should be able to
|
||||
* handle either reference, so it's safe to circumvent compile-time type checking.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
Equivalence<Object> equivalence = (Equivalence<Object>) this.equivalence;
|
||||
return equivalence.equivalent(this.reference, that.reference);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns the result of {@link Equivalence#hash(Object)} applied to the wrapped reference. */
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return equivalence.hash(reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation for this equivalence wrapper. The form of this string
|
||||
* representation is not specified.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return equivalence + ".wrap(" + reference + ")";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an equivalence over iterables based on the equivalence of their elements. More
|
||||
* specifically, two iterables are considered equivalent if they both contain the same number of
|
||||
* elements, and each pair of corresponding elements is equivalent according to {@code this}. Null
|
||||
* iterables are equivalent to one another.
|
||||
*
|
||||
* <p>Note that this method performs a similar function for equivalences as {@link
|
||||
* com.google.common.collect.Ordering#lexicographical} does for orderings.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
@GwtCompatible(serializable = true)
|
||||
public final <S extends T> Equivalence<Iterable<S>> pairwise() {
|
||||
// Ideally, the returned equivalence would support Iterable<? extends T>. However,
|
||||
// the need for this is so rare that it's not worth making callers deal with the ugly wildcard.
|
||||
return new PairwiseEquivalence<S>(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to true if and only if the input is equivalent to {@code
|
||||
* target} according to this equivalence relation.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public final Predicate<T> equivalentTo(T target) {
|
||||
return new EquivalentToPredicate<T>(this, target);
|
||||
}
|
||||
|
||||
private static final class EquivalentToPredicate<T> implements Predicate<T>, Serializable {
|
||||
|
||||
private final Equivalence<T> equivalence;
|
||||
private final T target;
|
||||
|
||||
EquivalentToPredicate(Equivalence<T> equivalence, T target) {
|
||||
this.equivalence = checkNotNull(equivalence);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(T input) {
|
||||
return equivalence.equivalent(input, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof EquivalentToPredicate) {
|
||||
EquivalentToPredicate<?> that = (EquivalentToPredicate<?>) obj;
|
||||
return equivalence.equals(that.equivalence) && Objects.equal(target, that.target);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(equivalence, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return equivalence + ".equivalentTo(" + target + ")";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an equivalence that delegates to {@link Object#equals} and {@link Object#hashCode}.
|
||||
* {@link Equivalence#equivalent} returns {@code true} if both values are null, or if neither
|
||||
* value is null and {@link Object#equals} returns {@code true}. {@link Equivalence#hash} returns
|
||||
* {@code 0} if passed a null value.
|
||||
*
|
||||
* @since 13.0
|
||||
* @since 8.0 (in Equivalences with null-friendly behavior)
|
||||
* @since 4.0 (in Equivalences)
|
||||
*/
|
||||
public static Equivalence<Object> equals() {
|
||||
return Equals.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an equivalence that uses {@code ==} to compare values and {@link
|
||||
* System#identityHashCode(Object)} to compute the hash code. {@link Equivalence#equivalent}
|
||||
* returns {@code true} if {@code a == b}, including in the case that a and b are both null.
|
||||
*
|
||||
* @since 13.0
|
||||
* @since 4.0 (in Equivalences)
|
||||
*/
|
||||
public static Equivalence<Object> identity() {
|
||||
return Identity.INSTANCE;
|
||||
}
|
||||
|
||||
static final class Equals extends Equivalence<Object> implements Serializable {
|
||||
|
||||
static final Equals INSTANCE = new Equals();
|
||||
|
||||
@Override
|
||||
protected boolean doEquivalent(Object a, Object b) {
|
||||
return a.equals(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doHash(Object o) {
|
||||
return o.hashCode();
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
}
|
||||
|
||||
static final class Identity extends Equivalence<Object> implements Serializable {
|
||||
|
||||
static final Identity INSTANCE = new Identity();
|
||||
|
||||
@Override
|
||||
protected boolean doEquivalent(Object a, Object b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doHash(Object o) {
|
||||
return System.identityHashCode(o);
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* Holder for extra methods of {@code Objects} only in web. Intended to be empty for regular
|
||||
* version.
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
abstract class ExtraObjectsMethodsForWeb {}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
|
||||
/**
|
||||
* Phantom reference with a {@code finalizeReferent()} method which a background thread invokes
|
||||
* after the garbage collector reclaims the referent. This is a simpler alternative to using a
|
||||
* {@link ReferenceQueue}.
|
||||
*
|
||||
* <p>Unlike a normal phantom reference, this reference will be cleared automatically.
|
||||
*
|
||||
* @author Bob Lee
|
||||
* @since 2.0
|
||||
*/
|
||||
@GwtIncompatible
|
||||
public abstract class FinalizablePhantomReference<T> extends PhantomReference<T>
|
||||
implements FinalizableReference {
|
||||
/**
|
||||
* Constructs a new finalizable phantom reference.
|
||||
*
|
||||
* @param referent to phantom reference
|
||||
* @param queue that should finalize the referent
|
||||
*/
|
||||
protected FinalizablePhantomReference(T referent, FinalizableReferenceQueue queue) {
|
||||
super(referent, queue.queue);
|
||||
queue.cleanUp();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
|
||||
/**
|
||||
* Implemented by references that have code to run after garbage collection of their referents.
|
||||
*
|
||||
* @see FinalizableReferenceQueue
|
||||
* @author Bob Lee
|
||||
* @since 2.0
|
||||
*/
|
||||
@GwtIncompatible
|
||||
public interface FinalizableReference {
|
||||
/**
|
||||
* Invoked on a background thread after the referent has been garbage collected unless security
|
||||
* restrictions prevented starting a background thread, in which case this method is invoked when
|
||||
* new references are created.
|
||||
*/
|
||||
void finalizeReferent();
|
||||
}
|
|
@ -0,0 +1,350 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import java.io.Closeable;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A reference queue with an associated background thread that dequeues references and invokes
|
||||
* {@link FinalizableReference#finalizeReferent()} on them.
|
||||
*
|
||||
* <p>Keep a strong reference to this object until all of the associated referents have been
|
||||
* finalized. If this object is garbage collected earlier, the backing thread will not invoke {@code
|
||||
* finalizeReferent()} on the remaining references.
|
||||
*
|
||||
* <p>As an example of how this is used, imagine you have a class {@code MyServer} that creates a a
|
||||
* {@link java.net.ServerSocket ServerSocket}, and you would like to ensure that the {@code
|
||||
* ServerSocket} is closed even if the {@code MyServer} object is garbage-collected without calling
|
||||
* its {@code close} method. You <em>could</em> use a finalizer to accomplish this, but that has a
|
||||
* number of well-known problems. Here is how you might use this class instead:
|
||||
*
|
||||
* <pre>{@code
|
||||
* public class MyServer implements Closeable {
|
||||
* private static final FinalizableReferenceQueue frq = new FinalizableReferenceQueue();
|
||||
* // You might also share this between several objects.
|
||||
*
|
||||
* private static final Set<Reference<?>> references = Sets.newConcurrentHashSet();
|
||||
* // This ensures that the FinalizablePhantomReference itself is not garbage-collected.
|
||||
*
|
||||
* private final ServerSocket serverSocket;
|
||||
*
|
||||
* private MyServer(...) {
|
||||
* ...
|
||||
* this.serverSocket = new ServerSocket(...);
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* public static MyServer create(...) {
|
||||
* MyServer myServer = new MyServer(...);
|
||||
* final ServerSocket serverSocket = myServer.serverSocket;
|
||||
* Reference<?> reference = new FinalizablePhantomReference<MyServer>(myServer, frq) {
|
||||
* public void finalizeReferent() {
|
||||
* references.remove(this):
|
||||
* if (!serverSocket.isClosed()) {
|
||||
* ...log a message about how nobody called close()...
|
||||
* try {
|
||||
* serverSocket.close();
|
||||
* } catch (IOException e) {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* };
|
||||
* references.add(reference);
|
||||
* return myServer;
|
||||
* }
|
||||
*
|
||||
* public void close() {
|
||||
* serverSocket.close();
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @author Bob Lee
|
||||
* @since 2.0
|
||||
*/
|
||||
@GwtIncompatible
|
||||
public class FinalizableReferenceQueue implements Closeable {
|
||||
/*
|
||||
* The Finalizer thread keeps a phantom reference to this object. When the client (for example, a
|
||||
* map built by MapMaker) no longer has a strong reference to this object, the garbage collector
|
||||
* will reclaim it and enqueue the phantom reference. The enqueued reference will trigger the
|
||||
* Finalizer to stop.
|
||||
*
|
||||
* If this library is loaded in the system class loader, FinalizableReferenceQueue can load
|
||||
* Finalizer directly with no problems.
|
||||
*
|
||||
* If this library is loaded in an application class loader, it's important that Finalizer not
|
||||
* have a strong reference back to the class loader. Otherwise, you could have a graph like this:
|
||||
*
|
||||
* Finalizer Thread runs instance of -> Finalizer.class loaded by -> Application class loader
|
||||
* which loaded -> ReferenceMap.class which has a static -> FinalizableReferenceQueue instance
|
||||
*
|
||||
* Even if no other references to classes from the application class loader remain, the Finalizer
|
||||
* thread keeps an indirect strong reference to the queue in ReferenceMap, which keeps the
|
||||
* Finalizer running, and as a result, the application class loader can never be reclaimed.
|
||||
*
|
||||
* This means that dynamically loaded web applications and OSGi bundles can't be unloaded.
|
||||
*
|
||||
* If the library is loaded in an application class loader, we try to break the cycle by loading
|
||||
* Finalizer in its own independent class loader:
|
||||
*
|
||||
* System class loader -> Application class loader -> ReferenceMap -> FinalizableReferenceQueue ->
|
||||
* etc. -> Decoupled class loader -> Finalizer
|
||||
*
|
||||
* Now, Finalizer no longer keeps an indirect strong reference to the static
|
||||
* FinalizableReferenceQueue field in ReferenceMap. The application class loader can be reclaimed
|
||||
* at which point the Finalizer thread will stop and its decoupled class loader can also be
|
||||
* reclaimed.
|
||||
*
|
||||
* If any of this fails along the way, we fall back to loading Finalizer directly in the
|
||||
* application class loader.
|
||||
*
|
||||
* NOTE: The tests for this behavior (FinalizableReferenceQueueClassLoaderUnloadingTest) fail
|
||||
* strangely when run in JDK 9. We are considering this a known issue. Please see
|
||||
* https://github.com/google/guava/issues/3086 for more information.
|
||||
*/
|
||||
|
||||
private static final Logger logger = Logger.getLogger(FinalizableReferenceQueue.class.getName());
|
||||
|
||||
private static final String FINALIZER_CLASS_NAME = "com.google.common.base.internal.Finalizer";
|
||||
|
||||
/** Reference to Finalizer.startFinalizer(). */
|
||||
private static final Method startFinalizer;
|
||||
|
||||
static {
|
||||
Class<?> finalizer =
|
||||
loadFinalizer(new SystemLoader(), new DecoupledLoader(), new DirectLoader());
|
||||
startFinalizer = getStartFinalizer(finalizer);
|
||||
}
|
||||
|
||||
/** The actual reference queue that our background thread will poll. */
|
||||
final ReferenceQueue<Object> queue;
|
||||
|
||||
final PhantomReference<Object> frqRef;
|
||||
|
||||
/** Whether or not the background thread started successfully. */
|
||||
final boolean threadStarted;
|
||||
|
||||
/** Constructs a new queue. */
|
||||
public FinalizableReferenceQueue() {
|
||||
// We could start the finalizer lazily, but I'd rather it blow up early.
|
||||
queue = new ReferenceQueue<>();
|
||||
frqRef = new PhantomReference<Object>(this, queue);
|
||||
boolean threadStarted = false;
|
||||
try {
|
||||
startFinalizer.invoke(null, FinalizableReference.class, queue, frqRef);
|
||||
threadStarted = true;
|
||||
} catch (IllegalAccessException impossible) {
|
||||
throw new AssertionError(impossible); // startFinalizer() is public
|
||||
} catch (Throwable t) {
|
||||
logger.log(
|
||||
Level.INFO,
|
||||
"Failed to start reference finalizer thread."
|
||||
+ " Reference cleanup will only occur when new references are created.",
|
||||
t);
|
||||
}
|
||||
|
||||
this.threadStarted = threadStarted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
frqRef.enqueue();
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeatedly dequeues references from the queue and invokes {@link
|
||||
* FinalizableReference#finalizeReferent()} on them until the queue is empty. This method is a
|
||||
* no-op if the background thread was created successfully.
|
||||
*/
|
||||
void cleanUp() {
|
||||
if (threadStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference<?> reference;
|
||||
while ((reference = queue.poll()) != null) {
|
||||
/*
|
||||
* This is for the benefit of phantom references. Weak and soft references will have already
|
||||
* been cleared by this point.
|
||||
*/
|
||||
reference.clear();
|
||||
try {
|
||||
((FinalizableReference) reference).finalizeReferent();
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the given loaders until it finds one that can load Finalizer.
|
||||
*
|
||||
* @return Finalizer.class
|
||||
*/
|
||||
private static Class<?> loadFinalizer(FinalizerLoader... loaders) {
|
||||
for (FinalizerLoader loader : loaders) {
|
||||
Class<?> finalizer = loader.loadFinalizer();
|
||||
if (finalizer != null) {
|
||||
return finalizer;
|
||||
}
|
||||
}
|
||||
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/** Loads Finalizer.class. */
|
||||
interface FinalizerLoader {
|
||||
|
||||
/**
|
||||
* Returns Finalizer.class or null if this loader shouldn't or can't load it.
|
||||
*
|
||||
* @throws SecurityException if we don't have the appropriate privileges
|
||||
*/
|
||||
Class<?> loadFinalizer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load Finalizer from the system class loader. If Finalizer is in the system class path,
|
||||
* we needn't create a separate loader.
|
||||
*/
|
||||
static class SystemLoader implements FinalizerLoader {
|
||||
// This is used by the ClassLoader-leak test in FinalizableReferenceQueueTest to disable
|
||||
// finding Finalizer on the system class path even if it is there.
|
||||
@VisibleForTesting static boolean disabled;
|
||||
|
||||
@Override
|
||||
public Class<?> loadFinalizer() {
|
||||
if (disabled) {
|
||||
return null;
|
||||
}
|
||||
ClassLoader systemLoader;
|
||||
try {
|
||||
systemLoader = ClassLoader.getSystemClassLoader();
|
||||
} catch (SecurityException e) {
|
||||
logger.info("Not allowed to access system class loader.");
|
||||
return null;
|
||||
}
|
||||
if (systemLoader != null) {
|
||||
try {
|
||||
return systemLoader.loadClass(FINALIZER_CLASS_NAME);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// Ignore. Finalizer is simply in a child class loader.
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to load Finalizer in its own class loader. If Finalizer's thread had a direct reference to
|
||||
* our class loader (which could be that of a dynamically loaded web application or OSGi bundle),
|
||||
* it would prevent our class loader from getting garbage collected.
|
||||
*/
|
||||
static class DecoupledLoader implements FinalizerLoader {
|
||||
private static final String LOADING_ERROR =
|
||||
"Could not load Finalizer in its own class loader. Loading Finalizer in the current class "
|
||||
+ "loader instead. As a result, you will not be able to garbage collect this class "
|
||||
+ "loader. To support reclaiming this class loader, either resolve the underlying "
|
||||
+ "issue, or move Guava to your system class path.";
|
||||
|
||||
@Override
|
||||
public Class<?> loadFinalizer() {
|
||||
try {
|
||||
/*
|
||||
* We use URLClassLoader because it's the only concrete class loader implementation in the
|
||||
* JDK. If we used our own ClassLoader subclass, Finalizer would indirectly reference this
|
||||
* class loader:
|
||||
*
|
||||
* Finalizer.class -> CustomClassLoader -> CustomClassLoader.class -> This class loader
|
||||
*
|
||||
* System class loader will (and must) be the parent.
|
||||
*/
|
||||
ClassLoader finalizerLoader = newLoader(getBaseUrl());
|
||||
return finalizerLoader.loadClass(FINALIZER_CLASS_NAME);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, LOADING_ERROR, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets URL for base of path containing Finalizer.class. */
|
||||
URL getBaseUrl() throws IOException {
|
||||
// Find URL pointing to Finalizer.class file.
|
||||
String finalizerPath = FINALIZER_CLASS_NAME.replace('.', '/') + ".class";
|
||||
URL finalizerUrl = getClass().getClassLoader().getResource(finalizerPath);
|
||||
if (finalizerUrl == null) {
|
||||
throw new FileNotFoundException(finalizerPath);
|
||||
}
|
||||
|
||||
// Find URL pointing to base of class path.
|
||||
String urlString = finalizerUrl.toString();
|
||||
if (!urlString.endsWith(finalizerPath)) {
|
||||
throw new IOException("Unsupported path style: " + urlString);
|
||||
}
|
||||
urlString = urlString.substring(0, urlString.length() - finalizerPath.length());
|
||||
return new URL(finalizerUrl, urlString);
|
||||
}
|
||||
|
||||
/** Creates a class loader with the given base URL as its classpath. */
|
||||
URLClassLoader newLoader(URL base) {
|
||||
// We use the bootstrap class loader as the parent because Finalizer by design uses
|
||||
// only standard Java classes. That also means that FinalizableReferenceQueueTest
|
||||
// doesn't pick up the wrong version of the Finalizer class.
|
||||
return new URLClassLoader(new URL[] {base}, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Finalizer directly using the current class loader. We won't be able to garbage collect
|
||||
* this class loader, but at least the world doesn't end.
|
||||
*/
|
||||
static class DirectLoader implements FinalizerLoader {
|
||||
@Override
|
||||
public Class<?> loadFinalizer() {
|
||||
try {
|
||||
return Class.forName(FINALIZER_CLASS_NAME);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Looks up Finalizer.startFinalizer(). */
|
||||
static Method getStartFinalizer(Class<?> finalizer) {
|
||||
try {
|
||||
return finalizer.getMethod(
|
||||
"startFinalizer", Class.class, ReferenceQueue.class, PhantomReference.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
/**
|
||||
* Soft reference with a {@code finalizeReferent()} method which a background thread invokes after
|
||||
* the garbage collector reclaims the referent. This is a simpler alternative to using a {@link
|
||||
* ReferenceQueue}.
|
||||
*
|
||||
* @author Bob Lee
|
||||
* @since 2.0
|
||||
*/
|
||||
@GwtIncompatible
|
||||
public abstract class FinalizableSoftReference<T> extends SoftReference<T>
|
||||
implements FinalizableReference {
|
||||
/**
|
||||
* Constructs a new finalizable soft reference.
|
||||
*
|
||||
* @param referent to softly reference
|
||||
* @param queue that should finalize the referent
|
||||
*/
|
||||
protected FinalizableSoftReference(T referent, FinalizableReferenceQueue queue) {
|
||||
super(referent, queue.queue);
|
||||
queue.cleanUp();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* Weak reference with a {@code finalizeReferent()} method which a background thread invokes after
|
||||
* the garbage collector reclaims the referent. This is a simpler alternative to using a {@link
|
||||
* ReferenceQueue}.
|
||||
*
|
||||
* @author Bob Lee
|
||||
* @since 2.0
|
||||
*/
|
||||
@GwtIncompatible
|
||||
public abstract class FinalizableWeakReference<T> extends WeakReference<T>
|
||||
implements FinalizableReference {
|
||||
/**
|
||||
* Constructs a new finalizable weak reference.
|
||||
*
|
||||
* @param referent to weakly reference
|
||||
* @param queue that should finalize the referent
|
||||
*/
|
||||
protected FinalizableWeakReference(T referent, FinalizableReferenceQueue queue) {
|
||||
super(referent, queue.queue);
|
||||
queue.cleanUp();
|
||||
}
|
||||
}
|
59
src/main/java/com/google/common/base/Function.java
Normal file
59
src/main/java/com/google/common/base/Function.java
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* Legacy version of {@link java.util.function.Function java.util.function.Function}.
|
||||
*
|
||||
* <p>The {@link Functions} class provides common functions and related utilities.
|
||||
*
|
||||
* <p>As this interface extends {@code java.util.function.Function}, an instance of this type can be
|
||||
* used as a {@code java.util.function.Function} directly. To use a {@code
|
||||
* java.util.function.Function} in a context where a {@code com.google.common.base.Function} is
|
||||
* needed, use {@code function::apply}.
|
||||
*
|
||||
* <p>This interface is now a legacy type. Use {@code java.util.function.Function} (or the
|
||||
* appropriate primitive specialization such as {@code ToIntFunction}) instead whenever possible.
|
||||
* Otherwise, at least reduce <i>explicit</i> dependencies on this type by using lambda expressions
|
||||
* or method references instead of classes, leaving your code easier to migrate in the future.
|
||||
*
|
||||
* <p>See the Guava User Guide article on <a
|
||||
* href="https://github.com/google/guava/wiki/FunctionalExplained">the use of {@code Function}</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 2.0
|
||||
*/
|
||||
@GwtCompatible
|
||||
@FunctionalInterface
|
||||
public interface Function<F, T> extends java.util.function.Function<F, T> {
|
||||
@Override
|
||||
T apply(F input);
|
||||
|
||||
/**
|
||||
* <i>May</i> return {@code true} if {@code object} is a {@code Function} that behaves identically
|
||||
* to this function.
|
||||
*
|
||||
* <p><b>Warning: do not depend</b> on the behavior of this method.
|
||||
*
|
||||
* <p>Historically, {@code Function} instances in this library have implemented this method to
|
||||
* recognize certain cases where distinct {@code Function} instances would in fact behave
|
||||
* identically. However, as code migrates to {@code java.util.function}, that behavior will
|
||||
* disappear. It is best not to depend on it.
|
||||
*/
|
||||
@Override
|
||||
boolean equals(Object object);
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Equivalence applied on functional result.
|
||||
*
|
||||
* @author Bob Lee
|
||||
* @since 10.0
|
||||
*/
|
||||
@Beta
|
||||
@GwtCompatible
|
||||
final class FunctionalEquivalence<F, T> extends Equivalence<F> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
|
||||
private final Function<F, ? extends T> function;
|
||||
private final Equivalence<T> resultEquivalence;
|
||||
|
||||
FunctionalEquivalence(Function<F, ? extends T> function, Equivalence<T> resultEquivalence) {
|
||||
this.function = checkNotNull(function);
|
||||
this.resultEquivalence = checkNotNull(resultEquivalence);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doEquivalent(F a, F b) {
|
||||
return resultEquivalence.equivalent(function.apply(a), function.apply(b));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doHash(F a) {
|
||||
return resultEquivalence.hash(function.apply(a));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof FunctionalEquivalence) {
|
||||
FunctionalEquivalence<?, ?> that = (FunctionalEquivalence<?, ?>) obj;
|
||||
return function.equals(that.function) && resultEquivalence.equals(that.resultEquivalence);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(function, resultEquivalence);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return resultEquivalence + ".onResultOf(" + function + ")";
|
||||
}
|
||||
}
|
400
src/main/java/com/google/common/base/Functions.java
Normal file
400
src/main/java/com/google/common/base/Functions.java
Normal file
|
@ -0,0 +1,400 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code com.google.common.base.Function} instances; see that
|
||||
* class for information about migrating to {@code java.util.function}.
|
||||
*
|
||||
* <p>All methods return serializable functions as long as they're given serializable parameters.
|
||||
*
|
||||
* <p>See the Guava User Guide article on <a
|
||||
* href="https://github.com/google/guava/wiki/FunctionalExplained">the use of {@code Function}</a>.
|
||||
*
|
||||
* @author Mike Bostock
|
||||
* @author Jared Levy
|
||||
* @since 2.0
|
||||
*/
|
||||
@GwtCompatible
|
||||
public final class Functions {
|
||||
private Functions() {}
|
||||
|
||||
/**
|
||||
* A function equivalent to the method reference {@code Object::toString}, for users not yet using
|
||||
* Java 8. The function simply invokes {@code toString} on its argument and returns the result. It
|
||||
* throws a {@link NullPointerException} on null input.
|
||||
*
|
||||
* <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as
|
||||
* documented at {@link Function#apply}). For example, this function yields different results for
|
||||
* the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}.
|
||||
*
|
||||
* <p><b>Warning:</b> as with all function types in this package, avoid depending on the specific
|
||||
* {@code equals}, {@code hashCode} or {@code toString} behavior of the returned function. A
|
||||
* future migration to {@code java.util.function} will not preserve this behavior.
|
||||
*
|
||||
* <p><b>For Java 8 users:</b> use the method reference {@code Object::toString} instead. In the
|
||||
* future, when this class requires Java 8, this method will be deprecated. See {@link Function}
|
||||
* for more important information about the Java 8 transition.
|
||||
*/
|
||||
public static Function<Object, String> toStringFunction() {
|
||||
return ToStringFunction.INSTANCE;
|
||||
}
|
||||
|
||||
// enum singleton pattern
|
||||
private enum ToStringFunction implements Function<Object, String> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public String apply(Object o) {
|
||||
checkNotNull(o); // eager for GWT.
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Functions.toStringFunction()";
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the identity function. */
|
||||
// implementation is "fully variant"; E has become a "pass-through" type
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <E> Function<E, E> identity() {
|
||||
return (Function<E, E>) IdentityFunction.INSTANCE;
|
||||
}
|
||||
|
||||
// enum singleton pattern
|
||||
private enum IdentityFunction implements Function<Object, Object> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Object apply(Object o) {
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Functions.identity()";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a function which performs a map lookup. The returned function throws an {@link
|
||||
* IllegalArgumentException} if given a key that does not exist in the map. See also {@link
|
||||
* #forMap(Map, Object)}, which returns a default value in this case.
|
||||
*
|
||||
* <p>Note: if {@code map} is a {@link com.google.common.collect.BiMap BiMap} (or can be one), you
|
||||
* can use {@link com.google.common.collect.Maps#asConverter Maps.asConverter} instead to get a
|
||||
* function that also supports reverse conversion.
|
||||
*
|
||||
* <p><b>Java 8 users:</b> if you are okay with {@code null} being returned for an unrecognized
|
||||
* key (instead of an exception being thrown), you can use the method reference {@code map::get}
|
||||
* instead.
|
||||
*/
|
||||
public static <K, V> Function<K, V> forMap(Map<K, V> map) {
|
||||
return new FunctionForMapNoDefault<>(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a function which performs a map lookup with a default value. The function created by
|
||||
* this method returns {@code defaultValue} for all inputs that do not belong to the map's key
|
||||
* set. See also {@link #forMap(Map)}, which throws an exception in this case.
|
||||
*
|
||||
* <p><b>Java 8 users:</b> you can just write the lambda expression {@code k ->
|
||||
* map.getOrDefault(k, defaultValue)} instead.
|
||||
*
|
||||
* @param map source map that determines the function behavior
|
||||
* @param defaultValue the value to return for inputs that aren't map keys
|
||||
* @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code
|
||||
* defaultValue} otherwise
|
||||
*/
|
||||
public static <K, V> Function<K, V> forMap(Map<K, ? extends V> map, V defaultValue) {
|
||||
return new ForMapWithDefault<>(map, defaultValue);
|
||||
}
|
||||
|
||||
private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable {
|
||||
final Map<K, V> map;
|
||||
|
||||
FunctionForMapNoDefault(Map<K, V> map) {
|
||||
this.map = checkNotNull(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V apply(K key) {
|
||||
V result = map.get(key);
|
||||
checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof FunctionForMapNoDefault) {
|
||||
FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o;
|
||||
return map.equals(that.map);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return map.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Functions.forMap(" + map + ")";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable {
|
||||
final Map<K, ? extends V> map;
|
||||
final V defaultValue;
|
||||
|
||||
ForMapWithDefault(Map<K, ? extends V> map, V defaultValue) {
|
||||
this.map = checkNotNull(map);
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V apply(K key) {
|
||||
V result = map.get(key);
|
||||
return (result != null || map.containsKey(key)) ? result : defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof ForMapWithDefault) {
|
||||
ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o;
|
||||
return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(map, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// TODO(cpovirk): maybe remove "defaultValue=" to make this look like the method call does
|
||||
return "Functions.forMap(" + map + ", defaultValue=" + defaultValue + ")";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition
|
||||
* is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}.
|
||||
*
|
||||
* <p><b>Java 8 users:</b> use {@code g.compose(f)} or (probably clearer) {@code f.andThen(g)}
|
||||
* instead.
|
||||
*
|
||||
* @param g the second function to apply
|
||||
* @param f the first function to apply
|
||||
* @return the composition of {@code f} and {@code g}
|
||||
* @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
|
||||
*/
|
||||
public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) {
|
||||
return new FunctionComposition<>(g, f);
|
||||
}
|
||||
|
||||
private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable {
|
||||
private final Function<B, C> g;
|
||||
private final Function<A, ? extends B> f;
|
||||
|
||||
public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) {
|
||||
this.g = checkNotNull(g);
|
||||
this.f = checkNotNull(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public C apply(A a) {
|
||||
return g.apply(f.apply(a));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof FunctionComposition) {
|
||||
FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
|
||||
return f.equals(that.f) && g.equals(that.g);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return f.hashCode() ^ g.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// TODO(cpovirk): maybe make this look like the method call does ("Functions.compose(...)")
|
||||
return g + "(" + f + ")";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that returns the same boolean output as the given predicate for all inputs.
|
||||
*
|
||||
* <p>The returned function is <i>consistent with equals</i> (as documented at {@link
|
||||
* Function#apply}) if and only if {@code predicate} is itself consistent with equals.
|
||||
*
|
||||
* <p><b>Java 8 users:</b> use the method reference {@code predicate::test} instead.
|
||||
*/
|
||||
public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) {
|
||||
return new PredicateFunction<T>(predicate);
|
||||
}
|
||||
|
||||
/** @see Functions#forPredicate */
|
||||
private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable {
|
||||
private final Predicate<T> predicate;
|
||||
|
||||
private PredicateFunction(Predicate<T> predicate) {
|
||||
this.predicate = checkNotNull(predicate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(T t) {
|
||||
return predicate.apply(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof PredicateFunction) {
|
||||
PredicateFunction<?> that = (PredicateFunction<?>) obj;
|
||||
return predicate.equals(that.predicate);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return predicate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Functions.forPredicate(" + predicate + ")";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a function that ignores its input and always returns {@code value}.
|
||||
*
|
||||
* <p><b>Java 8 users:</b> use the lambda expression {@code o -> value} instead.
|
||||
*
|
||||
* @param value the constant value for the function to return
|
||||
* @return a function that always returns {@code value}
|
||||
*/
|
||||
public static <E> Function<Object, E> constant(E value) {
|
||||
return new ConstantFunction<E>(value);
|
||||
}
|
||||
|
||||
private static class ConstantFunction<E> implements Function<Object, E>, Serializable {
|
||||
private final E value;
|
||||
|
||||
public ConstantFunction(E value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E apply(Object from) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof ConstantFunction) {
|
||||
ConstantFunction<?> that = (ConstantFunction<?>) obj;
|
||||
return Objects.equal(value, that.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (value == null) ? 0 : value.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Functions.constant(" + value + ")";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a function that ignores its input and returns the result of {@code supplier.get()}.
|
||||
*
|
||||
* <p><b>Java 8 users:</b> use the lambda expression {@code o -> supplier.get()} instead.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public static <T> Function<Object, T> forSupplier(Supplier<T> supplier) {
|
||||
return new SupplierFunction<T>(supplier);
|
||||
}
|
||||
|
||||
/** @see Functions#forSupplier */
|
||||
private static class SupplierFunction<T> implements Function<Object, T>, Serializable {
|
||||
|
||||
private final Supplier<T> supplier;
|
||||
|
||||
private SupplierFunction(Supplier<T> supplier) {
|
||||
this.supplier = checkNotNull(supplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(Object input) {
|
||||
return supplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof SupplierFunction) {
|
||||
SupplierFunction<?> that = (SupplierFunction<?>) obj;
|
||||
return this.supplier.equals(that.supplier);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return supplier.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Functions.forSupplier(" + supplier + ")";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
}
|
90
src/main/java/com/google/common/base/JdkPattern.java
Normal file
90
src/main/java/com/google/common/base/JdkPattern.java
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import java.io.Serializable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** A regex pattern implementation which is backed by the {@link Pattern}. */
|
||||
@GwtIncompatible
|
||||
final class JdkPattern extends CommonPattern implements Serializable {
|
||||
private final Pattern pattern;
|
||||
|
||||
JdkPattern(Pattern pattern) {
|
||||
this.pattern = Preconditions.checkNotNull(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonMatcher matcher(CharSequence t) {
|
||||
return new JdkMatcher(pattern.matcher(t));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pattern() {
|
||||
return pattern.pattern();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int flags() {
|
||||
return pattern.flags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return pattern.toString();
|
||||
}
|
||||
|
||||
private static final class JdkMatcher extends CommonMatcher {
|
||||
final Matcher matcher;
|
||||
|
||||
JdkMatcher(Matcher matcher) {
|
||||
this.matcher = Preconditions.checkNotNull(matcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches() {
|
||||
return matcher.matches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean find() {
|
||||
return matcher.find();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean find(int index) {
|
||||
return matcher.find(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String replaceAll(String replacement) {
|
||||
return matcher.replaceAll(replacement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int end() {
|
||||
return matcher.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int start() {
|
||||
return matcher.start();
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
462
src/main/java/com/google/common/base/Joiner.java
Normal file
462
src/main/java/com/google/common/base/Joiner.java
Normal file
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.io.IOException;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* An object which joins pieces of text (specified as an array, {@link Iterable}, varargs or even a
|
||||
* {@link Map}) with a separator. It either appends the results to an {@link Appendable} or returns
|
||||
* them as a {@link String}. Example:
|
||||
*
|
||||
* <pre>{@code
|
||||
* Joiner joiner = Joiner.on("; ").skipNulls();
|
||||
* . . .
|
||||
* return joiner.join("Harry", null, "Ron", "Hermione");
|
||||
* }</pre>
|
||||
*
|
||||
* <p>This returns the string {@code "Harry; Ron; Hermione"}. Note that all input elements are
|
||||
* converted to strings using {@link Object#toString()} before being appended.
|
||||
*
|
||||
* <p>If neither {@link #skipNulls()} nor {@link #useForNull(String)} is specified, the joining
|
||||
* methods will throw {@link NullPointerException} if any given element is null.
|
||||
*
|
||||
* <p><b>Warning: joiner instances are always immutable</b>; a configuration method such as {@code
|
||||
* useForNull} has no effect on the instance it is invoked on! You must store and use the new joiner
|
||||
* instance returned by the method. This makes joiners thread-safe, and safe to store as {@code
|
||||
* static final} constants.
|
||||
*
|
||||
* <pre>{@code
|
||||
* // Bad! Do not do this!
|
||||
* Joiner joiner = Joiner.on(',');
|
||||
* joiner.skipNulls(); // does nothing!
|
||||
* return joiner.join("wrong", null, "wrong");
|
||||
* }</pre>
|
||||
*
|
||||
* <p>See the Guava User Guide article on <a
|
||||
* href="https://github.com/google/guava/wiki/StringsExplained#joiner">{@code Joiner}</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 2.0
|
||||
*/
|
||||
@GwtCompatible
|
||||
public class Joiner {
|
||||
/** Returns a joiner which automatically places {@code separator} between consecutive elements. */
|
||||
public static Joiner on(String separator) {
|
||||
return new Joiner(separator);
|
||||
}
|
||||
|
||||
/** Returns a joiner which automatically places {@code separator} between consecutive elements. */
|
||||
public static Joiner on(char separator) {
|
||||
return new Joiner(String.valueOf(separator));
|
||||
}
|
||||
|
||||
private final String separator;
|
||||
|
||||
private Joiner(String separator) {
|
||||
this.separator = checkNotNull(separator);
|
||||
}
|
||||
|
||||
private Joiner(Joiner prototype) {
|
||||
this.separator = prototype.separator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each of {@code parts}, using the previously configured
|
||||
* separator between each, to {@code appendable}.
|
||||
*/
|
||||
public <A extends Appendable> A appendTo(A appendable, Iterable<?> parts) throws IOException {
|
||||
return appendTo(appendable, parts.iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each of {@code parts}, using the previously configured
|
||||
* separator between each, to {@code appendable}.
|
||||
*
|
||||
* @since 11.0
|
||||
*/
|
||||
public <A extends Appendable> A appendTo(A appendable, Iterator<?> parts) throws IOException {
|
||||
checkNotNull(appendable);
|
||||
if (parts.hasNext()) {
|
||||
appendable.append(toString(parts.next()));
|
||||
while (parts.hasNext()) {
|
||||
appendable.append(separator);
|
||||
appendable.append(toString(parts.next()));
|
||||
}
|
||||
}
|
||||
return appendable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each of {@code parts}, using the previously configured
|
||||
* separator between each, to {@code appendable}.
|
||||
*/
|
||||
public final <A extends Appendable> A appendTo(A appendable, Object[] parts) throws IOException {
|
||||
return appendTo(appendable, Arrays.asList(parts));
|
||||
}
|
||||
|
||||
/** Appends to {@code appendable} the string representation of each of the remaining arguments. */
|
||||
public final <A extends Appendable> A appendTo(
|
||||
A appendable, Object first, Object second, Object... rest)
|
||||
throws IOException {
|
||||
return appendTo(appendable, iterable(first, second, rest));
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each of {@code parts}, using the previously configured
|
||||
* separator between each, to {@code builder}. Identical to {@link #appendTo(Appendable,
|
||||
* Iterable)}, except that it does not throw {@link IOException}.
|
||||
*/
|
||||
public final StringBuilder appendTo(StringBuilder builder, Iterable<?> parts) {
|
||||
return appendTo(builder, parts.iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each of {@code parts}, using the previously configured
|
||||
* separator between each, to {@code builder}. Identical to {@link #appendTo(Appendable,
|
||||
* Iterable)}, except that it does not throw {@link IOException}.
|
||||
*
|
||||
* @since 11.0
|
||||
*/
|
||||
public final StringBuilder appendTo(StringBuilder builder, Iterator<?> parts) {
|
||||
try {
|
||||
appendTo((Appendable) builder, parts);
|
||||
} catch (IOException impossible) {
|
||||
throw new AssertionError(impossible);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each of {@code parts}, using the previously configured
|
||||
* separator between each, to {@code builder}. Identical to {@link #appendTo(Appendable,
|
||||
* Iterable)}, except that it does not throw {@link IOException}.
|
||||
*/
|
||||
public final StringBuilder appendTo(StringBuilder builder, Object[] parts) {
|
||||
return appendTo(builder, Arrays.asList(parts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends to {@code builder} the string representation of each of the remaining arguments.
|
||||
* Identical to {@link #appendTo(Appendable, Object, Object, Object...)}, except that it does not
|
||||
* throw {@link IOException}.
|
||||
*/
|
||||
public final StringBuilder appendTo(
|
||||
StringBuilder builder, Object first, Object second, Object... rest) {
|
||||
return appendTo(builder, iterable(first, second, rest));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the string representation of each of {@code parts}, using the
|
||||
* previously configured separator between each.
|
||||
*/
|
||||
public final String join(Iterable<?> parts) {
|
||||
return join(parts.iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the string representation of each of {@code parts}, using the
|
||||
* previously configured separator between each.
|
||||
*
|
||||
* @since 11.0
|
||||
*/
|
||||
public final String join(Iterator<?> parts) {
|
||||
return appendTo(new StringBuilder(), parts).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the string representation of each of {@code parts}, using the
|
||||
* previously configured separator between each.
|
||||
*/
|
||||
public final String join(Object[] parts) {
|
||||
return join(Arrays.asList(parts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the string representation of each argument, using the previously
|
||||
* configured separator between each.
|
||||
*/
|
||||
public final String join(Object first, Object second, Object... rest) {
|
||||
return join(iterable(first, second, rest));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a joiner with the same behavior as this one, except automatically substituting {@code
|
||||
* nullText} for any provided null elements.
|
||||
*/
|
||||
public Joiner useForNull(final String nullText) {
|
||||
checkNotNull(nullText);
|
||||
return new Joiner(this) {
|
||||
@Override
|
||||
CharSequence toString(Object part) {
|
||||
return (part == null) ? nullText : Joiner.this.toString(part);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Joiner useForNull(String nullText) {
|
||||
throw new UnsupportedOperationException("already specified useForNull");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Joiner skipNulls() {
|
||||
throw new UnsupportedOperationException("already specified useForNull");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a joiner with the same behavior as this joiner, except automatically skipping over any
|
||||
* provided null elements.
|
||||
*/
|
||||
public Joiner skipNulls() {
|
||||
return new Joiner(this) {
|
||||
@Override
|
||||
public <A extends Appendable> A appendTo(A appendable, Iterator<?> parts) throws IOException {
|
||||
checkNotNull(appendable, "appendable");
|
||||
checkNotNull(parts, "parts");
|
||||
while (parts.hasNext()) {
|
||||
Object part = parts.next();
|
||||
if (part != null) {
|
||||
appendable.append(Joiner.this.toString(part));
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (parts.hasNext()) {
|
||||
Object part = parts.next();
|
||||
if (part != null) {
|
||||
appendable.append(separator);
|
||||
appendable.append(Joiner.this.toString(part));
|
||||
}
|
||||
}
|
||||
return appendable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Joiner useForNull(String nullText) {
|
||||
throw new UnsupportedOperationException("already specified skipNulls");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapJoiner withKeyValueSeparator(String kvs) {
|
||||
throw new UnsupportedOperationException("can't use .skipNulls() with maps");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code MapJoiner} using the given key-value separator, and the same configuration as
|
||||
* this {@code Joiner} otherwise.
|
||||
*
|
||||
* @since 20.0
|
||||
*/
|
||||
public MapJoiner withKeyValueSeparator(char keyValueSeparator) {
|
||||
return withKeyValueSeparator(String.valueOf(keyValueSeparator));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code MapJoiner} using the given key-value separator, and the same configuration as
|
||||
* this {@code Joiner} otherwise.
|
||||
*/
|
||||
public MapJoiner withKeyValueSeparator(String keyValueSeparator) {
|
||||
return new MapJoiner(this, keyValueSeparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* An object that joins map entries in the same manner as {@code Joiner} joins iterables and
|
||||
* arrays. Like {@code Joiner}, it is thread-safe and immutable.
|
||||
*
|
||||
* <p>In addition to operating on {@code Map} instances, {@code MapJoiner} can operate on {@code
|
||||
* Multimap} entries in two distinct modes:
|
||||
*
|
||||
* <ul>
|
||||
* <li>To output a separate entry for each key-value pair, pass {@code multimap.entries()} to a
|
||||
* {@code MapJoiner} method that accepts entries as input, and receive output of the form
|
||||
* {@code key1=A&key1=B&key2=C}.
|
||||
* <li>To output a single entry for each key, pass {@code multimap.asMap()} to a {@code
|
||||
* MapJoiner} method that accepts a map as input, and receive output of the form {@code
|
||||
* key1=[A, B]&key2=C}.
|
||||
* </ul>
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static final class MapJoiner {
|
||||
private final Joiner joiner;
|
||||
private final String keyValueSeparator;
|
||||
|
||||
private MapJoiner(Joiner joiner, String keyValueSeparator) {
|
||||
this.joiner = joiner; // only "this" is ever passed, so don't checkNotNull
|
||||
this.keyValueSeparator = checkNotNull(keyValueSeparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each entry of {@code map}, using the previously
|
||||
* configured separator and key-value separator, to {@code appendable}.
|
||||
*/
|
||||
public <A extends Appendable> A appendTo(A appendable, Map<?, ?> map) throws IOException {
|
||||
return appendTo(appendable, map.entrySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each entry of {@code map}, using the previously
|
||||
* configured separator and key-value separator, to {@code builder}. Identical to {@link
|
||||
* #appendTo(Appendable, Map)}, except that it does not throw {@link IOException}.
|
||||
*/
|
||||
public StringBuilder appendTo(StringBuilder builder, Map<?, ?> map) {
|
||||
return appendTo(builder, map.entrySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each entry in {@code entries}, using the previously
|
||||
* configured separator and key-value separator, to {@code appendable}.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
@Beta
|
||||
public <A extends Appendable> A appendTo(A appendable, Iterable<? extends Entry<?, ?>> entries)
|
||||
throws IOException {
|
||||
return appendTo(appendable, entries.iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each entry in {@code entries}, using the previously
|
||||
* configured separator and key-value separator, to {@code appendable}.
|
||||
*
|
||||
* @since 11.0
|
||||
*/
|
||||
@Beta
|
||||
public <A extends Appendable> A appendTo(A appendable, Iterator<? extends Entry<?, ?>> parts)
|
||||
throws IOException {
|
||||
checkNotNull(appendable);
|
||||
if (parts.hasNext()) {
|
||||
Entry<?, ?> entry = parts.next();
|
||||
appendable.append(joiner.toString(entry.getKey()));
|
||||
appendable.append(keyValueSeparator);
|
||||
appendable.append(joiner.toString(entry.getValue()));
|
||||
while (parts.hasNext()) {
|
||||
appendable.append(joiner.separator);
|
||||
Entry<?, ?> e = parts.next();
|
||||
appendable.append(joiner.toString(e.getKey()));
|
||||
appendable.append(keyValueSeparator);
|
||||
appendable.append(joiner.toString(e.getValue()));
|
||||
}
|
||||
}
|
||||
return appendable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each entry in {@code entries}, using the previously
|
||||
* configured separator and key-value separator, to {@code builder}. Identical to {@link
|
||||
* #appendTo(Appendable, Iterable)}, except that it does not throw {@link IOException}.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
@Beta
|
||||
public StringBuilder appendTo(StringBuilder builder, Iterable<? extends Entry<?, ?>> entries) {
|
||||
return appendTo(builder, entries.iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of each entry in {@code entries}, using the previously
|
||||
* configured separator and key-value separator, to {@code builder}. Identical to {@link
|
||||
* #appendTo(Appendable, Iterable)}, except that it does not throw {@link IOException}.
|
||||
*
|
||||
* @since 11.0
|
||||
*/
|
||||
@Beta
|
||||
public StringBuilder appendTo(StringBuilder builder, Iterator<? extends Entry<?, ?>> entries) {
|
||||
try {
|
||||
appendTo((Appendable) builder, entries);
|
||||
} catch (IOException impossible) {
|
||||
throw new AssertionError(impossible);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the string representation of each entry of {@code map}, using the
|
||||
* previously configured separator and key-value separator.
|
||||
*/
|
||||
public String join(Map<?, ?> map) {
|
||||
return join(map.entrySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the string representation of each entry in {@code entries}, using
|
||||
* the previously configured separator and key-value separator.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
@Beta
|
||||
public String join(Iterable<? extends Entry<?, ?>> entries) {
|
||||
return join(entries.iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the string representation of each entry in {@code entries}, using
|
||||
* the previously configured separator and key-value separator.
|
||||
*
|
||||
* @since 11.0
|
||||
*/
|
||||
@Beta
|
||||
public String join(Iterator<? extends Entry<?, ?>> entries) {
|
||||
return appendTo(new StringBuilder(), entries).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map joiner with the same behavior as this one, except automatically substituting
|
||||
* {@code nullText} for any provided null keys or values.
|
||||
*/
|
||||
public MapJoiner useForNull(String nullText) {
|
||||
return new MapJoiner(joiner.useForNull(nullText), keyValueSeparator);
|
||||
}
|
||||
}
|
||||
|
||||
CharSequence toString(Object part) {
|
||||
checkNotNull(part); // checkNotNull for GWT (do not optimize).
|
||||
return (part instanceof CharSequence) ? (CharSequence) part : part.toString();
|
||||
}
|
||||
|
||||
private static Iterable<Object> iterable(
|
||||
final Object first, final Object second, final Object[] rest) {
|
||||
checkNotNull(rest);
|
||||
return new AbstractList<Object>() {
|
||||
@Override
|
||||
public int size() {
|
||||
return rest.length + 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return first;
|
||||
case 1:
|
||||
return second;
|
||||
default:
|
||||
return rest[index - 2];
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
373
src/main/java/com/google/common/base/MoreObjects.java
Normal file
373
src/main/java/com/google/common/base/MoreObjects.java
Normal file
|
@ -0,0 +1,373 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Helper functions that operate on any {@code Object}, and are not already provided in {@link
|
||||
* java.util.Objects}.
|
||||
*
|
||||
* <p>See the Guava User Guide on <a
|
||||
* href="https://github.com/google/guava/wiki/CommonObjectUtilitiesExplained">writing {@code Object}
|
||||
* methods with {@code MoreObjects}</a>.
|
||||
*
|
||||
* @author Laurence Gonsalves
|
||||
* @since 18.0 (since 2.0 as {@code Objects})
|
||||
*/
|
||||
@GwtCompatible
|
||||
public final class MoreObjects {
|
||||
/**
|
||||
* Returns the first of two given parameters that is not {@code null}, if either is, or otherwise
|
||||
* throws a {@link NullPointerException}.
|
||||
*
|
||||
* <p>To find the first non-null element in an iterable, use {@code Iterables.find(iterable,
|
||||
* Predicates.notNull())}. For varargs, use {@code Iterables.find(Arrays.asList(a, b, c, ...),
|
||||
* Predicates.notNull())}, static importing as necessary.
|
||||
*
|
||||
* <p><b>Note:</b> if {@code first} is represented as an {@link Optional}, this can be
|
||||
* accomplished with {@link Optional#or(Object) first.or(second)}. That approach also allows for
|
||||
* lazy evaluation of the fallback instance, using {@link Optional#or(Supplier)
|
||||
* first.or(supplier)}.
|
||||
*
|
||||
* <p><b>Java 9 users:</b> use {@code java.util.Objects.requireNonNullElse(first, second)}
|
||||
* instead.
|
||||
*
|
||||
* @return {@code first} if it is non-null; otherwise {@code second} if it is non-null
|
||||
* @throws NullPointerException if both {@code first} and {@code second} are null
|
||||
* @since 18.0 (since 3.0 as {@code Objects.firstNonNull()}).
|
||||
*/
|
||||
public static <T> T firstNonNull(T first, T second) {
|
||||
if (first != null) {
|
||||
return first;
|
||||
}
|
||||
if (second != null) {
|
||||
return second;
|
||||
}
|
||||
throw new NullPointerException("Both parameters are null");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link ToStringHelper}.
|
||||
*
|
||||
* <p>This is helpful for implementing {@link Object#toString()}. Specification by example:
|
||||
*
|
||||
* <pre>{@code
|
||||
* // Returns "ClassName{}"
|
||||
* MoreObjects.toStringHelper(this)
|
||||
* .toString();
|
||||
*
|
||||
* // Returns "ClassName{x=1}"
|
||||
* MoreObjects.toStringHelper(this)
|
||||
* .add("x", 1)
|
||||
* .toString();
|
||||
*
|
||||
* // Returns "MyObject{x=1}"
|
||||
* MoreObjects.toStringHelper("MyObject")
|
||||
* .add("x", 1)
|
||||
* .toString();
|
||||
*
|
||||
* // Returns "ClassName{x=1, y=foo}"
|
||||
* MoreObjects.toStringHelper(this)
|
||||
* .add("x", 1)
|
||||
* .add("y", "foo")
|
||||
* .toString();
|
||||
*
|
||||
* // Returns "ClassName{x=1}"
|
||||
* MoreObjects.toStringHelper(this)
|
||||
* .omitNullValues()
|
||||
* .add("x", 1)
|
||||
* .add("y", null)
|
||||
* .toString();
|
||||
* }</pre>
|
||||
*
|
||||
* <p>Note that in GWT, class names are often obfuscated.
|
||||
*
|
||||
* @param self the object to generate the string for (typically {@code this}), used only for its
|
||||
* class name
|
||||
* @since 18.0 (since 2.0 as {@code Objects.toStringHelper()}).
|
||||
*/
|
||||
public static ToStringHelper toStringHelper(Object self) {
|
||||
return new ToStringHelper(self.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link ToStringHelper} in the same manner as {@link
|
||||
* #toStringHelper(Object)}, but using the simple name of {@code clazz} instead of using an
|
||||
* instance's {@link Object#getClass()}.
|
||||
*
|
||||
* <p>Note that in GWT, class names are often obfuscated.
|
||||
*
|
||||
* @param clazz the {@link Class} of the instance
|
||||
* @since 18.0 (since 7.0 as {@code Objects.toStringHelper()}).
|
||||
*/
|
||||
public static ToStringHelper toStringHelper(Class<?> clazz) {
|
||||
return new ToStringHelper(clazz.getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link ToStringHelper} in the same manner as {@link
|
||||
* #toStringHelper(Object)}, but using {@code className} instead of using an instance's {@link
|
||||
* Object#getClass()}.
|
||||
*
|
||||
* @param className the name of the instance type
|
||||
* @since 18.0 (since 7.0 as {@code Objects.toStringHelper()}).
|
||||
*/
|
||||
public static ToStringHelper toStringHelper(String className) {
|
||||
return new ToStringHelper(className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Support class for {@link MoreObjects#toStringHelper}.
|
||||
*
|
||||
* @author Jason Lee
|
||||
* @since 18.0 (since 2.0 as {@code Objects.ToStringHelper}).
|
||||
*/
|
||||
public static final class ToStringHelper {
|
||||
private final String className;
|
||||
private final ValueHolder holderHead = new ValueHolder();
|
||||
private ValueHolder holderTail = holderHead;
|
||||
private boolean omitNullValues = false;
|
||||
|
||||
/** Use {@link MoreObjects#toStringHelper(Object)} to create an instance. */
|
||||
private ToStringHelper(String className) {
|
||||
this.className = checkNotNull(className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link ToStringHelper} so {@link #toString()} will ignore properties with null
|
||||
* value. The order of calling this method, relative to the {@code add()}/{@code addValue()}
|
||||
* methods, is not significant.
|
||||
*
|
||||
* @since 18.0 (since 12.0 as {@code Objects.ToStringHelper.omitNullValues()}).
|
||||
*/
|
||||
public ToStringHelper omitNullValues() {
|
||||
omitNullValues = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a name/value pair to the formatted output in {@code name=value} format. If {@code value}
|
||||
* is {@code null}, the string {@code "null"} is used, unless {@link #omitNullValues()} is
|
||||
* called, in which case this name/value pair will not be added.
|
||||
*/
|
||||
public ToStringHelper add(String name, Object value) {
|
||||
return addHolder(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a name/value pair to the formatted output in {@code name=value} format.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}).
|
||||
*/
|
||||
public ToStringHelper add(String name, boolean value) {
|
||||
return addHolder(name, String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a name/value pair to the formatted output in {@code name=value} format.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}).
|
||||
*/
|
||||
public ToStringHelper add(String name, char value) {
|
||||
return addHolder(name, String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a name/value pair to the formatted output in {@code name=value} format.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}).
|
||||
*/
|
||||
public ToStringHelper add(String name, double value) {
|
||||
return addHolder(name, String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a name/value pair to the formatted output in {@code name=value} format.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}).
|
||||
*/
|
||||
public ToStringHelper add(String name, float value) {
|
||||
return addHolder(name, String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a name/value pair to the formatted output in {@code name=value} format.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}).
|
||||
*/
|
||||
public ToStringHelper add(String name, int value) {
|
||||
return addHolder(name, String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a name/value pair to the formatted output in {@code name=value} format.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}).
|
||||
*/
|
||||
public ToStringHelper add(String name, long value) {
|
||||
return addHolder(name, String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an unnamed value to the formatted output.
|
||||
*
|
||||
* <p>It is strongly encouraged to use {@link #add(String, Object)} instead and give value a
|
||||
* readable name.
|
||||
*/
|
||||
public ToStringHelper addValue(Object value) {
|
||||
return addHolder(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an unnamed value to the formatted output.
|
||||
*
|
||||
* <p>It is strongly encouraged to use {@link #add(String, boolean)} instead and give value a
|
||||
* readable name.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}).
|
||||
*/
|
||||
public ToStringHelper addValue(boolean value) {
|
||||
return addHolder(String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an unnamed value to the formatted output.
|
||||
*
|
||||
* <p>It is strongly encouraged to use {@link #add(String, char)} instead and give value a
|
||||
* readable name.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}).
|
||||
*/
|
||||
public ToStringHelper addValue(char value) {
|
||||
return addHolder(String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an unnamed value to the formatted output.
|
||||
*
|
||||
* <p>It is strongly encouraged to use {@link #add(String, double)} instead and give value a
|
||||
* readable name.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}).
|
||||
*/
|
||||
public ToStringHelper addValue(double value) {
|
||||
return addHolder(String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an unnamed value to the formatted output.
|
||||
*
|
||||
* <p>It is strongly encouraged to use {@link #add(String, float)} instead and give value a
|
||||
* readable name.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}).
|
||||
*/
|
||||
public ToStringHelper addValue(float value) {
|
||||
return addHolder(String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an unnamed value to the formatted output.
|
||||
*
|
||||
* <p>It is strongly encouraged to use {@link #add(String, int)} instead and give value a
|
||||
* readable name.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}).
|
||||
*/
|
||||
public ToStringHelper addValue(int value) {
|
||||
return addHolder(String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an unnamed value to the formatted output.
|
||||
*
|
||||
* <p>It is strongly encouraged to use {@link #add(String, long)} instead and give value a
|
||||
* readable name.
|
||||
*
|
||||
* @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}).
|
||||
*/
|
||||
public ToStringHelper addValue(long value) {
|
||||
return addHolder(String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string in the format specified by {@link MoreObjects#toStringHelper(Object)}.
|
||||
*
|
||||
* <p>After calling this method, you can keep adding more properties to later call toString()
|
||||
* again and get a more complete representation of the same object; but properties cannot be
|
||||
* removed, so this only allows limited reuse of the helper instance. The helper allows
|
||||
* duplication of properties (multiple name/value pairs with the same name can be added).
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
// create a copy to keep it consistent in case value changes
|
||||
boolean omitNullValuesSnapshot = omitNullValues;
|
||||
String nextSeparator = "";
|
||||
StringBuilder builder = new StringBuilder(32).append(className).append('{');
|
||||
for (ValueHolder valueHolder = holderHead.next;
|
||||
valueHolder != null;
|
||||
valueHolder = valueHolder.next) {
|
||||
Object value = valueHolder.value;
|
||||
if (!omitNullValuesSnapshot || value != null) {
|
||||
builder.append(nextSeparator);
|
||||
nextSeparator = ", ";
|
||||
|
||||
if (valueHolder.name != null) {
|
||||
builder.append(valueHolder.name).append('=');
|
||||
}
|
||||
if (value != null && value.getClass().isArray()) {
|
||||
Object[] objectArray = {value};
|
||||
String arrayString = Arrays.deepToString(objectArray);
|
||||
builder.append(arrayString, 1, arrayString.length() - 1);
|
||||
} else {
|
||||
builder.append(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.append('}').toString();
|
||||
}
|
||||
|
||||
private ValueHolder addHolder() {
|
||||
ValueHolder valueHolder = new ValueHolder();
|
||||
holderTail = holderTail.next = valueHolder;
|
||||
return valueHolder;
|
||||
}
|
||||
|
||||
private ToStringHelper addHolder(Object value) {
|
||||
ValueHolder valueHolder = addHolder();
|
||||
valueHolder.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
private ToStringHelper addHolder(String name, Object value) {
|
||||
ValueHolder valueHolder = addHolder();
|
||||
valueHolder.value = value;
|
||||
valueHolder.name = checkNotNull(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
private static final class ValueHolder {
|
||||
String name;
|
||||
Object value;
|
||||
ValueHolder next;
|
||||
}
|
||||
}
|
||||
|
||||
private MoreObjects() {}
|
||||
}
|
78
src/main/java/com/google/common/base/Objects.java
Normal file
78
src/main/java/com/google/common/base/Objects.java
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Helper functions that can operate on any {@code Object}.
|
||||
*
|
||||
* <p>See the Guava User Guide on <a
|
||||
* href="https://github.com/google/guava/wiki/CommonObjectUtilitiesExplained">writing {@code Object}
|
||||
* methods with {@code Objects}</a>.
|
||||
*
|
||||
* @author Laurence Gonsalves
|
||||
* @since 2.0
|
||||
*/
|
||||
@GwtCompatible
|
||||
public final class Objects extends ExtraObjectsMethodsForWeb {
|
||||
private Objects() {}
|
||||
|
||||
/**
|
||||
* Determines whether two possibly-null objects are equal. Returns:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@code true} if {@code a} and {@code b} are both null.
|
||||
* <li>{@code true} if {@code a} and {@code b} are both non-null and they are equal according to
|
||||
* {@link Object#equals(Object)}.
|
||||
* <li>{@code false} in all other situations.
|
||||
* </ul>
|
||||
*
|
||||
* <p>This assumes that any non-null objects passed to this function conform to the {@code
|
||||
* equals()} contract.
|
||||
*
|
||||
* <p><b>Note for Java 7 and later:</b> This method should be treated as deprecated; use {@link
|
||||
* java.util.Objects#equals} instead.
|
||||
*/
|
||||
public static boolean equal(Object a, Object b) {
|
||||
return a == b || (a != null && a.equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a hash code for multiple values. The hash code is generated by calling {@link
|
||||
* Arrays#hashCode(Object[])}. Note that array arguments to this method, with the exception of a
|
||||
* single Object array, do not get any special handling; their hash codes are based on identity
|
||||
* and not contents.
|
||||
*
|
||||
* <p>This is useful for implementing {@link Object#hashCode()}. For example, in an object that
|
||||
* has three properties, {@code x}, {@code y}, and {@code z}, one could write:
|
||||
*
|
||||
* <pre>{@code
|
||||
* public int hashCode() {
|
||||
* return Objects.hashCode(getX(), getY(), getZ());
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p><b>Warning:</b> When a single object is supplied, the returned hash code does not equal the
|
||||
* hash code of that object.
|
||||
*
|
||||
* <p><b>Note for Java 7 and later:</b> This method should be treated as deprecated; use {@link
|
||||
* java.util.Objects#hash} instead.
|
||||
*/
|
||||
public static int hashCode(Object ... objects) {
|
||||
return Arrays.hashCode(objects);
|
||||
}
|
||||
}
|
356
src/main/java/com/google/common/base/Optional.java
Normal file
356
src/main/java/com/google/common/base/Optional.java
Normal file
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* An immutable object that may contain a non-null reference to another object. Each instance of
|
||||
* this type either contains a non-null reference, or contains nothing (in which case we say that
|
||||
* the reference is "absent"); it is never said to "contain {@code null}".
|
||||
*
|
||||
* <p>A non-null {@code Optional<T>} reference can be used as a replacement for a nullable {@code T}
|
||||
* reference. It allows you to represent "a {@code T} that must be present" and a "a {@code T} that
|
||||
* might be absent" as two distinct types in your program, which can aid clarity.
|
||||
*
|
||||
* <p>Some uses of this class include
|
||||
*
|
||||
* <ul>
|
||||
* <li>As a method return type, as an alternative to returning {@code null} to indicate that no
|
||||
* value was available
|
||||
* <li>To distinguish between "unknown" (for example, not present in a map) and "known to have no
|
||||
* value" (present in the map, with value {@code Optional.absent()})
|
||||
* <li>To wrap nullable references for storage in a collection that does not support {@code null}
|
||||
* (though there are <a
|
||||
* href="https://github.com/google/guava/wiki/LivingWithNullHostileCollections">several other
|
||||
* approaches to this</a> that should be considered first)
|
||||
* </ul>
|
||||
*
|
||||
* <p>A common alternative to using this class is to find or create a suitable <a
|
||||
* href="http://en.wikipedia.org/wiki/Null_Object_pattern">null object</a> for the type in question.
|
||||
*
|
||||
* <p>This class is not intended as a direct analogue of any existing "option" or "maybe" construct
|
||||
* from other programming environments, though it may bear some similarities.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional} (JDK 8 and higher):</b> A new {@code Optional}
|
||||
* class was added for Java 8. The two classes are extremely similar, but incompatible (they cannot
|
||||
* share a common supertype). <i>All</i> known differences are listed either here or with the
|
||||
* relevant methods below.
|
||||
*
|
||||
* <ul>
|
||||
* <li>This class is serializable; {@code java.util.Optional} is not.
|
||||
* <li>{@code java.util.Optional} has the additional methods {@code ifPresent}, {@code filter},
|
||||
* {@code flatMap}, and {@code orElseThrow}.
|
||||
* <li>{@code java.util} offers the primitive-specialized versions {@code OptionalInt}, {@code
|
||||
* OptionalLong} and {@code OptionalDouble}, the use of which is recommended; Guava does not
|
||||
* have these.
|
||||
* </ul>
|
||||
*
|
||||
* <p><b>There are no plans to deprecate this class in the foreseeable future.</b> However, we do
|
||||
* gently recommend that you prefer the new, standard Java class whenever possible.
|
||||
*
|
||||
* <p>See the Guava User Guide article on <a
|
||||
* href="https://github.com/google/guava/wiki/UsingAndAvoidingNullExplained#optional">using {@code
|
||||
* Optional}</a>.
|
||||
*
|
||||
* @param <T> the type of instance that can be contained. {@code Optional} is naturally covariant on
|
||||
* this type, so it is safe to cast an {@code Optional<T>} to {@code Optional<S>} for any
|
||||
* supertype {@code S} of {@code T}.
|
||||
* @author Kurt Alfred Kluever
|
||||
* @author Kevin Bourrillion
|
||||
* @since 10.0
|
||||
*/
|
||||
@GwtCompatible(serializable = true)
|
||||
public abstract class Optional<T> implements Serializable {
|
||||
/**
|
||||
* Returns an {@code Optional} instance with no contained reference.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is equivalent to Java 8's
|
||||
* {@code Optional.empty}.
|
||||
*/
|
||||
public static <T> Optional<T> absent() {
|
||||
return Absent.withType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code Optional} instance containing the given non-null reference. To have {@code
|
||||
* null} treated as {@link #absent}, use {@link #fromNullable} instead.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> no differences.
|
||||
*
|
||||
* @throws NullPointerException if {@code reference} is null
|
||||
*/
|
||||
public static <T> Optional<T> of(T reference) {
|
||||
return new Present<T>(checkNotNull(reference));
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@code nullableReference} is non-null, returns an {@code Optional} instance containing that
|
||||
* reference; otherwise returns {@link Optional#absent}.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is equivalent to Java 8's
|
||||
* {@code Optional.ofNullable}.
|
||||
*/
|
||||
public static <T> Optional<T> fromNullable(T nullableReference) {
|
||||
return (nullableReference == null) ? Optional.<T>absent() : new Present<T>(nullableReference);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the equivalent {@code com.google.common.base.Optional} value to the given {@code
|
||||
* java.util.Optional}, or {@code null} if the argument is null.
|
||||
*
|
||||
* @since 21.0
|
||||
*/
|
||||
public static <T> Optional<T> fromJavaUtil(
|
||||
java.util.Optional<T> javaUtilOptional) {
|
||||
return (javaUtilOptional == null) ? null : fromNullable(javaUtilOptional.orElse(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the equivalent {@code java.util.Optional} value to the given {@code
|
||||
* com.google.common.base.Optional}, or {@code null} if the argument is null.
|
||||
*
|
||||
* <p>If {@code googleOptional} is known to be non-null, use {@code googleOptional.toJavaUtil()}
|
||||
* instead.
|
||||
*
|
||||
* <p>Unfortunately, the method reference {@code Optional::toJavaUtil} will not work, because it
|
||||
* could refer to either the static or instance version of this method. Write out the lambda
|
||||
* expression {@code o -> Optional.toJavaUtil(o)} instead.
|
||||
*
|
||||
* @since 21.0
|
||||
*/
|
||||
public static <T> java.util.Optional<T> toJavaUtil(
|
||||
Optional<T> googleOptional) {
|
||||
return googleOptional == null ? null : googleOptional.toJavaUtil();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the equivalent {@code java.util.Optional} value to this optional.
|
||||
*
|
||||
* <p>Unfortunately, the method reference {@code Optional::toJavaUtil} will not work, because it
|
||||
* could refer to either the static or instance version of this method. Write out the lambda
|
||||
* expression {@code o -> o.toJavaUtil()} instead.
|
||||
*
|
||||
* @since 21.0
|
||||
*/
|
||||
public java.util.Optional<T> toJavaUtil() {
|
||||
return java.util.Optional.ofNullable(orNull());
|
||||
}
|
||||
|
||||
Optional() {}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this holder contains a (non-null) instance.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> no differences.
|
||||
*/
|
||||
public abstract boolean isPresent();
|
||||
|
||||
/**
|
||||
* Returns the contained instance, which must be present. If the instance might be absent, use
|
||||
* {@link #or(Object)} or {@link #orNull} instead.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> when the value is absent, this method
|
||||
* throws {@link IllegalStateException}, whereas the Java 8 counterpart throws {@link
|
||||
* java.util.NoSuchElementException NoSuchElementException}.
|
||||
*
|
||||
* @throws IllegalStateException if the instance is absent ({@link #isPresent} returns {@code
|
||||
* false}); depending on this <i>specific</i> exception type (over the more general {@link
|
||||
* RuntimeException}) is discouraged
|
||||
*/
|
||||
public abstract T get();
|
||||
|
||||
/**
|
||||
* Returns the contained instance if it is present; {@code defaultValue} otherwise. If no default
|
||||
* value should be required because the instance is known to be present, use {@link #get()}
|
||||
* instead. For a default value of {@code null}, use {@link #orNull}.
|
||||
*
|
||||
* <p>Note about generics: The signature {@code public T or(T defaultValue)} is overly
|
||||
* restrictive. However, the ideal signature, {@code public <S super T> S or(S)}, is not legal
|
||||
* Java. As a result, some sensible operations involving subtypes are compile errors:
|
||||
*
|
||||
* <pre>{@code
|
||||
* Optional<Integer> optionalInt = getSomeOptionalInt();
|
||||
* Number value = optionalInt.or(0.5); // error
|
||||
*
|
||||
* FluentIterable<? extends Number> numbers = getSomeNumbers();
|
||||
* Optional<? extends Number> first = numbers.first();
|
||||
* Number value = first.or(0.5); // error
|
||||
* }</pre>
|
||||
*
|
||||
* <p>As a workaround, it is always safe to cast an {@code Optional<? extends T>} to {@code
|
||||
* Optional<T>}. Casting either of the above example {@code Optional} instances to {@code
|
||||
* Optional<Number>} (where {@code Number} is the desired output type) solves the problem:
|
||||
*
|
||||
* <pre>{@code
|
||||
* Optional<Number> optionalInt = (Optional) getSomeOptionalInt();
|
||||
* Number value = optionalInt.or(0.5); // fine
|
||||
*
|
||||
* FluentIterable<? extends Number> numbers = getSomeNumbers();
|
||||
* Optional<Number> first = (Optional) numbers.first();
|
||||
* Number value = first.or(0.5); // fine
|
||||
* }</pre>
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is similar to Java 8's {@code
|
||||
* Optional.orElse}, but will not accept {@code null} as a {@code defaultValue} ({@link #orNull}
|
||||
* must be used instead). As a result, the value returned by this method is guaranteed non-null,
|
||||
* which is not the case for the {@code java.util} equivalent.
|
||||
*/
|
||||
public abstract T or(T defaultValue);
|
||||
|
||||
/**
|
||||
* Returns this {@code Optional} if it has a value present; {@code secondChoice} otherwise.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> this method has no equivalent in Java 8's
|
||||
* {@code Optional} class; write {@code thisOptional.isPresent() ? thisOptional : secondChoice}
|
||||
* instead.
|
||||
*/
|
||||
public abstract Optional<T> or(Optional<? extends T> secondChoice);
|
||||
|
||||
/**
|
||||
* Returns the contained instance if it is present; {@code supplier.get()} otherwise.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is similar to Java 8's {@code
|
||||
* Optional.orElseGet}, except when {@code supplier} returns {@code null}. In this case this
|
||||
* method throws an exception, whereas the Java 8 method returns the {@code null} to the caller.
|
||||
*
|
||||
* @throws NullPointerException if this optional's value is absent and the supplier returns {@code
|
||||
* null}
|
||||
*/
|
||||
@Beta
|
||||
public abstract T or(Supplier<? extends T> supplier);
|
||||
|
||||
/**
|
||||
* Returns the contained instance if it is present; {@code null} otherwise. If the instance is
|
||||
* known to be present, use {@link #get()} instead.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is equivalent to Java 8's
|
||||
* {@code Optional.orElse(null)}.
|
||||
*/
|
||||
public abstract T orNull();
|
||||
|
||||
/**
|
||||
* Returns an immutable singleton {@link Set} whose only element is the contained instance if it
|
||||
* is present; an empty immutable {@link Set} otherwise.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> this method has no equivalent in Java 8's
|
||||
* {@code Optional} class. However, this common usage:
|
||||
*
|
||||
* <pre>{@code
|
||||
* for (Foo foo : possibleFoo.asSet()) {
|
||||
* doSomethingWith(foo);
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* ... can be replaced with:
|
||||
*
|
||||
* <pre>{@code
|
||||
* possibleFoo.ifPresent(foo -> doSomethingWith(foo));
|
||||
* }</pre>
|
||||
*
|
||||
* <p><b>Java 9 users:</b> some use cases can be written with calls to {@code optional.stream()}.
|
||||
*
|
||||
* @since 11.0
|
||||
*/
|
||||
public abstract Set<T> asSet();
|
||||
|
||||
/**
|
||||
* If the instance is present, it is transformed with the given {@link Function}; otherwise,
|
||||
* {@link Optional#absent} is returned.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is similar to Java 8's {@code
|
||||
* Optional.map}, except when {@code function} returns {@code null}. In this case this method
|
||||
* throws an exception, whereas the Java 8 method returns {@code Optional.absent()}.
|
||||
*
|
||||
* @throws NullPointerException if the function returns {@code null}
|
||||
* @since 12.0
|
||||
*/
|
||||
public abstract <V> Optional<V> transform(Function<? super T, V> function);
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code object} is an {@code Optional} instance, and either the
|
||||
* contained references are {@linkplain Object#equals equal} to each other or both are absent.
|
||||
* Note that {@code Optional} instances of differing parameterized types can be equal.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> no differences.
|
||||
*/
|
||||
@Override
|
||||
public abstract boolean equals(Object object);
|
||||
|
||||
/**
|
||||
* Returns a hash code for this instance.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> this class leaves the specific choice of
|
||||
* hash code unspecified, unlike the Java 8 equivalent.
|
||||
*/
|
||||
@Override
|
||||
public abstract int hashCode();
|
||||
|
||||
/**
|
||||
* Returns a string representation for this instance.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> this class leaves the specific string
|
||||
* representation unspecified, unlike the Java 8 equivalent.
|
||||
*/
|
||||
@Override
|
||||
public abstract String toString();
|
||||
|
||||
/**
|
||||
* Returns the value of each present instance from the supplied {@code optionals}, in order,
|
||||
* skipping over occurrences of {@link Optional#absent}. Iterators are unmodifiable and are
|
||||
* evaluated lazily.
|
||||
*
|
||||
* <p><b>Comparison to {@code java.util.Optional}:</b> this method has no equivalent in Java 8's
|
||||
* {@code Optional} class; use {@code
|
||||
* optionals.stream().filter(Optional::isPresent).map(Optional::get)} instead.
|
||||
*
|
||||
* <p><b>Java 9 users:</b> use {@code optionals.stream().flatMap(Optional::stream)} instead.
|
||||
*
|
||||
* @since 11.0 (generics widened in 13.0)
|
||||
*/
|
||||
@Beta
|
||||
public static <T> Iterable<T> presentInstances(
|
||||
final Iterable<? extends Optional<? extends T>> optionals) {
|
||||
checkNotNull(optionals);
|
||||
return new Iterable<T>() {
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new AbstractIterator<T>() {
|
||||
private final Iterator<? extends Optional<? extends T>> iterator =
|
||||
checkNotNull(optionals.iterator());
|
||||
|
||||
@Override
|
||||
protected T computeNext() {
|
||||
while (iterator.hasNext()) {
|
||||
Optional<? extends T> optional = iterator.next();
|
||||
if (optional.isPresent()) {
|
||||
return optional.get();
|
||||
}
|
||||
}
|
||||
return endOfData();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
|
||||
@GwtCompatible(serializable = true)
|
||||
final class PairwiseEquivalence<T> extends Equivalence<Iterable<T>> implements Serializable {
|
||||
|
||||
final Equivalence<? super T> elementEquivalence;
|
||||
|
||||
PairwiseEquivalence(Equivalence<? super T> elementEquivalence) {
|
||||
this.elementEquivalence = Preconditions.checkNotNull(elementEquivalence);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doEquivalent(Iterable<T> iterableA, Iterable<T> iterableB) {
|
||||
Iterator<T> iteratorA = iterableA.iterator();
|
||||
Iterator<T> iteratorB = iterableB.iterator();
|
||||
|
||||
while (iteratorA.hasNext() && iteratorB.hasNext()) {
|
||||
if (!elementEquivalence.equivalent(iteratorA.next(), iteratorB.next())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !iteratorA.hasNext() && !iteratorB.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doHash(Iterable<T> iterable) {
|
||||
int hash = 78721;
|
||||
for (T element : iterable) {
|
||||
hash = hash * 24943 + elementEquivalence.hash(element);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof PairwiseEquivalence) {
|
||||
PairwiseEquivalence<?> that = (PairwiseEquivalence<?>) object;
|
||||
return this.elementEquivalence.equals(that.elementEquivalence);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return elementEquivalence.hashCode() ^ 0x46a3eb07;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return elementEquivalence + ".pairwise()";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
}
|
38
src/main/java/com/google/common/base/PatternCompiler.java
Normal file
38
src/main/java/com/google/common/base/PatternCompiler.java
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
|
||||
/**
|
||||
* Pluggable interface for compiling a regex pattern. By default this package uses the {@code
|
||||
* java.util.regex} library, but an alternate implementation can be supplied using the {@link
|
||||
* java.util.ServiceLoader} mechanism.
|
||||
*/
|
||||
@GwtIncompatible
|
||||
interface PatternCompiler {
|
||||
/**
|
||||
* Compiles the given pattern.
|
||||
*
|
||||
* @throws IllegalArgumentException if the pattern is invalid
|
||||
*/
|
||||
CommonPattern compile(String pattern);
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the regex implementation behaves like Perl -- notably, by supporting
|
||||
* possessive quantifiers but also being susceptible to catastrophic backtracking.
|
||||
*/
|
||||
boolean isPcreLike();
|
||||
}
|
121
src/main/java/com/google/common/base/Platform.java
Normal file
121
src/main/java/com/google/common/base/Platform.java
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (C) 2009 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Strings.lenientFormat;
|
||||
import static java.lang.Boolean.parseBoolean;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Locale;
|
||||
import java.util.ServiceConfigurationError;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Methods factored out so that they can be emulated differently in GWT.
|
||||
*
|
||||
* @author Jesse Wilson
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
final class Platform {
|
||||
private static final Logger logger = Logger.getLogger(Platform.class.getName());
|
||||
private static final PatternCompiler patternCompiler = loadPatternCompiler();
|
||||
|
||||
private Platform() {}
|
||||
|
||||
/** Calls {@link System#nanoTime()}. */
|
||||
@SuppressWarnings("GoodTime") // reading system time without TimeSource
|
||||
static long systemNanoTime() {
|
||||
return System.nanoTime();
|
||||
}
|
||||
|
||||
static CharMatcher precomputeCharMatcher(CharMatcher matcher) {
|
||||
return matcher.precomputedInternal();
|
||||
}
|
||||
|
||||
static <T extends Enum<T>> Optional<T> getEnumIfPresent(Class<T> enumClass, String value) {
|
||||
WeakReference<? extends Enum<?>> ref = Enums.getEnumConstants(enumClass).get(value);
|
||||
return ref == null ? Optional.<T>absent() : Optional.of(enumClass.cast(ref.get()));
|
||||
}
|
||||
|
||||
static String formatCompact4Digits(double value) {
|
||||
return String.format(Locale.ROOT, "%.4g", value);
|
||||
}
|
||||
|
||||
static boolean stringIsNullOrEmpty(String string) {
|
||||
return string == null || string.isEmpty();
|
||||
}
|
||||
|
||||
static String nullToEmpty(String string) {
|
||||
return (string == null) ? "" : string;
|
||||
}
|
||||
|
||||
static String emptyToNull(String string) {
|
||||
return stringIsNullOrEmpty(string) ? null : string;
|
||||
}
|
||||
|
||||
static CommonPattern compilePattern(String pattern) {
|
||||
Preconditions.checkNotNull(pattern);
|
||||
return patternCompiler.compile(pattern);
|
||||
}
|
||||
|
||||
static boolean patternCompilerIsPcreLike() {
|
||||
return patternCompiler.isPcreLike();
|
||||
}
|
||||
|
||||
private static PatternCompiler loadPatternCompiler() {
|
||||
return new JdkPatternCompiler();
|
||||
}
|
||||
|
||||
private static void logPatternCompilerError(ServiceConfigurationError e) {
|
||||
logger.log(Level.WARNING, "Error loading regex compiler, falling back to next option", e);
|
||||
}
|
||||
|
||||
private static final class JdkPatternCompiler implements PatternCompiler {
|
||||
@Override
|
||||
public CommonPattern compile(String pattern) {
|
||||
return new JdkPattern(Pattern.compile(pattern));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPcreLike() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String GWT_RPC_PROPERTY_NAME = "guava.gwt.emergency_reenable_rpc";
|
||||
|
||||
static void checkGwtRpcEnabled() {
|
||||
if (!parseBoolean(System.getProperty(GWT_RPC_PROPERTY_NAME, "true"))) {
|
||||
throw new UnsupportedOperationException(
|
||||
lenientFormat(
|
||||
"We are removing GWT-RPC support for Guava types. You can temporarily reenable"
|
||||
+ " support by setting the system property %s to true. For more about system"
|
||||
+ " properties, see %s. For more about Guava's GWT-RPC support, see %s.",
|
||||
GWT_RPC_PROPERTY_NAME,
|
||||
"https://stackoverflow.com/q/5189914/28465",
|
||||
"https://groups.google.com/d/msg/guava-announce/zHZTFg7YF3o/rQNnwdHeEwAJ"));
|
||||
}
|
||||
logger.log(
|
||||
java.util.logging.Level.WARNING,
|
||||
"In January 2020, we will remove GWT-RPC support for Guava types. You are seeing this"
|
||||
+ " warning because you are sending a Guava type over GWT-RPC, which will break. You"
|
||||
+ " can identify which type by looking at the class name in the attached stack trace.",
|
||||
new Throwable());
|
||||
|
||||
}
|
||||
}
|
1404
src/main/java/com/google/common/base/Preconditions.java
Normal file
1404
src/main/java/com/google/common/base/Preconditions.java
Normal file
File diff suppressed because it is too large
Load diff
78
src/main/java/com/google/common/base/Predicate.java
Normal file
78
src/main/java/com/google/common/base/Predicate.java
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* Legacy version of {@link java.util.function.Predicate java.util.function.Predicate}. Determines a
|
||||
* true or false value for a given input.
|
||||
*
|
||||
* <p>As this interface extends {@code java.util.function.Predicate}, an instance of this type may
|
||||
* be used as a {@code Predicate} directly. To use a {@code java.util.function.Predicate} where a
|
||||
* {@code com.google.common.base.Predicate} is expected, use the method reference {@code
|
||||
* predicate::test}.
|
||||
*
|
||||
* <p>This interface is now a legacy type. Use {@code java.util.function.Predicate} (or the
|
||||
* appropriate primitive specialization such as {@code IntPredicate}) instead whenever possible.
|
||||
* Otherwise, at least reduce <i>explicit</i> dependencies on this type by using lambda expressions
|
||||
* or method references instead of classes, leaving your code easier to migrate in the future.
|
||||
*
|
||||
* <p>The {@link Predicates} class provides common predicates and related utilities.
|
||||
*
|
||||
* <p>See the Guava User Guide article on <a
|
||||
* href="https://github.com/google/guava/wiki/FunctionalExplained">the use of {@code Predicate}</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 2.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@GwtCompatible
|
||||
public interface Predicate<T> extends java.util.function.Predicate<T> {
|
||||
/**
|
||||
* Returns the result of applying this predicate to {@code input} (Java 8 users, see notes in the
|
||||
* class documentation above). This method is <i>generally expected</i>, but not absolutely
|
||||
* required, to have the following properties:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Its execution does not cause any observable side effects.
|
||||
* <li>The computation is <i>consistent with equals</i>; that is, {@link Objects#equal
|
||||
* Objects.equal}{@code (a, b)} implies that {@code predicate.apply(a) ==
|
||||
* predicate.apply(b))}.
|
||||
* </ul>
|
||||
*
|
||||
* @throws NullPointerException if {@code input} is null and this predicate does not accept null
|
||||
* arguments
|
||||
*/
|
||||
boolean apply(T input);
|
||||
|
||||
/**
|
||||
* Indicates whether another object is equal to this predicate.
|
||||
*
|
||||
* <p>Most implementations will have no reason to override the behavior of {@link Object#equals}.
|
||||
* However, an implementation may also choose to return {@code true} whenever {@code object} is a
|
||||
* {@link Predicate} that it considers <i>interchangeable</i> with this one. "Interchangeable"
|
||||
* <i>typically</i> means that {@code this.apply(t) == that.apply(t)} for all {@code t} of type
|
||||
* {@code T}). Note that a {@code false} result from this method does not imply that the
|
||||
* predicates are known <i>not</i> to be interchangeable.
|
||||
*/
|
||||
@Override
|
||||
boolean equals(Object object);
|
||||
|
||||
@Override
|
||||
default boolean test(T input) {
|
||||
return apply(input);
|
||||
}
|
||||
}
|
702
src/main/java/com/google/common/base/Predicates.java
Normal file
702
src/main/java/com/google/common/base/Predicates.java
Normal file
|
@ -0,0 +1,702 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.common.base;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code Predicate} instances.
|
||||
*
|
||||
* <p>All methods return serializable predicates as long as they're given serializable parameters.
|
||||
*
|
||||
* <p>See the Guava User Guide article on <a
|
||||
* href="https://github.com/google/guava/wiki/FunctionalExplained">the use of {@code Predicate}</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 2.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class Predicates {
|
||||
private Predicates() {}
|
||||
|
||||
// TODO(kevinb): considering having these implement a VisitablePredicate
|
||||
// interface which specifies an accept(PredicateVisitor) method.
|
||||
|
||||
/** Returns a predicate that always evaluates to {@code true}. */
|
||||
@GwtCompatible(serializable = true)
|
||||
public static <T> Predicate<T> alwaysTrue() {
|
||||
return ObjectPredicate.ALWAYS_TRUE.withNarrowedType();
|
||||
}
|
||||
|
||||
/** Returns a predicate that always evaluates to {@code false}. */
|
||||
@GwtCompatible(serializable = true)
|
||||
public static <T> Predicate<T> alwaysFalse() {
|
||||
return ObjectPredicate.ALWAYS_FALSE.withNarrowedType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if the object reference being tested is
|
||||
* null.
|
||||
*/
|
||||
@GwtCompatible(serializable = true)
|
||||
public static <T> Predicate<T> isNull() {
|
||||
return ObjectPredicate.IS_NULL.withNarrowedType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if the object reference being tested is not
|
||||
* null.
|
||||
*/
|
||||
@GwtCompatible(serializable = true)
|
||||
public static <T> Predicate<T> notNull() {
|
||||
return ObjectPredicate.NOT_NULL.withNarrowedType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if the given predicate evaluates to {@code
|
||||
* false}.
|
||||
*/
|
||||
public static <T> Predicate<T> not(Predicate<T> predicate) {
|
||||
return new NotPredicate<T>(predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if each of its components evaluates to
|
||||
* {@code true}. The components are evaluated in order, and evaluation will be "short-circuited"
|
||||
* as soon as a false predicate is found. It defensively copies the iterable passed in, so future
|
||||
* changes to it won't alter the behavior of this predicate. If {@code components} is empty, the
|
||||
* returned predicate will always evaluate to {@code true}.
|
||||
*/
|
||||
public static <T> Predicate<T> and(Iterable<? extends Predicate<? super T>> components) {
|
||||
return new AndPredicate<T>(defensiveCopy(components));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if each of its components evaluates to
|
||||
* {@code true}. The components are evaluated in order, and evaluation will be "short-circuited"
|
||||
* as soon as a false predicate is found. It defensively copies the array passed in, so future
|
||||
* changes to it won't alter the behavior of this predicate. If {@code components} is empty, the
|
||||
* returned predicate will always evaluate to {@code true}.
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <T> Predicate<T> and(Predicate<? super T>... components) {
|
||||
return new AndPredicate<T>(defensiveCopy(components));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if both of its components evaluate to {@code
|
||||
* true}. The components are evaluated in order, and evaluation will be "short-circuited" as soon
|
||||
* as a false predicate is found.
|
||||
*/
|
||||
public static <T> Predicate<T> and(Predicate<? super T> first, Predicate<? super T> second) {
|
||||
return new AndPredicate<T>(Predicates.<T>asList(checkNotNull(first), checkNotNull(second)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if any one of its components evaluates to
|
||||
* {@code true}. The components are evaluated in order, and evaluation will be "short-circuited"
|
||||
* as soon as a true predicate is found. It defensively copies the iterable passed in, so future
|
||||
* changes to it won't alter the behavior of this predicate. If {@code components} is empty, the
|
||||
* returned predicate will always evaluate to {@code false}.
|
||||
*/
|
||||
public static <T> Predicate<T> or(Iterable<? extends Predicate<? super T>> components) {
|
||||
return new OrPredicate<T>(defensiveCopy(components));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if any one of its components evaluates to
|
||||
* {@code true}. The components are evaluated in order, and evaluation will be "short-circuited"
|
||||
* as soon as a true predicate is found. It defensively copies the array passed in, so future
|
||||
* changes to it won't alter the behavior of this predicate. If {@code components} is empty, the
|
||||
* returned predicate will always evaluate to {@code false}.
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <T> Predicate<T> or(Predicate<? super T>... components) {
|
||||
return new OrPredicate<T>(defensiveCopy(components));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if either of its components evaluates to
|
||||
* {@code true}. The components are evaluated in order, and evaluation will be "short-circuited"
|
||||
* as soon as a true predicate is found.
|
||||
*/
|
||||
public static <T> Predicate<T> or(Predicate<? super T> first, Predicate<? super T> second) {
|
||||
return new OrPredicate<T>(Predicates.<T>asList(checkNotNull(first), checkNotNull(second)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if the object being tested {@code equals()}
|
||||
* the given target or both are null.
|
||||
*/
|
||||
public static <T> Predicate<T> equalTo(T target) {
|
||||
return (target == null) ? Predicates.<T>isNull() : new IsEqualToPredicate<T>(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if the object being tested is an instance of
|
||||
* the given class. If the object being tested is {@code null} this predicate evaluates to {@code
|
||||
* false}.
|
||||
*
|
||||
* <p>If you want to filter an {@code Iterable} to narrow its type, consider using {@link
|
||||
* com.google.common.collect.Iterables#filter(Iterable, Class)} in preference.
|
||||
*
|
||||
* <p><b>Warning:</b> contrary to the typical assumptions about predicates (as documented at
|
||||
* {@link Predicate#apply}), the returned predicate may not be <i>consistent with equals</i>. For
|
||||
* example, {@code instanceOf(ArrayList.class)} will yield different results for the two equal
|
||||
* instances {@code Lists.newArrayList(1)} and {@code Arrays.asList(1)}.
|
||||
*/
|
||||
@GwtIncompatible // Class.isInstance
|
||||
public static Predicate<Object> instanceOf(Class<?> clazz) {
|
||||
return new InstanceOfPredicate(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if the class being tested is assignable to
|
||||
* (is a subtype of) {@code clazz}. Example:
|
||||
*
|
||||
* <pre>{@code
|
||||
* List<Class<?>> classes = Arrays.asList(
|
||||
* Object.class, String.class, Number.class, Long.class);
|
||||
* return Iterables.filter(classes, subtypeOf(Number.class));
|
||||
* }</pre>
|
||||
*
|
||||
* The code above returns an iterable containing {@code Number.class} and {@code Long.class}.
|
||||
*
|
||||
* @since 20.0 (since 10.0 under the incorrect name {@code assignableFrom})
|
||||
*/
|
||||
@GwtIncompatible // Class.isAssignableFrom
|
||||
@Beta
|
||||
public static Predicate<Class<?>> subtypeOf(Class<?> clazz) {
|
||||
return new SubtypeOfPredicate(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if the object reference being tested is a
|
||||
* member of the given collection. It does not defensively copy the collection passed in, so
|
||||
* future changes to it will alter the behavior of the predicate.
|
||||
*
|
||||
* <p>This method can technically accept any {@code Collection<?>}, but using a typed collection
|
||||
* helps prevent bugs. This approach doesn't block any potential users since it is always possible
|
||||
* to use {@code Predicates.<Object>in()}.
|
||||
*
|
||||
* @param target the collection that may contain the function input
|
||||
*/
|
||||
public static <T> Predicate<T> in(Collection<? extends T> target) {
|
||||
return new InPredicate<T>(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the composition of a function and a predicate. For every {@code x}, the generated
|
||||
* predicate returns {@code predicate(function(x))}.
|
||||
*
|
||||
* @return the composition of the provided function and predicate
|
||||
*/
|
||||
public static <A, B> Predicate<A> compose(
|
||||
Predicate<B> predicate, Function<A, ? extends B> function) {
|
||||
return new CompositionPredicate<>(predicate, function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if the {@code CharSequence} being tested
|
||||
* contains any match for the given regular expression pattern. The test used is equivalent to
|
||||
* {@code Pattern.compile(pattern).matcher(arg).find()}
|
||||
*
|
||||
* @throws IllegalArgumentException if the pattern is invalid
|
||||
* @since 3.0
|
||||
*/
|
||||
@GwtIncompatible // Only used by other GWT-incompatible code.
|
||||
public static Predicate<CharSequence> containsPattern(String pattern) {
|
||||
return new ContainsPatternFromStringPredicate(pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that evaluates to {@code true} if the {@code CharSequence} being tested
|
||||
* contains any match for the given regular expression pattern. The test used is equivalent to
|
||||
* {@code pattern.matcher(arg).find()}
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
@GwtIncompatible(value = "java.util.regex.Pattern")
|
||||
public static Predicate<CharSequence> contains(Pattern pattern) {
|
||||
return new ContainsPatternPredicate(new JdkPattern(pattern));
|
||||
}
|
||||
|
||||
// End public API, begin private implementation classes.
|
||||
|
||||
// Package private for GWT serialization.
|
||||
enum ObjectPredicate implements Predicate<Object> {
|
||||
/** @see Predicates#alwaysTrue() */
|
||||
ALWAYS_TRUE {
|
||||
@Override
|
||||
public boolean apply(Object o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Predicates.alwaysTrue()";
|
||||
}
|
||||
},
|
||||
/** @see Predicates#alwaysFalse() */
|
||||
ALWAYS_FALSE {
|
||||
@Override
|
||||
public boolean apply(Object o |