clone of Guava 28.1

This commit is contained in:
Jörg Prante 2020-01-19 15:34:00 +01:00
commit 3ab350bb93
569 changed files with 162570 additions and 0 deletions

12
.gitignore vendored Normal file
View file

@ -0,0 +1,12 @@
/data
/work
/logs
/.idea
/target
.DS_Store
*.iml
/.settings
/.classpath
/.project
/.gradle
/build

3
.travis.yml Normal file
View file

@ -0,0 +1,3 @@
language: java
jdk:
- openjdk11

202
LICENSE.txt Normal file
View 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
View 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
View 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"
}
}
*/

View 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>

View 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
View file

@ -0,0 +1,3 @@
group = org.xbib
name = guava
version = 28.1

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View 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
View 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
View 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
View file

@ -0,0 +1 @@
rootProject.name = name

View 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 {}

View file

@ -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;
}

View file

@ -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 "";
}

View file

@ -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 {
}

View 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;
}

View 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();
}
}

View 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');
}
}

View 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));
}
}

File diff suppressed because it is too large Load diff

View 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.
*/
}

View 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();
}

View 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();
}
}

View 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&lt;Integer, String&gt;() {
* 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;
}
}

View 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;
}
}
}

View 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;
}
}

View 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;
}
}

View file

@ -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 {}

View file

@ -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();
}
}

View file

@ -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();
}

View file

@ -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);
}
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View 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);
}

View file

@ -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 + ")";
}
}

View 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;
}
}

View 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;
}

View 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];
}
}
};
}
}

View 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() {}
}

View 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);
}
}

View 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;
}

View file

@ -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;
}

View 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();
}

View 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());
}
}

File diff suppressed because it is too large Load diff

View 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);
}
}

View 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