Browse Source

REPORT-98514 feat:websocket cbb——移除third下socketio

feature/x
Rock 1 year ago
parent
commit
fc8ffd63c5
  1. 1
      base-third-project/base-third-step1/pom.xml
  2. 1
      base-third-project/base-third-step2/pom.xml
  3. 3
      build.third_step1-jdk11.gradle
  4. 3
      build.third_step1.gradle
  5. 4
      build.third_step2-jdk11.gradle
  6. 4
      build.third_step2.gradle
  7. 6
      fine-jodd/.gitignore
  8. 18
      fine-jodd/pom.xml
  9. 5
      fine-jodd/readme.md
  10. 43
      fine-jodd/src/main/java/com/fr/third/jodd/Jodd.java
  11. 188
      fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanCopy.java
  12. 55
      fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanException.java
  13. 150
      fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanProperty.java
  14. 60
      fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanTemplateParser.java
  15. 154
      fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanUtil.java
  16. 559
      fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanUtilBean.java
  17. 346
      fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanUtilUtil.java
  18. 194
      fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanVisitor.java
  19. 131
      fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanVisitorImplBase.java
  20. 83
      fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanWalker.java
  21. 29
      fine-jodd/src/main/java/com/fr/third/jodd/bean/package-info.java
  22. 166
      fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastBooleanBuffer.java
  23. 166
      fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastByteBuffer.java
  24. 211
      fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastCharBuffer.java
  25. 166
      fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastDoubleBuffer.java
  26. 165
      fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastFloatBuffer.java
  27. 166
      fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastIntBuffer.java
  28. 166
      fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastLongBuffer.java
  29. 165
      fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastShortBuffer.java
  30. 29
      fine-jodd/src/main/java/com/fr/third/jodd/buffer/package-info.java
  31. 344
      fine-jodd/src/main/java/com/fr/third/jodd/cache/AbstractCacheMap.java
  32. 108
      fine-jodd/src/main/java/com/fr/third/jodd/cache/Cache.java
  33. 89
      fine-jodd/src/main/java/com/fr/third/jodd/cache/FIFOCache.java
  34. 153
      fine-jodd/src/main/java/com/fr/third/jodd/cache/FileCache.java
  35. 82
      fine-jodd/src/main/java/com/fr/third/jodd/cache/FileLFUCache.java
  36. 81
      fine-jodd/src/main/java/com/fr/third/jodd/cache/FileLRUCache.java
  37. 111
      fine-jodd/src/main/java/com/fr/third/jodd/cache/LFUCache.java
  38. 103
      fine-jodd/src/main/java/com/fr/third/jodd/cache/LRUCache.java
  39. 96
      fine-jodd/src/main/java/com/fr/third/jodd/cache/NoCache.java
  40. 98
      fine-jodd/src/main/java/com/fr/third/jodd/cache/TimedCache.java
  41. 205
      fine-jodd/src/main/java/com/fr/third/jodd/cache/TypeCache.java
  42. 29
      fine-jodd/src/main/java/com/fr/third/jodd/cache/package-info.java
  43. 298
      fine-jodd/src/main/java/com/fr/third/jodd/chalk/Chalk.java
  44. 123
      fine-jodd/src/main/java/com/fr/third/jodd/chalk/Chalk256.java
  45. 29
      fine-jodd/src/main/java/com/fr/third/jodd/chalk/package-info.java
  46. 233
      fine-jodd/src/main/java/com/fr/third/jodd/cli/Cli.java
  47. 37
      fine-jodd/src/main/java/com/fr/third/jodd/cli/CliException.java
  48. 96
      fine-jodd/src/main/java/com/fr/third/jodd/cli/Option.java
  49. 84
      fine-jodd/src/main/java/com/fr/third/jodd/cli/Param.java
  50. 29
      fine-jodd/src/main/java/com/fr/third/jodd/cli/package-info.java
  51. 65
      fine-jodd/src/main/java/com/fr/third/jodd/core/JoddCore.java
  52. 29
      fine-jodd/src/main/java/com/fr/third/jodd/core/package-info.java
  53. 303
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/DateTimeStamp.java
  54. 1776
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTime.java
  55. 88
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTimeDefault.java
  56. 302
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/JStopWatch.java
  57. 337
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/JulianDateStamp.java
  58. 118
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/Period.java
  59. 398
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeUtil.java
  60. 75
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeZoneUtil.java
  61. 330
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/AbstractFormatter.java
  62. 170
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/Iso8601JdtFormatter.java
  63. 75
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormat.java
  64. 62
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormatter.java
  65. 29
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/package-info.java
  66. 29
      fine-jodd/src/main/java/com/fr/third/jodd/datetime/package-info.java
  67. 301
      fine-jodd/src/main/java/com/fr/third/jodd/exception/ExceptionUtil.java
  68. 212
      fine-jodd/src/main/java/com/fr/third/jodd/exception/UncheckedException.java
  69. 29
      fine-jodd/src/main/java/com/fr/third/jodd/exception/package-info.java
  70. 52
      fine-jodd/src/main/java/com/fr/third/jodd/inex/InExRuleMatcher.java
  71. 381
      fine-jodd/src/main/java/com/fr/third/jodd/inex/InExRules.java
  72. 29
      fine-jodd/src/main/java/com/fr/third/jodd/inex/package-info.java
  73. 86
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/CachingIntrospector.java
  74. 378
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassDescriptor.java
  75. 66
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassIntrospector.java
  76. 79
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/CtorDescriptor.java
  77. 113
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/Ctors.java
  78. 70
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/Descriptor.java
  79. 134
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/FieldDescriptor.java
  80. 130
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/Fields.java
  81. 94
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/Getter.java
  82. 43
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/Mapper.java
  83. 37
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/MapperFunction.java
  84. 57
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/MapperFunctionInstances.java
  85. 193
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/MethodDescriptor.java
  86. 53
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/MethodParamDescriptor.java
  87. 162
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/Methods.java
  88. 255
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/Properties.java
  89. 313
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/PropertyDescriptor.java
  90. 90
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/Setter.java
  91. 29
      fine-jodd/src/main/java/com/fr/third/jodd/introspector/package-info.java
  92. 121
      fine-jodd/src/main/java/com/fr/third/jodd/io/AppendableWriter.java
  93. 60
      fine-jodd/src/main/java/com/fr/third/jodd/io/CharBufferReader.java
  94. 146
      fine-jodd/src/main/java/com/fr/third/jodd/io/FastByteArrayOutputStream.java
  95. 134
      fine-jodd/src/main/java/com/fr/third/jodd/io/FastCharArrayWriter.java
  96. 1006
      fine-jodd/src/main/java/com/fr/third/jodd/io/FileNameUtil.java
  97. 1685
      fine-jodd/src/main/java/com/fr/third/jodd/io/FileUtil.java
  98. 194
      fine-jodd/src/main/java/com/fr/third/jodd/io/NetUtil.java
  99. 92
      fine-jodd/src/main/java/com/fr/third/jodd/io/PathUtil.java
  100. 125
      fine-jodd/src/main/java/com/fr/third/jodd/io/StreamGobbler.java
  101. Some files were not shown because too many files have changed in this diff Show More

1
base-third-project/base-third-step1/pom.xml

@ -30,7 +30,6 @@
<module>../../fine-jboss-transaction-api</module>
<module>../../fine-jgit</module>
<module>../../fine-jna</module>
<module>../../fine-jodd</module>
<module>../../fine-lookandfeel</module>
<module>../../fine-lz4</module>
<module>../../fine-org-dom4j</module>

1
base-third-project/base-third-step2/pom.xml

@ -20,7 +20,6 @@
<module>../../fine-jai</module>
<module>../../fine-kryo</module>
<module>../../fine-poi-old</module>
<module>../../fine-redisson</module>
<module>../../fine-xmlgraphics</module>
</modules>

3
build.third_step1-jdk11.gradle

@ -45,7 +45,6 @@ sourceSets{
"${srcDir}/fine-jgit/src/main/java",
"${srcDir}/fine-jna/jna/src/main/java",
"${srcDir}/fine-jna/jna-platform/src/main/java",
"${srcDir}/fine-jodd/src/main/java",
//"${srcDir}/fine-lookandfeel/src/main/java",
"${srcDir}/fine-lz4/src/main/java",
"${srcDir}/fine-org-dom4j/src/main/java",
@ -92,8 +91,6 @@ def resourceDirs = [
"${srcDir}/fine-jna/jna/src/main/resources",
"${srcDir}/fine-jna/jna/src/main/java",
"${srcDir}/fine-jna/jna-platform/src/main/java",
"${srcDir}/fine-jodd/src/main/java",
"${srcDir}/fine-jodd/src/main/resources",
// "${srcDir}/fine-lookandfeel/src/main/java",
"${srcDir}/fine-lz4/src/main/java",
"${srcDir}/fine-lz4/src/main/resources",

3
build.third_step1.gradle

@ -46,7 +46,6 @@ sourceSets{
"${srcDir}/fine-jgit/src/main/java",
"${srcDir}/fine-jna/jna/src/main/java",
"${srcDir}/fine-jna/jna-platform/src/main/java",
"${srcDir}/fine-jodd/src/main/java",
//"${srcDir}/fine-lookandfeel/src/main/java",
"${srcDir}/fine-lz4/src/main/java",
"${srcDir}/fine-org-dom4j/src/main/java",
@ -140,8 +139,6 @@ task copyFiles(type:Copy,dependsOn:'compileJava'){
with dataContent.call("${srcDir}/fine-jna/jna/src/main/java")
with dataContent.call("${srcDir}/fine-jna/jna-platform/src/main/java")
with dataContent.call("${srcDir}/fine-jna/jna-platform/src/main/resources")
with dataContent.call("${srcDir}/fine-jodd/src/main/java")
with dataContent.call("${srcDir}/fine-jodd/src/main/resources")
// with dataContent.call("${srcDir}/fine-lookandfeel/src/main/java")
with dataContent.call("${srcDir}/fine-lz4/src/main/java")
with dataContent.call("${srcDir}/fine-lz4/src/main/resources")

4
build.third_step2-jdk11.gradle

@ -35,7 +35,6 @@ sourceSets{
"${srcDir}/fine-jai/src/main/java",
"${srcDir}/fine-kryo/src/main/java",
"${srcDir}/fine-poi-old/src/main/java",
"${srcDir}/fine-redisson/src/main/java",
"${srcDir}/fine-xmlgraphics/xmlgraphics-batik/src/main/java",
"${srcDir}/fine-xmlgraphics/xmlgraphics-commons/src/main/java"
]
@ -52,8 +51,6 @@ def resourceDirs = [
"${srcDir}/fine-kryo/src/main/resources",
"${srcDir}/fine-poi-old/src/main/java",
"${srcDir}/fine-poi-old/src/main/resources",
"${srcDir}/fine-redisson/src/main/java",
"${srcDir}/fine-redisson/src/main/resources",
"${srcDir}/fine-xmlgraphics/xmlgraphics-batik/src/main/java",
"${srcDir}/fine-xmlgraphics/xmlgraphics-batik/src/main/resources",
"${srcDir}/fine-xmlgraphics/xmlgraphics-commons/src/main/java",
@ -91,7 +88,6 @@ String essentialVersion = findProperty("essentialVersion")
dependencies{
compileOnly "com.fr.essential:fine-essential:${essentialVersion}"
compile fileTree(dir:"${srcDir}/fine-poi-old/lib",include: '**/*.jar')
compile fileTree(dir:"${srcDir}/fine-redisson/lib",include: '**/*.jar')
compile fileTree(dir:"${srcDir}/fine-xmlgraphics/xmlgraphics-batik/lib",include: '**/*.jar')
compile fileTree(dir:"${srcDir}/fine-xmlgraphics/xmlgraphics-commons/lib",include: '**/*.jar')
compile fileTree(dir:"${srcDir}/build/libs/",include:'**/*.jar')

4
build.third_step2.gradle

@ -28,7 +28,6 @@ sourceSets{
"${srcDir}/fine-jai/src/main/java",
"${srcDir}/fine-kryo/src/main/java",
"${srcDir}/fine-poi-old/src/main/java",
"${srcDir}/fine-redisson/src/main/java",
"${srcDir}/fine-xmlgraphics/xmlgraphics-batik/src/main/java",
"${srcDir}/fine-xmlgraphics/xmlgraphics-commons/src/main/java"
]
@ -64,7 +63,6 @@ String essentialVersion = findProperty("essentialVersion")
dependencies{
compileOnly "com.fr.essential:fine-essential:${essentialVersion}"
compile fileTree(dir:"${srcDir}/fine-poi-old/lib",include: '**/*.jar')
compile fileTree(dir:"${srcDir}/fine-redisson/lib",include: '**/*.jar')
compile fileTree(dir:"${srcDir}/fine-xmlgraphics/xmlgraphics-batik/lib",include: '**/*.jar')
compile fileTree(dir:"${srcDir}/fine-xmlgraphics/xmlgraphics-commons/lib",include: '**/*.jar')
compile fileTree(dir:"${srcDir}/build/libs/",include:'**/*.jar')
@ -96,8 +94,6 @@ task copyFiles(type:Copy,dependsOn:'compileJava'){
with dataContent.call("${srcDir}/fine-kryo/src/main/resources")
with dataContent.call("${srcDir}/fine-poi-old/src/main/java")
with dataContent.call("${srcDir}/fine-poi-old/src/main/resources")
with dataContent.call("${srcDir}/fine-redisson/src/main/java")
with dataContent.call("${srcDir}/fine-redisson/src/main/resources")
with dataContent.call("${srcDir}/fine-xmlgraphics/xmlgraphics-batik/src/main/java")
with dataContent.call("${srcDir}/fine-xmlgraphics/xmlgraphics-batik/src/main/resources")
with dataContent.call("${srcDir}/fine-xmlgraphics/xmlgraphics-commons/src/main/java")

6
fine-jodd/.gitignore vendored

@ -1,6 +0,0 @@
*.iml
.idea/
.DS_Store
.project
.classpath
*.gradle

18
fine-jodd/pom.xml

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.fr.third</groupId>
<artifactId>step1</artifactId>
<version>${revision}</version>
<relativePath>../base-third-project/base-third-step1</relativePath>
</parent>
<artifactId>fine-jodd</artifactId>
<version>${revision}</version>
</project>

5
fine-jodd/readme.md

@ -1,5 +0,0 @@
## jodd
版本:3.7.1
github地址:https://github.com/oblac/jodd/tree/v3.7.1

43
fine-jodd/src/main/java/com/fr/third/jodd/Jodd.java

@ -1,43 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd;
/**
* Jodd!
*/
public class Jodd {
/**
* Ascii art of Jodds name. Every serious framework needs one:)
*/
public static String JODD = "\n" +
" __ __ __\n" +
" / /___ ____/ /___/ /\n" +
" __ / / __ \\/ __ / __ / \n" +
" / /_/ / /_/ / /_/ / /_/ / \n" +
" \\____/\\____/\\__,_/\\__,_/ \n";
}

188
fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanCopy.java

@ -1,188 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.bean;
import java.util.Map;
import static com.fr.third.jodd.util.StringPool.LEFT_SQ_BRACKET;
import static com.fr.third.jodd.util.StringPool.RIGHT_SQ_BRACKET;
/**
* Powerful tool for copying properties from one bean into another.
* <code>BeanCopy</code> works with POJO beans, but also with <code>Map</code>.
*
* @see BeanVisitor
*/
public class BeanCopy extends BeanVisitorImplBase<BeanCopy> {
protected Object destination;
protected boolean forced;
protected boolean declaredTarget;
protected boolean isTargetMap;
// ---------------------------------------------------------------- ctor
/**
* Creates new BeanCopy process between the source and the destination.
* Both source and destination can be a POJO object or a <code>Map</code>.
*/
public BeanCopy(final Object source, final Object destination) {
this.source = source;
this.destination = destination;
}
private BeanCopy(final Object source) {
this.source = source;
}
/**
* Simple static factory for <code>BeanCopy</code>.
* @see #BeanCopy(Object, Object)
*/
public static BeanCopy beans(final Object source, final Object destination) {
return new BeanCopy(source, destination);
}
/**
* Creates <code>BeanCopy</code> with given POJO bean as a source.
*/
public static BeanCopy fromBean(final Object source) {
return new BeanCopy(source);
}
/**
* Creates <code>BeanCopy</code> with given <code>Map</code> as a source.
*/
public static BeanCopy fromMap(final Map source) {
BeanCopy beanCopy = new BeanCopy(source);
beanCopy.isSourceMap = true;
return beanCopy;
}
/**
* Defines source, detects a map.
*/
public static BeanCopy from(final Object source) {
BeanCopy beanCopy = new BeanCopy(source);
beanCopy.isSourceMap = source instanceof Map;
return beanCopy;
}
// ---------------------------------------------------------------- destination
/**
* Defines destination bean.
*/
public BeanCopy toBean(final Object destination) {
this.destination = destination;
return this;
}
/**
* Defines destination map.
*/
public BeanCopy toMap(final Map destination) {
this.destination = destination;
isTargetMap = true;
return this;
}
/**
* Defines destination, detects a map.
*/
public BeanCopy to(final Object destination) {
this.destination = destination;
this.isTargetMap = destination instanceof Map;
return this;
}
// ---------------------------------------------------------------- properties
/**
* Defines if all properties should be copied (when set to <code>true</code>)
* or only public (when set to <code>false</code>, default).
*/
@Override
public BeanCopy declared(final boolean declared) {
this.declared = declared;
this.declaredTarget = declared;
return this;
}
/**
* Fine-tuning of the declared behaviour.
*/
public BeanCopy declared(final boolean declaredSource, final boolean declaredTarget) {
this.declared = declaredSource;
this.declaredTarget = declaredTarget;
return this;
}
public BeanCopy forced(final boolean forced) {
this.forced = forced;
return this;
}
// ---------------------------------------------------------------- visitor
protected BeanUtil beanUtil;
/**
* Performs the copying.
*/
public void copy() {
beanUtil = new BeanUtilBean()
.declared(declared)
.forced(forced)
.silent(true);
visit();
}
/**
* Copies single property to the destination.
* Exceptions are ignored, so copying continues if
* destination does not have some of the sources properties.
*/
@Override
protected boolean visitProperty(String name, final Object value) {
if (isTargetMap) {
name = LEFT_SQ_BRACKET + name + RIGHT_SQ_BRACKET;
}
beanUtil.setProperty(destination, name, value);
return true;
}
}

55
fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanException.java

@ -1,55 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.bean;
import com.fr.third.jodd.exception.UncheckedException;
/**
* Unchecked bean exception.
*/
public class BeanException extends UncheckedException {
public BeanException(final Throwable t) {
super(t);
}
public BeanException(final String message) {
super(message);
}
public BeanException(final String message, final BeanProperty bp) {
super(message + ". Invalid property: " + bp);
}
public BeanException(final String message, final Throwable t) {
super(message, t);
}
public BeanException(final String message, final BeanProperty bp, final Throwable t) {
super(message + ". Invalid property: " + bp, t);
}
}

150
fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanProperty.java

@ -1,150 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.bean;
import com.fr.third.jodd.introspector.ClassDescriptor;
import com.fr.third.jodd.introspector.ClassIntrospector;
import com.fr.third.jodd.introspector.Getter;
import com.fr.third.jodd.introspector.PropertyDescriptor;
import com.fr.third.jodd.introspector.Setter;
import java.util.function.Supplier;
/**
* Represents a bean named property. Contains two information:
* <ol>
* <li>Bean instance (and cached class descriptor)</li>
* <li>Property name</li>
* </ol>
* Used only internally by {@link BeanUtil} and similar utils.
*/
class BeanProperty {
BeanProperty(final BeanUtilBean beanUtilBean, final Object bean, final String propertyName) {
this.introspector = beanUtilBean.introspector;
setName(propertyName);
updateBean(bean);
this.last = true;
this.first = true;
this.fullName = bean.getClass().getSimpleName() + '#' + propertyName;
}
// ---------------------------------------------------------------- bean and descriptor
final String fullName; // initial name
final ClassIntrospector introspector;
Object bean;
private ClassDescriptor cd;
String name; // property name
boolean last; // is it a last property (when nested)
boolean first; // is it first property (when nested)
String indexString; // indexString for index property
/**
* Sets current property name.
*/
public void setName(final String name) {
this.name = name;
this.updateProperty = true;
}
/**
* Sets new bean instance.
*/
private void setBean(final Object bean) {
this.bean = bean;
this.cd = (bean == null ? null : introspector.lookup(bean.getClass()));
this.first = false;
this.updateProperty = true;
}
/**
* Updates the bean. Detects special case of suppliers.
*/
public void updateBean(final Object bean) {
this.setBean(bean);
if (this.cd != null && this.cd.isSupplier()) {
final Object newBean = ((Supplier)this.bean).get();
setBean(newBean);
}
}
// ---------------------------------------------------------------- simple properties
// indicates that property descriptor has to be updated
// since there was some property-related change of BeanProperty state
private boolean updateProperty = true;
// most recent property descriptor
private PropertyDescriptor propertyDescriptor;
/**
* Loads property descriptor, if property was updated.
*/
private void loadPropertyDescriptor() {
if (updateProperty) {
if (cd == null) {
propertyDescriptor = null;
} else {
propertyDescriptor = cd.getPropertyDescriptor(name, true);
}
updateProperty = false;
}
}
/**
* Returns getter.
*/
public Getter getGetter(final boolean declared) {
loadPropertyDescriptor();
return propertyDescriptor != null ? propertyDescriptor.getGetter(declared) : null;
}
/**
* Returns setter.
*/
public Setter getSetter(final boolean declared) {
loadPropertyDescriptor();
return propertyDescriptor != null ? propertyDescriptor.getSetter(declared) : null;
}
/**
* Returns <code>true</code> if class is a map.
*/
public boolean isMap() {
return cd != null && cd.isMap();
}
String index;
// ---------------------------------------------------------------- toString
@Override
public String toString() {
return fullName + " (" + (bean != null ? bean.getClass().getSimpleName() : "?") + '#' + name + ')';
}
}

60
fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanTemplateParser.java

@ -1,60 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.bean;
import com.fr.third.jodd.template.ContextTemplateParser;
import com.fr.third.jodd.template.StringTemplateParser;
/**
* Bean template is a string template with JSP-alike
* macros for injecting context values.
* This is a parser for such bean templates.
* <p>
* Once set, <code>BeanTemplateParser</code> instance is reusable
* as it doesn't store any parsing state.
* <p>
* Based on {@link StringTemplateParser}.
*/
public class BeanTemplateParser extends StringTemplateParser {
/**
* Creates bean-backed <code>MacroResolver</code>.
*/
public ContextTemplateParser of(final Object context) {
return template -> parseWithBean(template, context);
}
public String parseWithBean(final String template, final Object context) {
return super.parse(template, macroName -> {
Object value = BeanUtil.declaredSilent.getProperty(context, macroName);
if (value == null) {
return null;
}
return value.toString();
});
}
}

154
fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanUtil.java

@ -1,154 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.bean;
/**
* Supreme utility for reading and writing bean properties. However, this one is the fastest available.
* Although it provides various methods, the whole thing can be easily extended to match most needs.
* <p>
* BeanUtil supports:
* <ul>
* <li>Nested properties: separated by a dot ('.')</li>
* <li>Indexed properties: arrays or Lists</li>
* <li>Simple properties: accessor or Map</li>
* </ul>
*
* <p>
* Variants includes combinations of forced, declared and silent writing.
* <ul>
* <li><i>Forced</i> setting property tries to create destination property so it can be set correctly.</li>
* <li><i>Silent</i> doesn't throw an exception if destination doesn't exist or if conversion fails.</li>
* <li><i>Declared</i> includes only declared (public) properties.</li>
* </ul>
* <p>
* This utility considers both bean property methods (set and get accessors), and bean fields.
* This is done because of several reasons: often there is no need for both set/get accessors, since
* bean logic requires just one functionality (e.g. just reading). In such case, other bean manipulation
* libraries still requires to have both accessors in order to set or get value.
* Another reason is that most common usage is to work with public accessors, and in that case
* private fields are ignored.
*/
public interface BeanUtil {
/**
* Default instance of {@link BeanUtilBean}.
*/
BeanUtil pojo = new BeanUtilBean();
BeanUtil declared = new BeanUtilBean().declared(true);
BeanUtil silent = new BeanUtilBean().silent(true);
BeanUtil forced = new BeanUtilBean().forced(true);
BeanUtil declaredSilent = new BeanUtilBean().declared(true).silent(true);
BeanUtil declaredForced = new BeanUtilBean().declared(true).forced(true);
BeanUtil declaredForcedSilent = new BeanUtilBean().declared(true).forced(true).silent(true);
BeanUtil forcedSilent = new BeanUtilBean().forced(true).silent(true);
// ---------------------------------------------------------------- SET
/**
* Sets Java Bean property.
* @param bean Java POJO bean or a Map
* @param name property name
* @param value property value
*/
void setProperty(Object bean, String name, Object value);
/**
* Sets indexed property.
*/
void setIndexProperty(Object bean, String property, int index, Object value);
/**
* Sets simple property.
*/
void setSimpleProperty(Object bean, String property, Object value);
// ---------------------------------------------------------------- GET
/**
* Returns value of bean's property.
* <p>
* In silent mode, returning of <code>null</code> is ambiguous: it may means that property name
* is valid and property value is <code>null</code> or that property name is invalid.
* <p>
* Using forced mode does not have any influence on the result.
*/
<T> T getProperty(Object bean, String name);
/**
* Returns value of indexed property.
*/
<T> T getIndexProperty(Object bean, String property, int index);
/**
* Reads simple property.
*/
<T> T getSimpleProperty(Object bean, String property);
// ---------------------------------------------------------------- HAS
/**
* Returns <code>true</code> if bean has a property.
*/
boolean hasProperty(Object bean, String name);
/**
* Returns <code>true</code> if bean has only a root property.
* If yes, this means that property may be injected into the bean.
* If not, bean does not contain the property.
*/
boolean hasRootProperty(Object bean, String name);
/**
* Returns <code>true</code> if simple property exist.
*/
boolean hasSimpleProperty(Object bean, String property);
// ---------------------------------------------------------------- type
/**
* Returns property type.
*/
Class<?> getPropertyType(Object bean, String name);
// ---------------------------------------------------------------- misc
/**
* Returns the very first name chunk of the property.
*/
public String extractThisReference(String propertyName);
}

559
fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanUtilBean.java

@ -1,559 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.bean;
import com.fr.third.jodd.introspector.Getter;
import com.fr.third.jodd.introspector.Setter;
import com.fr.third.jodd.util.ClassUtil;
import com.fr.third.jodd.util.StringUtil;
import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Instantiable version of {@link BeanUtil}.
*/
public class BeanUtilBean extends BeanUtilUtil implements BeanUtil {
/**
* Sets the declared flag.
*/
public BeanUtilBean declared(final boolean declared) {
this.isDeclared = declared;
return this;
}
/**
* Sets the forced flag.
*/
public BeanUtilBean forced(final boolean forced) {
this.isForced = forced;
return this;
}
/**
* Sets the silent flag.
*/
public BeanUtilBean silent(final boolean silent) {
this.isSilent = silent;
return this;
}
// ---------------------------------------------------------------- internal resolver
/**
* Resolves nested property name to the very last indexed property.
* If forced, <code>null</code> or non-existing properties will be created.
*/
protected void resolveNestedProperties(final BeanProperty bp) {
String name = bp.name;
int dotNdx;
while ((dotNdx = indexOfDot(name)) != -1) {
bp.last = false;
bp.setName(name.substring(0, dotNdx));
bp.updateBean(getIndexProperty(bp));
name = name.substring(dotNdx + 1);
}
bp.last = true;
bp.setName(name);
}
protected boolean resolveExistingNestedProperties(final BeanProperty bp) {
String name = bp.name;
int dotNdx;
while ((dotNdx = indexOfDot(name)) != -1) {
bp.last = false;
bp.setName(name.substring(0, dotNdx));
final String temp = bp.name;
if (!hasIndexProperty(bp)) {
return false;
}
bp.setName(temp);
bp.updateBean(getIndexProperty(bp));
name = name.substring(dotNdx + 1);
}
bp.last = true;
bp.setName(name);
return true;
}
// ---------------------------------------------------------------- simple property
@Override
public boolean hasSimpleProperty(final Object bean, final String property) {
return hasSimpleProperty(new BeanProperty(this, bean, property));
}
protected boolean hasSimpleProperty(final BeanProperty bp) {
if (bp.bean == null) {
return false;
}
// try: getter
final Getter getter = bp.getGetter(isDeclared);
if (getter != null) {
return true;
}
// try: (Map) get("property")
if (bp.isMap()) {
Map map = (Map) bp.bean;
if (map.containsKey(bp.name)) {
return true;
}
}
return false;
}
@Override
public <T> T getSimpleProperty(final Object bean, final String property) {
return (T) getSimpleProperty(new BeanProperty(this, bean, property));
}
protected Object getSimpleProperty(final BeanProperty bp) {
if (bp.name.length() == 0) {
if (bp.indexString != null) {
// index string exist, but property name is missing
return bp.bean;
}
throw new BeanException("Invalid property", bp);
}
Getter getter = bp.getGetter(isDeclared);
if (getter != null) {
Object result;
try {
result = getter.invokeGetter(bp.bean);
} catch (Exception ex) {
if (isSilent) {
return null;
}
throw new BeanException("Getter failed: " + getter, ex);
}
if ((result == null) && (isForced)) {
result = createBeanProperty(bp);
}
return result;
}
// try: (Map) get("property")
if (bp.isMap()) {
Map map = (Map) bp.bean;
Object key = convertIndexToMapKey(getter, bp.name);
if (!map.containsKey(key)) {
if (!isForced) {
if (isSilent) {
return null;
}
throw new BeanException("Map key not found: " + bp.name, bp);
}
Map value = new HashMap();
//noinspection unchecked
map.put(key, value);
return value;
}
return map.get(key);
}
// failed
if (isSilent) {
return null;
}
throw new BeanException("Simple property not found: " + bp.name, bp);
}
@Override
public void setSimpleProperty(final Object bean, final String property, final Object value) {
setSimpleProperty(new BeanProperty(this, bean, property), value);
}
/**
* Sets a value of simple property.
*/
@SuppressWarnings({"unchecked"})
protected void setSimpleProperty(final BeanProperty bp, final Object value) {
Setter setter = bp.getSetter(isDeclared);
// try: setter
if (setter != null) {
invokeSetter(setter, bp, value);
return;
}
// try: put("property", value)
if (bp.isMap()) {
((Map) bp.bean).put(bp.name, value);
return;
}
if (isSilent) {
return;
}
throw new BeanException("Simple property not found: " + bp.name, bp);
}
// ---------------------------------------------------------------- indexed property
protected boolean hasIndexProperty(final BeanProperty bp) {
if (bp.bean == null) {
return false;
}
String indexString = extractIndex(bp);
if (indexString == null) {
return hasSimpleProperty(bp);
}
Object resultBean = getSimpleProperty(bp);
if (resultBean == null) {
return false;
}
// try: property[index]
if (resultBean.getClass().isArray()) {
int index = parseInt(indexString, bp);
return (index >= 0) && (index < Array.getLength(resultBean));
}
// try: list.get(index)
if (resultBean instanceof List) {
int index = parseInt(indexString, bp);
return (index >= 0) && (index < ((List)resultBean).size());
}
if (resultBean instanceof Map) {
return ((Map)resultBean).containsKey(indexString);
}
// failed
return false;
}
@Override
public <T> T getIndexProperty(final Object bean, final String property, final int index) {
BeanProperty bp = new BeanProperty(this, bean, property);
bp.indexString = bp.index = String.valueOf(index);
Object value = _getIndexProperty(bp);
bp.indexString = null;
return (T) value;
}
/**
* Get non-nested property value: either simple or indexed property.
* If forced, missing bean will be created if possible.
*/
protected Object getIndexProperty(final BeanProperty bp) {
bp.indexString = extractIndex(bp);
Object value = _getIndexProperty(bp);
bp.indexString = null;
return value;
}
private Object _getIndexProperty(final BeanProperty bp) {
Object resultBean = getSimpleProperty(bp);
Getter getter = bp.getGetter(isDeclared);
if (bp.indexString == null) {
return resultBean; // no index, just simple bean
}
if (resultBean == null) {
if (isSilent) {
return null;
}
throw new BeanException("Index property is null: " + bp.name, bp);
}
// try: property[index]
if (resultBean.getClass().isArray()) {
int index = parseInt(bp.indexString, bp);
if (isForced) {
return arrayForcedGet(bp, resultBean, index);
} else {
return Array.get(resultBean, index);
}
}
// try: list.get(index)
if (resultBean instanceof List) {
int index = parseInt(bp.indexString, bp);
List list = (List) resultBean;
if (!isForced) {
return list.get(index);
}
if (!bp.last) {
ensureListSize(list, index);
}
Object value = list.get(index);
if (value == null) {
Class listComponentType = extractGenericComponentType(getter);
if (listComponentType == Object.class) {
// not an error: when component type is unknown, use Map as generic bean
listComponentType = Map.class;
}
try {
value = ClassUtil.newInstance(listComponentType);
} catch (Exception ex) {
if (isSilent) {
return null;
}
throw new BeanException("Invalid list element: " + bp.name + '[' + index + ']', bp, ex);
}
//noinspection unchecked
list.set(index, value);
}
return value;
}
// try: map.get('index')
if (resultBean instanceof Map) {
Map map = (Map) resultBean;
Object key = convertIndexToMapKey(getter, bp.indexString);
if (!isForced) {
return map.get(key);
}
Object value = map.get(key);
if (!bp.last) {
if (value == null) {
Class mapComponentType = extractGenericComponentType(getter);
if (mapComponentType == Object.class) {
mapComponentType = Map.class;
}
try {
value = ClassUtil.newInstance(mapComponentType);
} catch (Exception ex) {
if (isSilent) {
return null;
}
throw new BeanException("Invalid map element: " + bp.name + '[' + bp.indexString + ']', bp, ex);
}
//noinspection unchecked
map.put(key, value);
}
}
return value;
}
// failed
if (isSilent) {
return null;
}
throw new BeanException("Index property is not an array, list or map: " + bp.name, bp);
}
@Override
public void setIndexProperty(final Object bean, final String property, final int index, final Object value) {
BeanProperty bp = new BeanProperty(this, bean, property);
bp.indexString = bp.index = String.valueOf(index);
_setIndexProperty(bp, value);
bp.indexString = null;
}
/**
* Sets indexed or regular properties (no nested!).
*/
protected void setIndexProperty(final BeanProperty bp, final Object value) {
bp.indexString = extractIndex(bp);
_setIndexProperty(bp, value);
bp.indexString = null;
}
@SuppressWarnings({"unchecked"})
private void _setIndexProperty(final BeanProperty bp, Object value) {
if (bp.indexString == null) {
setSimpleProperty(bp, value);
return;
}
// try: getInner()
Object nextBean = getSimpleProperty(bp);
Getter getter = bp.getGetter(isDeclared);
if (nextBean == null) {
if (isSilent) {
return;
}
throw new BeanException("Index property is null:" + bp.name, bp);
}
// inner bean found
if (nextBean.getClass().isArray()) {
int index = parseInt(bp.indexString, bp);
if (isForced) {
arrayForcedSet(bp, nextBean, index, value);
} else {
Array.set(nextBean, index, value);
}
return;
}
if (nextBean instanceof List) {
int index = parseInt(bp.indexString, bp);
Class listComponentType = extractGenericComponentType(getter);
if (listComponentType != Object.class) {
value = convertType(value, listComponentType);
}
List list = (List) nextBean;
if (isForced) {
ensureListSize(list, index);
}
list.set(index, value);
return;
}
if (nextBean instanceof Map) {
Map map = (Map) nextBean;
Object key = convertIndexToMapKey(getter, bp.indexString);
Class mapComponentType = extractGenericComponentType(getter);
if (mapComponentType != Object.class) {
value = convertType(value, mapComponentType);
}
map.put(key, value);
return;
}
// failed
if (isSilent) {
return;
}
throw new BeanException("Index property is not an array, list or map: " + bp.name, bp);
}
// ---------------------------------------------------------------- SET
@Override
public void setProperty(final Object bean, final String name, final Object value) {
BeanProperty beanProperty = new BeanProperty(this, bean, name);
if (!isSilent) {
resolveNestedProperties(beanProperty);
setIndexProperty(beanProperty, value);
}
else {
try {
resolveNestedProperties(beanProperty);
setIndexProperty(beanProperty, value);
}
catch (Exception ignore) {}
}
}
// ---------------------------------------------------------------- GET
/**
* Returns value of bean's property.
*/
@Override
public <T> T getProperty(final Object bean, final String name) {
BeanProperty beanProperty = new BeanProperty(this, bean, name);
if (!isSilent) {
resolveNestedProperties(beanProperty);
return (T) getIndexProperty(beanProperty);
}
else {
try {
resolveNestedProperties(beanProperty);
return (T) getIndexProperty(beanProperty);
}
catch (Exception ignore) {
return null;
}
}
}
// ---------------------------------------------------------------- HAS
@Override
public boolean hasProperty(final Object bean, final String name) {
BeanProperty beanProperty = new BeanProperty(this, bean, name);
if (!resolveExistingNestedProperties(beanProperty)) {
return false;
}
return hasIndexProperty(beanProperty);
}
@Override
public boolean hasRootProperty(final Object bean, String name) {
int dotNdx = indexOfDot(name);
if (dotNdx != -1) {
name = name.substring(0, dotNdx);
}
BeanProperty beanProperty = new BeanProperty(this, bean, name);
extractIndex(beanProperty);
return hasSimpleProperty(beanProperty);
}
// ---------------------------------------------------------------- type
@Override
public Class<?> getPropertyType(final Object bean, final String name) {
BeanProperty beanProperty = new BeanProperty(this, bean, name);
if (!resolveExistingNestedProperties(beanProperty)) {
return null;
}
hasIndexProperty(beanProperty);
return extractType(beanProperty);
}
// ---------------------------------------------------------------- utilities
private static final char[] INDEX_CHARS = new char[] {'.', '['};
/**
* Extract the first name of this reference.
*/
@Override
public String extractThisReference(final String propertyName) {
int ndx = StringUtil.indexOfChars(propertyName, INDEX_CHARS);
if (ndx == -1) {
return propertyName;
}
return propertyName.substring(0, ndx);
}
}

346
fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanUtilUtil.java

@ -1,346 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.bean;
import com.fr.third.jodd.introspector.ClassIntrospector;
import com.fr.third.jodd.introspector.Getter;
import com.fr.third.jodd.introspector.MapperFunction;
import com.fr.third.jodd.introspector.Setter;
import com.fr.third.jodd.typeconverter.TypeConverterManager;
import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.List;
/**
* Various bean property utilities that makes writings of {@link BeanUtil} classes easy.
*/
abstract class BeanUtilUtil implements BeanUtil {
// ---------------------------------------------------------------- flags
protected boolean isDeclared = false;
protected boolean isForced = false;
protected boolean isSilent = false;
// ---------------------------------------------------------------- introspector
protected ClassIntrospector introspector = ClassIntrospector.get();
protected TypeConverterManager typeConverterManager = TypeConverterManager.get();
/**
* Sets {@link ClassIntrospector introspector} implementation.
*/
public void setIntrospector(final ClassIntrospector introspector) {
this.introspector = introspector;
}
/**
* Sets {@link TypeConverterManager type converter manager} implementation.
*/
public void setTypeConverterManager(final TypeConverterManager typeConverterManager) {
this.typeConverterManager = typeConverterManager;
}
/**
* Converts object to destination type. Invoked before the
* value is set into destination. Throws <code>TypeConversionException</code>
* if conversion fails.
*/
@SuppressWarnings("unchecked")
protected Object convertType(final Object value, final Class type) {
return typeConverterManager.convertType(value, type);
}
/**
* Converter to collection.
*/
@SuppressWarnings("unchecked")
protected Object convertToCollection(final Object value, final Class destinationType, final Class componentType) {
return typeConverterManager.convertToCollection(value, destinationType, componentType);
}
// ---------------------------------------------------------------- accessors
/**
* Invokes setter, but first converts type to match the setter type.
*/
protected Object invokeSetter(final Setter setter, final BeanProperty bp, Object value) {
try {
final MapperFunction setterMapperFunction = setter.getMapperFunction();
if (setterMapperFunction != null) {
value = setterMapperFunction.apply(value);
}
final Class type = setter.getSetterRawType();
if (ClassUtil.isTypeOf(type, Collection.class)) {
Class componentType = setter.getSetterRawComponentType();
value = convertToCollection(value, type, componentType);
} else {
// no collections
value = convertType(value, type);
}
setter.invokeSetter(bp.bean, value);
} catch (Exception ex) {
if (isSilent) {
return null;
}
throw new BeanException("Setter failed: " + setter, ex);
}
return value;
}
// ---------------------------------------------------------------- forced
/**
* Returns the element of an array forced. If value is <code>null</code>, it will be instantiated.
* If not the last part of indexed bean property, array will be expanded to the index if necessary.
*/
protected Object arrayForcedGet(final BeanProperty bp, Object array, final int index) {
Class componentType = array.getClass().getComponentType();
if (!bp.last) {
array = ensureArraySize(bp, array, componentType, index);
}
Object value = Array.get(array, index);
if (value == null) {
try {
//noinspection unchecked
value = ClassUtil.newInstance(componentType);
} catch (Exception ex) {
if (isSilent) {
return null;
}
throw new BeanException("Invalid array element: " + bp.name + '[' + index + ']', bp, ex);
}
Array.set(array, index, value);
}
return value;
}
/**
* Sets the array element forced. If index is greater then arrays length, array will be expanded to the index.
* If speed is critical, it is better to allocate an array with proper size before using this method.
*/
protected void arrayForcedSet(final BeanProperty bp, Object array, final int index, Object value) {
Class componentType = array.getClass().getComponentType();
array = ensureArraySize(bp, array, componentType, index);
value = convertType(value, componentType);
Array.set(array, index, value);
}
@SuppressWarnings({"SuspiciousSystemArraycopy"})
protected Object ensureArraySize(final BeanProperty bp, Object array, final Class componentType, final int index) {
int len = Array.getLength(array);
if (index >= len) {
Object newArray = Array.newInstance(componentType, index + 1);
System.arraycopy(array, 0, newArray, 0, len);
Setter setter = bp.getSetter(true);
if (setter == null) {
// no point to check for bp.silent, throws NPE later
throw new BeanException("Setter or field not found: " + bp.name, bp);
}
newArray = invokeSetter(setter, bp, newArray);
array = newArray;
}
return array;
}
@SuppressWarnings({"unchecked"})
protected void ensureListSize(final List list, final int size) {
int len = list.size();
while (size >= len) {
list.add(null);
len++;
}
}
// ---------------------------------------------------------------- index
/**
* Finds the very first next dot. Ignores dots between index brackets.
* Returns <code>-1</code> when dot is not found.
*/
protected int indexOfDot(final String name) {
int ndx = 0;
int len = name.length();
boolean insideBracket = false;
while (ndx < len) {
char c = name.charAt(ndx);
if (insideBracket) {
if (c == ']') {
insideBracket = false;
}
} else {
if (c == '.') {
return ndx;
}
if (c == '[') {
insideBracket = true;
}
}
ndx++;
}
return -1;
}
/**
* Extract index string from non-nested property name.
* If index is found, it is stripped from bean property name.
* If no index is found, it returns <code>null</code>.
*/
protected String extractIndex(final BeanProperty bp) {
bp.index = null;
String name = bp.name;
int lastNdx = name.length() - 1;
if (lastNdx < 0) {
return null;
}
if (name.charAt(lastNdx) == ']') {
int leftBracketNdx = name.lastIndexOf('[');
if (leftBracketNdx != -1) {
bp.setName(name.substring(0, leftBracketNdx));
bp.index = name.substring(leftBracketNdx + 1, lastNdx);
return bp.index;
}
}
return null;
}
protected int parseInt(final String indexString, final BeanProperty bp) {
try {
return Integer.parseInt(indexString);
} catch (NumberFormatException nfex) {
// no point to use bp.silent, as will throw exception
throw new BeanException("Invalid index: " + indexString, bp, nfex);
}
}
// ---------------------------------------------------------------- create property
/**
* Creates new instance for current property name through its setter.
* It uses default constructor!
*/
protected Object createBeanProperty(final BeanProperty bp) {
Setter setter = bp.getSetter(true);
if (setter == null) {
return null;
}
Class type = setter.getSetterRawType();
Object newInstance;
try {
newInstance = ClassUtil.newInstance(type);
} catch (Exception ex) {
if (isSilent) {
return null;
}
throw new BeanException("Invalid property: " + bp.name, bp, ex);
}
newInstance = invokeSetter(setter, bp, newInstance);
return newInstance;
}
// ---------------------------------------------------------------- generic and type
/**
* Extracts generic component type of a property. Returns <code>Object.class</code>
* when property does not have component.
*/
protected Class extractGenericComponentType(final Getter getter) {
Class componentType = null;
if (getter != null) {
componentType = getter.getGetterRawComponentType();
}
if (componentType == null) {
componentType = Object.class;
}
return componentType;
}
/**
* Converts <b>Map</b> index to key type. If conversion fails, original value will be returned.
*/
protected Object convertIndexToMapKey(final Getter getter, final Object index) {
Class indexType = null;
if (getter != null) {
indexType = getter.getGetterRawKeyComponentType();
}
// check if set
if (indexType == null) {
indexType = Object.class; // marker for no generic type
}
if (indexType == Object.class) {
return index;
}
try {
return convertType(index, indexType);
} catch (Exception ignore) {
return index;
}
}
/**
* Extracts type of current property.
*/
protected Class extractType(final BeanProperty bp) {
Getter getter = bp.getGetter(isDeclared);
if (getter != null) {
if (bp.index != null) {
Class type = getter.getGetterRawComponentType();
return type == null ? Object.class : type;
}
return getter.getGetterRawType();
}
return null; // this should not happens
}
}

194
fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanVisitor.java

@ -1,194 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.bean;
import com.fr.third.jodd.inex.InExRuleMatcher;
import com.fr.third.jodd.inex.InExRules;
import com.fr.third.jodd.introspector.ClassDescriptor;
import com.fr.third.jodd.introspector.ClassIntrospector;
import com.fr.third.jodd.introspector.FieldDescriptor;
import com.fr.third.jodd.introspector.MethodDescriptor;
import com.fr.third.jodd.introspector.PropertyDescriptor;
import com.fr.third.jodd.util.StringUtil;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import static com.fr.third.jodd.util.StringPool.LEFT_SQ_BRACKET;
import static com.fr.third.jodd.util.StringPool.RIGHT_SQ_BRACKET;
/**
* Visitor for bean properties. It extracts properties names
* from the source bean and then visits one by one.
*
* @see BeanVisitorImplBase
*/
public abstract class BeanVisitor implements InExRuleMatcher<String, String> {
/**
* Source bean.
*/
protected Object source;
/**
* Include/exclude rules.
*/
protected InExRules<String, String, String> rules = new InExRules<>(this);
/**
* Flag for enabling declared properties, or just public ones.
*/
protected boolean declared;
/**
* Defines if null values should be ignored.
*/
protected boolean ignoreNullValues;
/**
* Defines if empty string should be ignored.
*/
protected boolean ignoreEmptyString;
/**
* Defines if fields should be included.
*/
protected boolean includeFields;
/**
* Initial matching mode.
*/
protected boolean blacklist = true;
/**
* Indicates the the source is a Map.
*/
protected boolean isSourceMap = false;
// ---------------------------------------------------------------- util
/**
* Returns all bean property names.
*/
protected String[] getAllBeanPropertyNames(final Class type, final boolean declared) {
final ClassDescriptor classDescriptor = ClassIntrospector.get().lookup(type);
final PropertyDescriptor[] propertyDescriptors = classDescriptor.getAllPropertyDescriptors();
final ArrayList<String> names = new ArrayList<>(propertyDescriptors.length);
for (final PropertyDescriptor propertyDescriptor : propertyDescriptors) {
final MethodDescriptor getter = propertyDescriptor.getReadMethodDescriptor();
if (getter != null) {
if (getter.matchDeclared(declared)) {
names.add(propertyDescriptor.getName());
}
}
else if (includeFields) {
final FieldDescriptor field = propertyDescriptor.getFieldDescriptor();
if (field != null) {
if (field.matchDeclared(declared)) {
names.add(field.getName());
}
}
}
}
return names.toArray(new String[0]);
}
/**
* Returns an array of bean properties. If bean is a <code>Map</code>,
* all its keys will be returned.
*/
protected String[] resolveProperties(final Object bean, final boolean declared) {
final String[] properties;
if (bean instanceof Map) {
final Set keys = ((Map) bean).keySet();
properties = new String[keys.size()];
int ndx = 0;
for (final Object key : keys) {
properties[ndx] = key.toString();
ndx++;
}
} else {
properties = getAllBeanPropertyNames(bean.getClass(), declared);
}
return properties;
}
/**
* Starts visiting properties.
*/
public void visit() {
final String[] properties = resolveProperties(source, declared);
for (final String name : properties) {
if (name == null) {
continue;
}
if (!rules.match(name, blacklist)) {
continue;
}
final Object value;
String propertyName = name;
if (isSourceMap) {
propertyName = LEFT_SQ_BRACKET + name + RIGHT_SQ_BRACKET;
}
if (declared) {
value = BeanUtil.declared.getProperty(source, propertyName);
} else {
value = BeanUtil.pojo.getProperty(source, propertyName);
}
if (value == null && ignoreNullValues) {
continue;
}
if (ignoreEmptyString && value instanceof String && StringUtil.isEmpty((String) value)) {
continue;
}
visitProperty(name, value);
}
}
/**
* Invoked for each visited property. Returns <code>true</code> if
* visiting should continue, otherwise <code>false</code> to stop.
*/
protected abstract boolean visitProperty(String name, Object value);
/**
* Compares property name to the rules.
*/
@Override
public boolean accept(final String propertyName, final String rule, final boolean include) {
return propertyName.equals(rule);
}
}

131
fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanVisitorImplBase.java

@ -1,131 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.bean;
/**
* Default implementation of {@link BeanVisitor} for just setting
* the properties in fluent way.
*/
public abstract class BeanVisitorImplBase<T> extends BeanVisitor {
@SuppressWarnings("unchecked")
protected T _this() {
return (T) this;
}
/**
* Excludes all properties, i.e. enables blacklist mode.
*/
public T excludeAll() {
blacklist = false;
return _this();
}
/**
* Defines excluded property names.
*/
public T exclude(final String... excludes) {
for (String ex : excludes) {
rules.exclude(ex);
}
return _this();
}
/**
* Exclude a property.
*/
public T exclude(final String exclude) {
rules.exclude(exclude);
return _this();
}
/**
* Defines included property names.
*/
public T include(final String... includes) {
for (String in : includes) {
rules.include(in);
}
return _this();
}
/**
* Include a property.
*/
public T include(final String include) {
rules.include(include);
return _this();
}
/**
* Defines included property names as public properties
* of given template class. Sets to black list mode.
*/
public T includeAs(final Class template) {
blacklist = false;
String[] properties = getAllBeanPropertyNames(template, false);
include(properties);
return _this();
}
/**
* Defines if <code>null</code> values should be ignored.
*/
public T ignoreNulls(final boolean ignoreNulls) {
this.ignoreNullValues = ignoreNulls;
return _this();
}
/**
* Defines if <code>empty string</code> should be ignored.
*/
public T ignoreEmptyString(final boolean ignoreEmptyString) {
this.ignoreEmptyString = ignoreEmptyString;
return _this();
}
/**
* Defines if all properties should be copied (when set to <code>true</code>)
* or only public (when set to <code>false</code>, default).
*/
public T declared(final boolean declared) {
this.declared = declared;
return _this();
}
/**
* Defines if fields without getters should be copied too.
*/
public T includeFields(final boolean includeFields) {
this.includeFields = includeFields;
return _this();
}
}

83
fine-jodd/src/main/java/com/fr/third/jodd/bean/BeanWalker.java

@ -1,83 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.bean;
import java.util.Map;
/**
* Walker over bean properties.
*/
public class BeanWalker extends BeanVisitorImplBase<BeanWalker> {
private final BeanWalkerCallback callback;
/**
* Functional callback for walking.
*/
public interface BeanWalkerCallback {
void visitProperty(String name, Object value);
}
public BeanWalker(final BeanWalkerCallback callback) {
this.callback = callback;
}
/**
* Static ctor.
*/
public static BeanWalker walk(final BeanWalkerCallback callback) {
return new BeanWalker(callback);
}
public void source(final Object source) {
this.source = source;
isSourceMap = (source instanceof Map);
visit();
}
public void bean(final Object bean) {
this.source = bean;
visit();
}
public void map(final Map map) {
this.source = map;
this.isSourceMap = true;
visit();
}
@Override
protected boolean visitProperty(final String name, final Object value) {
callback.visitProperty(name, value);
return true;
}
}

29
fine-jodd/src/main/java/com/fr/third/jodd/bean/package-info.java

@ -1,29 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/**
* Java Bean utilities, provides <em>the fastest</em> bean manipulation.
*/
package com.fr.third.jodd.bean;

166
fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastBooleanBuffer.java

@ -1,166 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.buffer;
import java.util.Arrays;
/**
* Faster {@code boolean} buffer.
*/
public class FastBooleanBuffer {
private boolean[] buffer;
private int offset;
/**
* Creates a new {@code boolean} buffer. The buffer capacity is
* initially 64 booleans, though its size increases if necessary.
*/
public FastBooleanBuffer() {
this.buffer = new boolean[64];
}
/**
* Creates a new {@code boolean} buffer, with a buffer capacity of
* the specified size.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public FastBooleanBuffer(final int size) {
this.buffer = new boolean[size];
}
/**
* Grows the buffer.
*/
private void grow(final int minCapacity) {
final int oldCapacity = buffer.length;
int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0) {
// special case, min capacity is larger then a grow
newCapacity = minCapacity + 512;
}
buffer = Arrays.copyOf(buffer, newCapacity);
}
/**
* Appends single {@code boolean} to buffer.
*/
public void append(final boolean element) {
if (offset - buffer.length >= 0) {
grow(offset);
}
buffer[offset++] = element;
}
/**
* Appends {@code boolean} array to buffer.
*/
public FastBooleanBuffer append(final boolean[] array, final int off, final int len) {
if (offset + len - buffer.length > 0) {
grow(offset + len);
}
System.arraycopy(array, off, buffer, offset, len);
offset += len;
return this;
}
/**
* Appends {@code boolean} array to buffer.
*/
public FastBooleanBuffer append(final boolean[] array) {
return append(array, 0, array.length);
}
/**
* Appends another fast buffer to this one.
*/
public FastBooleanBuffer append(final FastBooleanBuffer buff) {
if (buff.offset == 0) {
return this;
}
append(buff.buffer, 0, buff.offset);
return this;
}
/**
* Returns buffer size.
*/
public int size() {
return offset;
}
/**
* Tests if this buffer has no elements.
*/
public boolean isEmpty() {
return offset == 0;
}
/**
* Resets the buffer content.
*/
public void clear() {
offset = 0;
}
/**
* Creates {@code boolean} array from buffered content.
*/
public boolean[] toArray() {
return Arrays.copyOf(buffer, offset);
}
/**
* Creates {@code boolean} subarray from buffered content.
*/
public boolean[] toArray(final int start, final int len) {
final boolean[] array = new boolean[len];
if (len == 0) {
return array;
}
System.arraycopy(buffer, start, array, 0, len);
return array;
}
/**
* Returns {@code boolean} element at given index.
*/
public boolean get(final int index) {
if (index >= offset) {
throw new IndexOutOfBoundsException();
}
return buffer[index];
}
}

166
fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastByteBuffer.java

@ -1,166 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.buffer;
import java.util.Arrays;
/**
* Faster {@code byte} buffer. Works faster for smaller buffer sizes.
* After eg. length of 2048 the performances are practically the same.
*/
public class FastByteBuffer {
private byte[] buffer;
private int offset;
/**
* Creates a new {@code byte} buffer. The buffer capacity is
* initially 64 bytes, though its size increases if necessary.
*/
public FastByteBuffer() {
this.buffer = new byte[64];
}
/**
* Creates a new {@code byte} buffer, with a buffer capacity of
* the specified size.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public FastByteBuffer(final int size) {
this.buffer = new byte[size];
}
/**
* Grows the buffer.
*/
private void grow(final int minCapacity) {
final int oldCapacity = buffer.length;
int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0) {
// special case, min capacity is larger then a grow
newCapacity = minCapacity + 512;
}
buffer = Arrays.copyOf(buffer, newCapacity);
}
/**
* Appends single {@code byte} to buffer.
*/
public void append(final byte element) {
if (offset - buffer.length >= 0) {
grow(offset);
}
buffer[offset++] = element;
}
/**
* Appends {@code byte} array to buffer.
*/
public FastByteBuffer append(final byte[] array, final int off, final int len) {
if (offset + len - buffer.length > 0) {
grow(offset + len);
}
System.arraycopy(array, off, buffer, offset, len);
offset += len;
return this;
}
/**
* Appends {@code byte} array to buffer.
*/
public FastByteBuffer append(final byte[] array) {
return append(array, 0, array.length);
}
/**
* Appends another fast buffer to this one.
*/
public FastByteBuffer append(final FastByteBuffer buff) {
if (buff.offset == 0) {
return this;
}
append(buff.buffer, 0, buff.offset);
return this;
}
/**
* Returns buffer size.
*/
public int size() {
return offset;
}
/**
* Tests if this buffer has no elements.
*/
public boolean isEmpty() {
return offset == 0;
}
/**
* Resets the buffer content.
*/
public void clear() {
offset = 0;
}
/**
* Creates {@code byte} array from buffered content.
*/
public byte[] toArray() {
return Arrays.copyOf(buffer, offset);
}
/**
* Creates {@code byte} subarray from buffered content.
*/
public byte[] toArray(final int start, final int len) {
final byte[] array = new byte[len];
if (len == 0) {
return array;
}
System.arraycopy(buffer, start, array, 0, len);
return array;
}
/**
* Returns {@code byte} element at given index.
*/
public byte get(final int index) {
if (index >= offset) {
throw new IndexOutOfBoundsException();
}
return buffer[index];
}
}

211
fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastCharBuffer.java

@ -1,211 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.buffer;
import com.fr.third.jodd.util.CharArraySequence;
import java.util.Arrays;
/**
* Faster {@code char} buffer.
*/
public class FastCharBuffer implements CharSequence, Appendable {
private char[] buffer;
private int offset;
/**
* Creates a new {@code char} buffer. The buffer capacity is
* initially 64 chars, though its size increases if necessary.
*/
public FastCharBuffer() {
this.buffer = new char[64];
}
/**
* Creates a new {@code char} buffer, with a buffer capacity of
* the specified size, in chars.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public FastCharBuffer(final int size) {
this.buffer = new char[size];
}
/**
* Grows the buffer.
*/
private void grow(final int minCapacity) {
final int oldCapacity = buffer.length;
int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0) {
// special case, min capacity is larger then a grow
newCapacity = minCapacity + 512;
}
buffer = Arrays.copyOf(buffer, newCapacity);
}
/**
* Appends single {@code char} to buffer.
*/
@Override
public FastCharBuffer append(final char element) {
if (offset - buffer.length >= 0) {
grow(offset);
}
buffer[offset++] = element;
return this;
}
/**
* Appends {@code char} array to buffer.
*/
public FastCharBuffer append(final char[] array, final int off, final int len) {
if (offset + len - buffer.length > 0) {
grow(offset + len);
}
System.arraycopy(array, off, buffer, offset, len);
offset += len;
return this;
}
/**
* Appends {@code char} array to buffer.
*/
public FastCharBuffer append(final char[] array) {
return append(array, 0, array.length);
}
/**
* Appends another fast buffer to this one.
*/
public FastCharBuffer append(final FastCharBuffer buff) {
if (buff.offset == 0) {
return this;
}
append(buff.buffer, 0, buff.offset);
return this;
}
/**
* Returns buffer size.
*/
public int size() {
return offset;
}
@Override
public int length() {
return offset;
}
/**
* Tests if this buffer has no elements.
*/
public boolean isEmpty() {
return offset == 0;
}
/**
* Resets the buffer content.
*/
public void clear() {
offset = 0;
}
/**
* Creates {@code char} array from buffered content.
*/
public char[] toArray() {
return Arrays.copyOf(buffer, offset);
}
/**
* Creates {@code char} subarray from buffered content.
*/
public char[] toArray(final int start, final int len) {
final char[] array = new char[len];
if (len == 0) {
return array;
}
System.arraycopy(buffer, start, array, 0, len);
return array;
}
/**
* Returns {@code char} element at given index.
*/
public char get(final int index) {
if (index >= offset) {
throw new IndexOutOfBoundsException();
}
return buffer[index];
}
/**
* Appends character sequence to buffer.
*/
@Override
public FastCharBuffer append(final CharSequence csq) {
append(csq, 0, csq.length());
return this;
}
/**
* Appends character sequence to buffer.
*/
@Override
public FastCharBuffer append(final CharSequence csq, final int start, final int end) {
for (int i = start; i < end; i++) {
append(csq.charAt(i));
}
return this;
}
@Override
public char charAt(final int index) {
return get(index);
}
@Override
public CharSequence subSequence(final int start, final int end) {
return new CharArraySequence(buffer, start, end - start);
}
/**
* Returns a String of the char buffer.
* Please use {@code StringBuilder} instead, it is faster.
*/
@Override
public String toString() {
return new String(toArray());
}
}

166
fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastDoubleBuffer.java

@ -1,166 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.buffer;
import java.util.Arrays;
/**
* Faster {@code double} buffer.
*/
public class FastDoubleBuffer {
private double[] buffer;
private int offset;
/**
* Creates a new {@code double} buffer. The buffer capacity is
* initially 64 doubles, though its size increases if necessary.
*/
public FastDoubleBuffer() {
this.buffer = new double[64];
}
/**
* Creates a new {@code double} buffer, with a buffer capacity of
* the specified size.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public FastDoubleBuffer(final int size) {
this.buffer = new double[size];
}
/**
* Grows the buffer.
*/
private void grow(final int minCapacity) {
final int oldCapacity = buffer.length;
int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0) {
// special case, min capacity is larger then a grow
newCapacity = minCapacity + 512;
}
buffer = Arrays.copyOf(buffer, newCapacity);
}
/**
* Appends single {@code double} to buffer.
*/
public void append(final double element) {
if (offset - buffer.length >= 0) {
grow(offset);
}
buffer[offset++] = element;
}
/**
* Appends {@code double} array to buffer.
*/
public FastDoubleBuffer append(final double[] array, final int off, final int len) {
if (offset + len - buffer.length > 0) {
grow(offset + len);
}
System.arraycopy(array, off, buffer, offset, len);
offset += len;
return this;
}
/**
* Appends {@code double} array to buffer.
*/
public FastDoubleBuffer append(final double[] array) {
return append(array, 0, array.length);
}
/**
* Appends another fast buffer to this one.
*/
public FastDoubleBuffer append(final FastDoubleBuffer buff) {
if (buff.offset == 0) {
return this;
}
append(buff.buffer, 0, buff.offset);
return this;
}
/**
* Returns buffer size.
*/
public int size() {
return offset;
}
/**
* Tests if this buffer has no elements.
*/
public boolean isEmpty() {
return offset == 0;
}
/**
* Resets the buffer content.
*/
public void clear() {
offset = 0;
}
/**
* Creates {@code double} array from buffered content.
*/
public double[] toArray() {
return Arrays.copyOf(buffer, offset);
}
/**
* Creates {@code double} subarray from buffered content.
*/
public double[] toArray(final int start, final int len) {
final double[] array = new double[len];
if (len == 0) {
return array;
}
System.arraycopy(buffer, start, array, 0, len);
return array;
}
/**
* Returns {@code double} element at given index.
*/
public double get(final int index) {
if (index >= offset) {
throw new IndexOutOfBoundsException();
}
return buffer[index];
}
}

165
fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastFloatBuffer.java

@ -1,165 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.buffer;
import java.util.Arrays;
/**
* Faster {@code float} buffer.
*/
public class FastFloatBuffer {
private float[] buffer;
private int offset;
/**
* Creates a new {@code float} buffer. The buffer capacity is
* initially 64 floats, though its size increases if necessary.
*/
public FastFloatBuffer() {
this.buffer = new float[64];
}
/**
* Creates a new {@code float} buffer, with a buffer capacity of
* the specified size.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public FastFloatBuffer(final int size) {
this.buffer = new float[size];
}
/**
* Grows the buffer.
*/
private void grow(final int minCapacity) {
final int oldCapacity = buffer.length;
int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0) {
// special case, min capacity is larger then a grow
newCapacity = minCapacity + 512;
}
buffer = Arrays.copyOf(buffer, newCapacity);
}
/**
* Appends single {@code float} to buffer.
*/
public void append(final float element) {
if (offset - buffer.length >= 0) {
grow(offset);
}
buffer[offset++] = element;
}
/**
* Appends {@code float} array to buffer.
*/
public FastFloatBuffer append(final float[] array, final int off, final int len) {
if (offset + len - buffer.length > 0) {
grow(offset + len);
}
System.arraycopy(array, off, buffer, offset, len);
offset += len;
return this;
}
/**
* Appends {@code float} array to buffer.
*/
public FastFloatBuffer append(final float[] array) {
return append(array, 0, array.length);
}
/**
* Appends another fast buffer to this one.
*/
public FastFloatBuffer append(final FastFloatBuffer buff) {
if (buff.offset == 0) {
return this;
}
append(buff.buffer, 0, buff.offset);
return this;
}
/**
* Returns buffer size.
*/
public int size() {
return offset;
}
/**
* Tests if this buffer has no elements.
*/
public boolean isEmpty() {
return offset == 0;
}
/**
* Resets the buffer content.
*/
public void clear() {
offset = 0;
}
/**
* Creates {@code float} array from buffered content.
*/
public float[] toArray() {
return Arrays.copyOf(buffer, offset);
}
/**
* Creates {@code float} subarray from buffered content.
*/
public float[] toArray(final int start, final int len) {
final float[] array = new float[len];
if (len == 0) {
return array;
}
System.arraycopy(buffer, start, array, 0, len);
return array;
}
/**
* Returns {@code float} element at given index.
*/
public float get(final int index) {
if (index >= offset) {
throw new IndexOutOfBoundsException();
}
return buffer[index];
}
}

166
fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastIntBuffer.java

@ -1,166 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.buffer;
import java.util.Arrays;
/**
* Faster {@code int} buffer.
*/
public class FastIntBuffer {
private int[] buffer;
private int offset;
/**
* Creates a new {@code int} buffer. The buffer capacity is
* initially 64 ints, though its size increases if necessary.
*/
public FastIntBuffer() {
this.buffer = new int[64];
}
/**
* Creates a new {@code int} buffer, with a buffer capacity of
* the specified size.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public FastIntBuffer(final int size) {
this.buffer = new int[size];
}
/**
* Grows the buffer.
*/
private void grow(final int minCapacity) {
final int oldCapacity = buffer.length;
int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0) {
// special case, min capacity is larger then a grow
newCapacity = minCapacity + 512;
}
buffer = Arrays.copyOf(buffer, newCapacity);
}
/**
* Appends single {@code int} to buffer.
*/
public void append(final int element) {
if (offset - buffer.length >= 0) {
grow(offset);
}
buffer[offset++] = element;
}
/**
* Appends {@code int} array to buffer.
*/
public FastIntBuffer append(final int[] array, final int off, final int len) {
if (offset + len - buffer.length > 0) {
grow(offset + len);
}
System.arraycopy(array, off, buffer, offset, len);
offset += len;
return this;
}
/**
* Appends {@code int} array to buffer.
*/
public FastIntBuffer append(final int[] array) {
return append(array, 0, array.length);
}
/**
* Appends another fast buffer to this one.
*/
public FastIntBuffer append(final FastIntBuffer buff) {
if (buff.offset == 0) {
return this;
}
append(buff.buffer, 0, buff.offset);
return this;
}
/**
* Returns buffer size.
*/
public int size() {
return offset;
}
/**
* Tests if this buffer has no elements.
*/
public boolean isEmpty() {
return offset == 0;
}
/**
* Resets the buffer content.
*/
public void clear() {
offset = 0;
}
/**
* Creates {@code int} array from buffered content.
*/
public int[] toArray() {
return Arrays.copyOf(buffer, offset);
}
/**
* Creates {@code int} subarray from buffered content.
*/
public int[] toArray(final int start, final int len) {
final int[] array = new int[len];
if (len == 0) {
return array;
}
System.arraycopy(buffer, start, array, 0, len);
return array;
}
/**
* Returns {@code int} element at given index.
*/
public int get(final int index) {
if (index >= offset) {
throw new IndexOutOfBoundsException();
}
return buffer[index];
}
}

166
fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastLongBuffer.java

@ -1,166 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.buffer;
import java.util.Arrays;
/**
* Faster {@code long} buffer.
*/
public class FastLongBuffer {
private long[] buffer;
private int offset;
/**
* Creates a new {@code long} buffer. The buffer capacity is
* initially 64 longs, though its size increases if necessary.
*/
public FastLongBuffer() {
this.buffer = new long[64];
}
/**
* Creates a new {@code long} buffer, with a buffer capacity of
* the specified size.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public FastLongBuffer(final int size) {
this.buffer = new long[size];
}
/**
* Grows the buffer.
*/
private void grow(final int minCapacity) {
final int oldCapacity = buffer.length;
int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0) {
// special case, min capacity is larger then a grow
newCapacity = minCapacity + 512;
}
buffer = Arrays.copyOf(buffer, newCapacity);
}
/**
* Appends single {@code long} to buffer.
*/
public void append(final long element) {
if (offset - buffer.length >= 0) {
grow(offset);
}
buffer[offset++] = element;
}
/**
* Appends {@code long} array to buffer.
*/
public FastLongBuffer append(final long[] array, final int off, final int len) {
if (offset + len - buffer.length > 0) {
grow(offset + len);
}
System.arraycopy(array, off, buffer, offset, len);
offset += len;
return this;
}
/**
* Appends {@code long} array to buffer.
*/
public FastLongBuffer append(final long[] array) {
return append(array, 0, array.length);
}
/**
* Appends another fast buffer to this one.
*/
public FastLongBuffer append(final FastLongBuffer buff) {
if (buff.offset == 0) {
return this;
}
append(buff.buffer, 0, buff.offset);
return this;
}
/**
* Returns buffer size.
*/
public int size() {
return offset;
}
/**
* Tests if this buffer has no elements.
*/
public boolean isEmpty() {
return offset == 0;
}
/**
* Resets the buffer content.
*/
public void clear() {
offset = 0;
}
/**
* Creates {@code long} array from buffered content.
*/
public long[] toArray() {
return Arrays.copyOf(buffer, offset);
}
/**
* Creates {@code long} subarray from buffered content.
*/
public long[] toArray(final int start, final int len) {
final long[] array = new long[len];
if (len == 0) {
return array;
}
System.arraycopy(buffer, start, array, 0, len);
return array;
}
/**
* Returns {@code long} element at given index.
*/
public long get(final int index) {
if (index >= offset) {
throw new IndexOutOfBoundsException();
}
return buffer[index];
}
}

165
fine-jodd/src/main/java/com/fr/third/jodd/buffer/FastShortBuffer.java

@ -1,165 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.buffer;
import java.util.Arrays;
/**
* Faster {@code short} buffer.
*/
public class FastShortBuffer {
private short[] buffer;
private int offset;
/**
* Creates a new {@code short} buffer. The buffer capacity is
* initially 64 shorts, though its size increases if necessary.
*/
public FastShortBuffer() {
this.buffer = new short[64];
}
/**
* Creates a new {@code short} buffer, with a buffer capacity of
* the specified size.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public FastShortBuffer(final int size) {
this.buffer = new short[size];
}
/**
* Grows the buffer.
*/
private void grow(final int minCapacity) {
final int oldCapacity = buffer.length;
int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0) {
// special case, min capacity is larger then a grow
newCapacity = minCapacity + 512;
}
buffer = Arrays.copyOf(buffer, newCapacity);
}
/**
* Appends single {@code short} to buffer.
*/
public void append(final short element) {
if (offset - buffer.length >= 0) {
grow(offset);
}
buffer[offset++] = element;
}
/**
* Appends {@code short} array to buffer.
*/
public FastShortBuffer append(final short[] array, final int off, final int len) {
if (offset + len - buffer.length > 0) {
grow(offset + len);
}
System.arraycopy(array, off, buffer, offset, len);
offset += len;
return this;
}
/**
* Appends {@code short} array to buffer.
*/
public FastShortBuffer append(final short[] array) {
return append(array, 0, array.length);
}
/**
* Appends another fast buffer to this one.
*/
public FastShortBuffer append(final FastShortBuffer buff) {
if (buff.offset == 0) {
return this;
}
append(buff.buffer, 0, buff.offset);
return this;
}
/**
* Returns buffer size.
*/
public int size() {
return offset;
}
/**
* Tests if this buffer has no elements.
*/
public boolean isEmpty() {
return offset == 0;
}
/**
* Resets the buffer content.
*/
public void clear() {
offset = 0;
}
/**
* Creates {@code short} array from buffered content.
*/
public short[] toArray() {
return Arrays.copyOf(buffer, offset);
}
/**
* Creates {@code short} subarray from buffered content.
*/
public short[] toArray(final int start, final int len) {
final short[] array = new short[len];
if (len == 0) {
return array;
}
System.arraycopy(buffer, start, array, 0, len);
return array;
}
/**
* Returns {@code short} element at given index.
*/
public short get(final int index) {
if (index >= offset) {
throw new IndexOutOfBoundsException();
}
return buffer[index];
}
}

29
fine-jodd/src/main/java/com/fr/third/jodd/buffer/package-info.java

@ -1,29 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/**
* Faster primitive buffers, a simple wrappers over an array.
*/
package com.fr.third.jodd.buffer;

344
fine-jodd/src/main/java/com/fr/third/jodd/cache/AbstractCacheMap.java vendored

@ -1,344 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cache;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.locks.StampedLock;
/**
* Default implementation of timed and size cache map.
* Implementations should:
* <ul>
* <li>create a new cache map</li>
* <li>implements own <code>prune</code> strategy</li>
* </ul>
* Uses <code>ReentrantReadWriteLock</code> to synchronize access.
* Since upgrading from a read lock to the write lock is not possible,
* be careful withing {@link #get(Object)} method.
*/
public abstract class AbstractCacheMap<K,V> implements Cache<K,V> {
static class CacheObject<K2,V2> {
CacheObject(final K2 key, final V2 object, final long ttl) {
this.key = key;
this.cachedObject = object;
this.ttl = ttl;
this.lastAccess = System.currentTimeMillis();
}
final K2 key;
final V2 cachedObject;
long lastAccess; // time of last access
long accessCount; // number of accesses
long ttl; // objects timeout (time-to-live), 0 = no timeout
boolean isExpired() {
if (ttl == 0) {
return false;
}
return lastAccess + ttl < System.currentTimeMillis();
}
V2 getObject() {
lastAccess = System.currentTimeMillis();
accessCount++;
return cachedObject;
}
V2 peekObject() {
return cachedObject;
}
}
protected Map<K,CacheObject<K,V>> cacheMap;
private final StampedLock lock = new StampedLock();
// ---------------------------------------------------------------- properties
protected int cacheSize; // max cache size, 0 = no limit
/**
* {@inheritDoc}
*/
@Override
public int limit() {
return cacheSize;
}
protected long timeout; // default timeout, 0 = no timeout
/**
* Returns default cache timeout or <code>0</code> if it is not set.
* Timeout can be set individually for each object.
*/
@Override
public long timeout() {
return timeout;
}
/**
* Identifies if objects has custom timeouts.
* Should be used to determine if prune for existing objects is needed.
*/
protected boolean existCustomTimeout;
/**
* Returns <code>true</code> if prune of expired objects should be invoked.
* For internal use.
*/
protected boolean isPruneExpiredActive() {
return (timeout != 0) || existCustomTimeout;
}
// ---------------------------------------------------------------- put
/**
* {@inheritDoc}
*/
@Override
public void put(final K key, final V object) {
put(key, object, timeout);
}
/**
* {@inheritDoc}
*/
@Override
public void put(final K key, final V object, final long timeout) {
Objects.requireNonNull(object);
final long stamp = lock.writeLock();
try {
final CacheObject<K,V> co = createCacheObject(key, object, timeout);
if (timeout != 0) {
existCustomTimeout = true;
}
if (isReallyFull(key)) {
pruneCache();
}
cacheMap.put(key, co);
}
finally {
lock.unlockWrite(stamp);
}
}
protected CacheObject<K, V> createCacheObject(K key, V object, long timeout) {
return new CacheObject<>(key, object, timeout);
}
// ---------------------------------------------------------------- get
protected int hitCount;
protected int missCount;
/**
* Returns hit count.
*/
public int getHitCount() {
return hitCount;
}
/**
* Returns miss count.
*/
public int getMissCount() {
return missCount;
}
/**
* {@inheritDoc}
*/
@Override
public V get(final K key) {
long stamp = lock.readLock();
try {
final CacheObject<K,V> co = cacheMap.get(key);
if (co == null) {
missCount++;
return null;
}
if (co.isExpired()) {
final long newStamp = lock.tryConvertToWriteLock(stamp);
if (newStamp != 0L) {
stamp = newStamp;
// lock is upgraded to write lock
}
else {
// manually upgrade lock to write lock
lock.unlockRead(stamp);
stamp = lock.writeLock();
}
final CacheObject<K,V> removedCo = cacheMap.remove(key);
if (removedCo != null) {
onRemove(removedCo.key, removedCo.cachedObject);
}
missCount++;
return null;
}
hitCount++;
return co.getObject();
}
finally {
lock.unlock(stamp);
}
}
// ---------------------------------------------------------------- prune
/**
* Prune implementation.
*/
protected abstract int pruneCache();
/**
* {@inheritDoc}
*/
@Override
public final int prune() {
final long stamp = lock.writeLock();
try {
return pruneCache();
}
finally {
lock.unlockWrite(stamp);
}
}
// ---------------------------------------------------------------- common
/**
* {@inheritDoc}
*/
@Override
public boolean isFull() {
if (cacheSize == 0) {
return false;
}
return cacheMap.size() >= cacheSize;
}
protected boolean isReallyFull(final K key) {
if (cacheSize == 0) {
return false;
}
if (cacheMap.size() >= cacheSize) {
return !cacheMap.containsKey(key);
}
else {
return false;
}
}
/**
* {@inheritDoc}
*/
@Override
public V remove(final K key) {
V removedValue = null;
final long stamp = lock.writeLock();
try {
final CacheObject<K,V> co = cacheMap.remove(key);
if (co != null) {
onRemove(co.key, co.cachedObject);
removedValue = co.cachedObject;
}
}
finally {
lock.unlockWrite(stamp);
}
return removedValue;
}
/**
* {@inheritDoc}
*/
@Override
public void clear() {
final long stamp = lock.writeLock();
try {
cacheMap.clear();
}
finally {
lock.unlockWrite(stamp);
}
}
/**
* {@inheritDoc}
*/
@Override
public int size() {
return cacheMap.size();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isEmpty() {
return size() == 0;
}
/**
* {@inheritDoc}
*/
@Override
public Map<K, V> snapshot(final boolean peek) {
final long stamp = lock.writeLock();
try {
final Map<K, V> map = new HashMap<>(cacheMap.size());
cacheMap.forEach((key, cacheValue) -> {
if (!cacheValue.isExpired()) {
map.put(key, peek ? cacheValue.peekObject() : cacheValue.getObject());
}
});
return map;
}
finally {
lock.unlockWrite(stamp);
}
}
// ---------------------------------------------------------------- protected
/**
* Callback called on item removal. The cache is still locked.
*/
protected void onRemove(final K key, final V cachedObject) {
}
}

108
fine-jodd/src/main/java/com/fr/third/jodd/cache/Cache.java vendored

@ -1,108 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cache;
import java.util.Map;
/**
* Cache interface.
*/
public interface Cache<K, V> {
/**
* Returns cache size or <code>0</code> if there is no size limit.
*/
int limit();
/**
* Returns default timeout or <code>0</code> if it is not set.
*/
long timeout();
/**
* Adds an object to the cache with default timeout.
* @see Cache#put(Object, Object, long)
*/
void put(K key, V object);
/**
* Adds an object to the cache with specified timeout after which it becomes expired.
* If cache is full, {@link #prune()} is invoked to make room for new object.
* Cached value must be non-null.
*/
void put(K key, V object, long timeout);
/**
* Retrieves an object from the cache. Returns <code>null</code> if object
* is not longer in cache or if it is expired.
*/
V get(K key);
/**
* Prunes objects from cache and returns the number of removed objects.
* Used strategy depends on cache implementation.
*/
int prune();
/**
* Returns <code>true</code> if max cache capacity has been reached
* only if cache is size limited.
*/
boolean isFull();
/**
* Removes an object from the cache and returns removed value of {@code null}
* if object was not in the cache or was expired.
*/
V remove(K key);
/**
* Clears current cache.
*/
void clear();
/**
* Returns current cache size.
*/
int size();
/**
* Returns <code>true</code> if cache is empty.
*/
boolean isEmpty();
/**
* Creates a snapshot from current cache values. Returned values may not
* longer be valid or they might be already expired! Cache is locked during
* the snapshot creation.
* @param peek if set, snapshot will just peek the object and not get them (and modify last access)
*/
Map<K, V> snapshot(boolean peek);
default Map<K, V> snapshot() {
return this.snapshot(false);
}
}

89
fine-jodd/src/main/java/com/fr/third/jodd/cache/FIFOCache.java vendored

@ -1,89 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cache;
import java.util.Iterator;
import java.util.LinkedHashMap;
/**
* FIFO (first in first out) cache.
*
* <p>
* FIFO (first in first out): just adds items to the cache as they are accessed, putting them in a queue or buffer and
* not changing their location in the buffer; when the cache is full, items are ejected in the order they were
* added. Cache access overhead is constant time regardless of the size of the cache. The advantage of this algorithm
* is that it's simple and fast; it can be implemented using a simple array and an index. The disadvantage is that
* it's not very smart; it doesn't make any effort to keep more commonly used items in cache.
* <p>
* Summary for FIFO: fast, not adaptive, not scan resistant.
*/
public class FIFOCache<K, V> extends AbstractCacheMap<K, V> {
public FIFOCache(final int cacheSize) {
this(cacheSize, 0);
}
/**
* Creates a new LRU cache.
*/
public FIFOCache(final int cacheSize, final long timeout) {
this.cacheSize = cacheSize;
this.timeout = timeout;
cacheMap = new LinkedHashMap<>(cacheSize + 1, 1.0f, false);
}
// ---------------------------------------------------------------- prune
/**
* Prune expired objects and, if cache is still full, the first one.
*/
@Override
protected int pruneCache() {
int count = 0;
CacheObject<K,V> first = null;
Iterator<CacheObject<K,V>> values = cacheMap.values().iterator();
while (values.hasNext()) {
CacheObject<K,V> co = values.next();
if (co.isExpired()) {
values.remove();
onRemove(co.key, co.cachedObject);
count++;
}
if (first == null) {
first = co;
}
}
if (isFull()) {
if (first != null) {
cacheMap.remove(first.key);
onRemove(first.key, first.cachedObject);
count++;
}
}
return count;
}
}

153
fine-jodd/src/main/java/com/fr/third/jodd/cache/FileCache.java vendored

@ -1,153 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cache;
import com.fr.third.jodd.io.FileUtil;
import java.io.File;
import java.io.IOException;
/**
* Base in-memory files cache.
*/
public abstract class FileCache {
protected final Cache<File, byte[]> cache;
protected final int maxSize;
protected final int maxFileSize;
protected final long timeout;
protected int usedSize;
/**
* Creates new File LFU cache.
* @param maxSize total cache size in bytes
* @param maxFileSize max available file size in bytes, may be 0
* @param timeout timeout, may be 0
*/
protected FileCache(final int maxSize, final int maxFileSize, final long timeout) {
this.maxSize = maxSize;
this.maxFileSize = maxFileSize;
this.timeout = timeout;
this.cache = createCache();
}
/**
* Creates new cache instance for files content.
*/
protected abstract Cache<File, byte[]> createCache();
/**
* Creates CacheObject that updates last access time based on files last modification.
*/
protected AbstractCacheMap.CacheObject<File, byte[]> createFileCacheObject(File fileKey, byte[] object, long timeout) {
return new AbstractCacheMap.CacheObject<File, byte[]>(fileKey, object, timeout) {
@Override
boolean isExpired() {
if (fileKey.lastModified() > this.lastAccess) {
this.lastAccess = fileKey.lastModified();
}
return super.isExpired();
}
};
}
// ---------------------------------------------------------------- get
/**
* Returns max cache size in bytes.
*/
public int maxSize() {
return maxSize;
}
/**
* Returns actually used size in bytes.
*/
public int usedSize() {
return usedSize;
}
/**
* Returns maximum allowed file size that can be added to the cache.
* Files larger than this value will be not added, even if there is
* enough room.
*/
public int maxFileSize() {
return maxFileSize;
}
/**
* Returns number of cached files.
*/
public int cachedFilesCount() {
return cache.size();
}
/**
* Returns timeout.
*/
public long cacheTimeout() {
return cache.timeout();
}
/**
* Clears the cache.
*/
public void clear() {
cache.clear();
usedSize = 0;
}
// ---------------------------------------------------------------- get
/**
* Returns cached file bytes. If file is not cached it will be
* read and put in the cache (if all the rules are satisfied).
*/
public byte[] getFileBytes(final File file) throws IOException {
byte[] bytes = cache.get(file);
if (bytes != null) {
return bytes;
}
// add file
bytes = FileUtil.readBytes(file);
if ((maxFileSize != 0) && (file.length() > maxFileSize)) {
// don't cache files that size exceed max allowed file size
return bytes;
}
usedSize += bytes.length;
// put file into cache
// if used size > total, purge() will be invoked
cache.put(file, bytes);
return bytes;
}
}

82
fine-jodd/src/main/java/com/fr/third/jodd/cache/FileLFUCache.java vendored

@ -1,82 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cache;
import java.io.File;
/**
* Files LFU cache stores files content in memory to dramatically
* speed up performances for frequently read files.
*/
public class FileLFUCache extends FileCache {
/**
* Creates file LFU cache with specified size. Sets
* {@link #maxFileSize max available file size} to half of this value.
*/
public FileLFUCache(final int maxSize) {
this(maxSize, maxSize / 2, 0);
}
public FileLFUCache(final int maxSize, final int maxFileSize) {
this(maxSize, maxFileSize, 0);
}
/**
* Creates new File LFU cache.
* @param maxSize total cache size in bytes
* @param maxFileSize max available file size in bytes, may be 0
* @param timeout timeout, may be 0
*/
public FileLFUCache(final int maxSize, final int maxFileSize, final long timeout) {
super(maxSize, maxFileSize, timeout);
}
@Override
protected Cache<File, byte[]> createCache() {
return new LFUCache<File, byte[]>(0, timeout) {
@Override
public boolean isFull() {
return usedSize > FileLFUCache.this.maxSize;
}
@Override
protected boolean isReallyFull(final File file) {
return isFull();
}
@Override
protected void onRemove(final File key, final byte[] cachedObject) {
usedSize -= cachedObject.length;
}
@Override
protected CacheObject<File, byte[]> createCacheObject(File key, byte[] object, long timeout) {
return createFileCacheObject(key, object, timeout);
}
};
}
}

81
fine-jodd/src/main/java/com/fr/third/jodd/cache/FileLRUCache.java vendored

@ -1,81 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cache;
import java.io.File;
/**
* Cache of recently used files.
*/
public class FileLRUCache extends FileCache {
/**
* Creates file LRU cache with specified size. Sets
* {@link #maxFileSize max available file size} to half of this value.
*/
public FileLRUCache(final int maxSize) {
this(maxSize, maxSize / 2, 0);
}
public FileLRUCache(final int maxSize, final int maxFileSize) {
this(maxSize, maxFileSize, 0);
}
/**
* Creates new File LRU cache.
* @param maxSize total cache size in bytes
* @param maxFileSize max available file size in bytes, may be 0
* @param timeout timeout, may be 0
*/
public FileLRUCache(final int maxSize, final int maxFileSize, final long timeout) {
super(maxSize, maxFileSize, timeout);
}
@Override
protected Cache<File, byte[]> createCache() {
return new LRUCache<File, byte[]>(0, timeout) {
@Override
public boolean isFull() {
return usedSize > FileLRUCache.this.maxSize;
}
@Override
protected boolean isReallyFull(final File file) {
return isFull();
}
@Override
protected void onRemove(final File key, final byte[] cachedObject) {
usedSize -= cachedObject.length;
}
@Override
protected CacheObject<File, byte[]> createCacheObject(File key, byte[] object, long timeout) {
return createFileCacheObject(key, object, timeout);
}
};
}
}

111
fine-jodd/src/main/java/com/fr/third/jodd/cache/LFUCache.java vendored

@ -1,111 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cache;
import java.util.HashMap;
import java.util.Iterator;
/**
* LFU (least frequently used) cache. Frequency is calculated as access count. This cache
* is resistant on 'new usages scenario': when some object is removed from the cache,
* access count of all items in cache is decreased by access count of removed value.
* This allows new frequent elements to come into the cache.
* <p>
* Frequency of use data is kept on all items. The most frequently used items are kept in the cache.
* Because of the bookkeeping requirements, cache access overhead increases logarithmically with cache size.
* The advantage is that long term usage patterns are captured well, incidentally making the algorithm scan resistant;
* the disadvantage, besides the larger access overhead, is that the algorithm doesn't adapt quickly to changing
* usage patterns, and in particular doesn't help with temporally clustered accesses.
* <p>
* Summary for LFU: not fast, captures frequency of use, scan resistant.
*/
public class LFUCache<K,V> extends AbstractCacheMap<K,V> {
public LFUCache(final int maxSize) {
this(maxSize, 0);
}
public LFUCache(final int maxSize, final long timeout) {
this.cacheSize = maxSize;
this.timeout = timeout;
cacheMap = new HashMap<>(maxSize + 1);
}
// ---------------------------------------------------------------- prune
/**
* Prunes expired and, if cache is still full, the LFU element(s) from the cache.
* On LFU removal, access count is normalized to value which had removed object.
* Returns the number of removed objects.
*/
@Override
protected int pruneCache() {
int count = 0;
CacheObject<K,V> comin = null;
// remove expired items and find cached object with minimal access count
Iterator<CacheObject<K,V>> values = cacheMap.values().iterator();
while (values.hasNext()) {
CacheObject<K,V> co = values.next();
if (co.isExpired()) {
values.remove();
onRemove(co.key, co.cachedObject);
count++;
continue;
}
if (comin == null) {
comin = co;
} else {
if (co.accessCount < comin.accessCount) {
comin = co;
}
}
}
if (!isFull()) {
return count;
}
// decrease access count to all cached objects
if (comin != null) {
long minAccessCount = comin.accessCount;
values = cacheMap.values().iterator();
while (values.hasNext()) {
CacheObject<K, V> co = values.next();
co.accessCount -= minAccessCount;
if (co.accessCount <= 0) {
values.remove();
onRemove(co.key, co.cachedObject);
count++;
}
}
}
return count;
}
}

103
fine-jodd/src/main/java/com/fr/third/jodd/cache/LRUCache.java vendored

@ -1,103 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cache;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Iterator;
/**
* LRU (least recently used) cache.
*
* <p>
* Items are added to the cache as they are accessed; when the cache is full, the least recently used item is ejected.
* This type of cache is typically implemented as a linked list, so that an item in cache, when it is accessed again,
* can be moved back up to the head of the queue; items are ejected from the tail of the queue. Cache access overhead
* is again constant time. This algorithm is simple and fast, and it has a significant advantage over FIFO in being
* able to adapt somewhat to the data access pattern; frequently used items are less likely to be
* ejected from the cache. The main disadvantage is that it can still get filled up with items that are
* unlikely to be reaccessed soon; in particular, it can become useless in the face of scanning type accesses.
* Nonetheless, this is by far the most frequently used caching algorithm.
* <p>
* Implementation note: unfortunately, it was not possible to have <code>onRemove</code> callback method,
* since <code>LinkedHashMap</code> has its removal methods private.
* <p>
* Summary for LRU: fast, adaptive, not scan resistant.
*/
public class LRUCache<K, V> extends AbstractCacheMap<K, V> {
public LRUCache(final int cacheSize) {
this(cacheSize, 0);
}
/**
* Creates a new LRU cache.
*/
public LRUCache(final int cacheSize, final long timeout) {
this.cacheSize = cacheSize;
this.timeout = timeout;
cacheMap = new LinkedHashMap<K, CacheObject<K,V>>(cacheSize + 1, 1.0f, true) {
@Override
protected boolean removeEldestEntry(final Map.Entry eldest) {
return LRUCache.this.removeEldestEntry(size());
}
};
}
/**
* Removes the eldest entry if current cache size exceed cache size.
*/
protected boolean removeEldestEntry(final int currentSize) {
if (cacheSize == 0) {
return false;
}
return currentSize > cacheSize;
}
// ---------------------------------------------------------------- prune
/**
* Prune only expired objects, <code>LinkedHashMap</code> will take care of LRU if needed.
*/
@Override
protected int pruneCache() {
if (!isPruneExpiredActive()) {
return 0;
}
int count = 0;
Iterator<CacheObject<K,V>> values = cacheMap.values().iterator();
while (values.hasNext()) {
CacheObject<K,V> co = values.next();
if (co.isExpired()) {
values.remove();
onRemove(co.key, co.cachedObject);
count++;
}
}
return count;
}
}

96
fine-jodd/src/main/java/com/fr/third/jodd/cache/NoCache.java vendored

@ -1,96 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cache;
import java.util.Collections;
import java.util.Map;
/**
* Simple no-cache implementations of {@link Cache} for situation when cache
* needs to be quickly turned-off.
*/
public class NoCache<K, V> implements Cache<K, V> {
@Override
public int limit() {
return 0;
}
@Override
public long timeout() {
return 0;
}
@Override
public void put(final K key, final V object) {
// ignore
}
@Override
public void put(final K key, final V object, final long timeout) {
// ignore
}
@Override
public V get(final K key) {
return null;
}
@Override
public int prune() {
return 0;
}
@Override
public boolean isFull() {
return true;
}
@Override
public V remove(final K key) {
return null;
}
@Override
public void clear() {
// ignore
}
@Override
public int size() {
return 0;
}
@Override
public boolean isEmpty() {
return true;
}
@Override
public Map<K, V> snapshot(final boolean peek) {
return Collections.emptyMap();
}
}

98
fine-jodd/src/main/java/com/fr/third/jodd/cache/TimedCache.java vendored

@ -1,98 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cache;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
/**
* Timed cache. Not limited by size, objects are removed only when they are expired.
* Prune is not invoked explicitly by standard {@link Cache} methods, however,
* it is possible to schedule prunes on fined-rate delays.
*/
public class TimedCache<K, V> extends AbstractCacheMap<K, V> {
public TimedCache(final long timeout) {
this.cacheSize = 0;
this.timeout = timeout;
cacheMap = new HashMap<>();
}
// ---------------------------------------------------------------- prune
/**
* Prunes expired elements from the cache. Returns the number of removed objects.
*/
@Override
protected int pruneCache() {
int count = 0;
Iterator<CacheObject<K,V>> values = cacheMap.values().iterator();
while (values.hasNext()) {
CacheObject co = values.next();
if (co.isExpired()) {
values.remove();
count++;
}
}
return count;
}
// ---------------------------------------------------------------- auto prune
protected Timer pruneTimer;
/**
* Schedules prune.
*/
public void schedulePrune(final long delay) {
if (pruneTimer != null) {
pruneTimer.cancel();
}
pruneTimer = new Timer();
pruneTimer.schedule(
new TimerTask() {
@Override
public void run() {
prune();
}
}, delay, delay
);
}
/**
* Cancels prune schedules.
*/
public void cancelPruneSchedule() {
if (pruneTimer != null) {
pruneTimer.cancel();
pruneTimer = null;
}
}
}

205
fine-jodd/src/main/java/com/fr/third/jodd/cache/TypeCache.java vendored

@ -1,205 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cache;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* Types cache. Provides several implementations depending on what you need to be addressed.
* There are two things you should take care off:
* <ul>
* <li>synchronization - especially on storing items. If not synchronized, one instance of an item may be put
* more then once into the map. This is usually fine, as it happens only during the initialization and makes not
* harm if something is created twice</li>
* <li>weak - if your key classes are replaced during the runtime, you should use weak map, in order to automatically
* remove obsolete keys.</li>
* </ul>
*/
public class TypeCache<T> {
// ---------------------------------------------------------------- builder
/**
* Creates a type cache by using a builder.
*/
public static <A> Builder<A> create() {
return new Builder<>();
}
/**
* Creates default implementation of the type cache.
*/
@SuppressWarnings("unchecked")
public static <A> TypeCache<A> createDefault() {
return TypeCache.<A>create().get();
}
public static class Builder<A> {
private boolean threadsafe;
private boolean weak;
private boolean none;
/**
* No cache will be used.
* Setting other properties will not have any affect.
*/
public Builder<A> noCache() {
none = true;
return this;
}
/**
* Cache keys will be weak.
*/
public Builder<A> weak(final boolean weak) {
this.weak = weak;
return this;
}
/**
* Cache will be thread-safe.
*/
public Builder<A> threadsafe(final boolean threadsafe) {
this.threadsafe = threadsafe;
return this;
}
/**
* Builds a type cache.
*/
public TypeCache<A> get() {
final Map<Class<?>, A> map;
if (none) {
map = new AbstractMap<Class<?>, A>() {
@Override
public A put(final Class<?> key, final A value) {
return null;
}
@Override
public A get(final Object key) {
return null;
}
@Override
public Set<Entry<Class<?>, A>> entrySet() {
return Collections.emptySet();
}
};
}
else if (weak) {
if (threadsafe) {
map = Collections.synchronizedMap(new WeakHashMap<>());
} else {
map = new WeakHashMap<>();
}
} else {
if (threadsafe) {
map = new ConcurrentHashMap<>();
} else {
map = new IdentityHashMap<>();
}
}
return new TypeCache<>(map);
}
}
// ---------------------------------------------------------------- map
private final Map<Class<?>, T> map;
private TypeCache(final Map<Class<?>, T> backedMap) {
this.map = backedMap;
}
/**
* Add values to the map.
*/
public T put(final Class<?> type, final T value) {
return map.put(type, value);
}
/**
* Returns value from the map or {@code null} if value does not exist.
*/
public T get(final Class<?> key) {
return map.get(key);
}
/**
* Returns existing value or add default supplied one.
* Use this method instead of {@code get-nullcheck-put} block when
* thread-safety is of importance.
*/
@SuppressWarnings("unchecked")
public <K> T get(final Class<K> key, final Function<Class<K>, ? extends T> mappingFunction) {
return map.computeIfAbsent(key, aClass -> mappingFunction.apply((Class<K>) aClass));
}
/**
* Removes element from the type cache.
*/
public T remove(final Class<?> type) {
return map.remove(type);
}
/**
* Clears complete cache.
*/
public void clear() {
map.clear();
}
/**
* Returns cache size.
*/
public int size() {
return map.size();
}
/**
* Returns {@code true} if cache is empty.
*/
public boolean isEmpty() {
return map.isEmpty();
}
/**
* Iterates all cached values.
*/
public void forEachValue(final Consumer<? super T> valueConsumer) {
map.values().forEach(valueConsumer);
}
}

29
fine-jodd/src/main/java/com/fr/third/jodd/cache/package-info.java vendored

@ -1,29 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/**
* Some useful caches: LRU, LFU, FIFO.
*/
package com.fr.third.jodd.cache;

298
fine-jodd/src/main/java/com/fr/third/jodd/chalk/Chalk.java

@ -1,298 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.chalk;
import com.fr.third.jodd.util.StringPool;
/**
* Chalk allows you to color output going to console.
* @see Chalk256
*/
public class Chalk<T extends Chalk<T>> {
/**
* Global flag that disables all the chalks.
* Useful for windows platforms :)
*/
public static boolean enabled = true;
protected static final String RESET = "0";
protected static final String BOLD = "1";
protected static final String UNBOLD = "22"; // 21 isn't widely supported and 22 does the same thing
protected static final String DIM = "2";
protected static final String UNDIM = "22";
protected static final String ITALIC = "3";
protected static final String UNITALIC = "23";
protected static final String UNDERLINE = "4";
protected static final String UNUNDERLINE = "24";
protected static final String INVERSE = "7";
protected static final String UNINVERSE = "27";
protected static final String HIDDEN = "8";
protected static final String UNHIDDEN = "28";
protected static final String STRIKETHROUGH = "9";
protected static final String UNSTRIKETHROUGH = "29";
protected static final String COLOR_RESET = "39";
protected static final String BLACK = "30";
protected static final String RED = "31";
protected static final String GREEN = "32";
protected static final String YELLOW = "33";
protected static final String BLUE = "34";
protected static final String MAGENTA = "35";
protected static final String CYAN = "36";
protected static final String WHITE = "37";
protected static final String GRAY = "90";
protected static final String BGCOLOR_RESET = "49";
protected static final String BGBLACK = "40";
protected static final String BGRED = "41";
protected static final String BGGREEN = "42";
protected static final String BGYELLOW = "43";
protected static final String BGBLUE = "44";
protected static final String BGMAGENTA = "45";
protected static final String BGCYAN = "46";
protected static final String BGWHITE = "47";
protected StringBuilder prefix;
protected StringBuilder suffix;
protected String text;
/**
* Creates new chalk.
*/
public static Chalk chalk() {
return new Chalk();
}
@SuppressWarnings("unchecked")
protected T _this() {
return (T) this;
}
// ---------------------------------------------------------------- style
public T bold() {
startSequence(BOLD);
endSequence(UNBOLD);
return _this();
}
public T italic() {
startSequence(ITALIC);
endSequence(UNITALIC);
return _this();
}
public T dim() {
startSequence(DIM);
endSequence(UNDIM);
return _this();
}
public T underline() {
startSequence(UNDERLINE);
endSequence(UNUNDERLINE);
return _this();
}
public T inverse() {
startSequence(INVERSE);
endSequence(UNINVERSE);
return _this();
}
public T hidden() {
startSequence(HIDDEN);
endSequence(UNHIDDEN);
return _this();
}
public T strikeThrough() {
startSequence(STRIKETHROUGH);
endSequence(UNSTRIKETHROUGH);
return _this();
}
// ---------------------------------------------------------------- colors
public T black() {
startSequence(BLACK);
endSequence(COLOR_RESET);
return _this();
}
public T red() {
startSequence(RED);
endSequence(COLOR_RESET);
return _this();
}
public T green() {
startSequence(GREEN);
endSequence(COLOR_RESET);
return _this();
}
public T yellow() {
startSequence(YELLOW);
endSequence(COLOR_RESET);
return _this();
}
public T blue() {
startSequence(BLUE);
endSequence(COLOR_RESET);
return _this();
}
public T magenta() {
startSequence(MAGENTA);
endSequence(COLOR_RESET);
return _this();
}
public T cyan() {
startSequence(CYAN);
endSequence(COLOR_RESET);
return _this();
}
public T white() {
startSequence(WHITE);
endSequence(COLOR_RESET);
return _this();
}
public T gray() {
startSequence(GRAY);
endSequence(COLOR_RESET);
return _this();
}
public T grey() {
return gray();
}
// ---------------------------------------------------------------- bg colors
public T bgBlack() {
startSequence(BGBLACK);
endSequence(BGCOLOR_RESET);
return _this();
}
public T bgRed() {
startSequence(BGRED);
endSequence(BGCOLOR_RESET);
return _this();
}
public T bgGreen() {
startSequence(BGGREEN);
endSequence(BGCOLOR_RESET);
return _this();
}
public T bgYellow() {
startSequence(BGYELLOW);
endSequence(BGCOLOR_RESET);
return _this();
}
public T bgBlue() {
startSequence(BGBLUE);
endSequence(BGCOLOR_RESET);
return _this();
}
public T bgMagenta() {
startSequence(BGMAGENTA);
endSequence(BGCOLOR_RESET);
return _this();
}
public T bgCyan() {
startSequence(BGCYAN);
endSequence(BGCOLOR_RESET);
return _this();
}
public T bgWhite() {
startSequence(BGWHITE);
endSequence(BGCOLOR_RESET);
return _this();
}
// ---------------------------------------------------------------- internal
protected void startSequence(final String value) {
if (prefix == null) {
prefix = new StringBuilder();
prefix.append("\u001B[");
}
else {
prefix.append(StringPool.SEMICOLON);
}
prefix.append(value);
}
protected void endSequence(final String value) {
if (suffix == null) {
suffix = new StringBuilder();
suffix
.append("\u001B[")
.append(value);
}
else {
suffix.insert(2, value + StringPool.SEMICOLON);
}
}
// ---------------------------------------------------------------- out
/**
* Returns chalked string.
*/
public String on(final String string) {
if (!enabled) {
return string;
}
final StringBuilder sb = new StringBuilder();
if (prefix != null) {
sb.append(prefix).append("m");
}
sb.append(string);
if (suffix != null) {
sb.append(suffix).append("m");
}
return sb.toString();
}
/**
* Prints chalked string to system output.
*/
public void print(final String string) {
System.out.print(on(string));
}
/**
* Prints chalked string to system output.
*/
public void println(final String string) {
System.out.println(on(string));
}
}

123
fine-jodd/src/main/java/com/fr/third/jodd/chalk/Chalk256.java

@ -1,123 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.chalk;
/**
* Chalk256 allows you to color output going to ansi-256 console.
* @see Chalk
*/
public class Chalk256 extends Chalk<Chalk256> {
private static final String[] FG_CODES = new String[256];
private static final String[] BG_CODES = new String[256];
static {
for (int i = 0; i < FG_CODES.length; i++) {
FG_CODES[i] = "38;5;" + i;
}
for (int i = 0; i < BG_CODES.length; i++) {
BG_CODES[i] = "48;5;" + i;
}
}
public static Chalk256 chalk() {
return new Chalk256();
}
// ---------------------------------------------------------------- fg codes
public Chalk256 standard(final int index) {
startSequence(FG_CODES[index(index, 0, 8)]);
endSequence(RESET);
return _this();
}
public Chalk256 bright(final int index) {
startSequence(FG_CODES[index(index, 8, 16)]);
endSequence(RESET);
return _this();
}
public Chalk256 rgb(final int index) {
startSequence(FG_CODES[index(index, 16, 232)]);
endSequence(RESET);
return _this();
}
/**
* Colors with red-green-blue value, in the range 0 to 6.
*/
public Chalk256 rgb(final int r, final int b, final int g) {
startSequence(FG_CODES[index(36*r + 6*g + b,16, 232)]);
endSequence(RESET);
return _this();
}
public Chalk256 grayscale(final int index) {
startSequence(FG_CODES[index(index, 232, 256)]);
endSequence(RESET);
return _this();
}
// ---------------------------------------------------------------- bg codes
public Chalk256 bgStandard(final int index) {
startSequence(BG_CODES[index(index, 0, 8)]);
endSequence(RESET);
return _this();
}
public Chalk256 bgBright(final int index) {
startSequence(BG_CODES[index(index, 8, 16)]);
endSequence(RESET);
return _this();
}
public Chalk256 bgRgb(final int index) {
startSequence(BG_CODES[index(index, 16, 232)]);
endSequence(RESET);
return _this();
}
/**
* Colors with red-green-blue value, in the range 0 to 6.
*/
public Chalk256 bgRgb(final int r, final int b, final int g) {
startSequence(BG_CODES[index(36*r + 6*g + b,16, 232)]);
endSequence(RESET);
return _this();
}
public Chalk256 bgGrayscale(final int index) {
startSequence(BG_CODES[index(index, 232, 256)]);
endSequence(RESET);
return _this();
}
// ---------------------------------------------------------------- bgcolors
private int index(int index, final int from, final int to) {
index += from;
if ((index < from) || (index >= to)) {
throw new IllegalArgumentException("Color index not in range: [0, " + (to - from) + "]");
}
return index;
}
}

29
fine-jodd/src/main/java/com/fr/third/jodd/chalk/package-info.java

@ -1,29 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/**
* Little tool for coloring the console output.
*/
package com.fr.third.jodd.chalk;

233
fine-jodd/src/main/java/com/fr/third/jodd/cli/Cli.java

@ -1,233 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cli;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class Cli implements Consumer<String[]> {
private final List<Option> options = new ArrayList<>();
private final List<Param> params = new ArrayList<>();
public Option option() {
final Option option = new Option();
options.add(option);
return option;
}
public Param param() {
final Param param = new Param();
params.add(param);
return param;
}
private boolean consumeOptionWithLongName(final String input, final String valueToConsume) {
for (final Option option : options) {
if (input.equals(option.longName)) {
if (option.hasArg && valueToConsume == null) {
throw new CliException("Option value not provided for: " + input);
}
option.consumer.accept(option.hasArg ? valueToConsume : input);
return option.hasArg;
}
if (option.longName != null && input.startsWith(option.longName + "=")) {
option.consumer.accept(input.substring(option.longName.length() + 1));
return false;
}
}
throw new CliException("Unknown option: " + input);
}
private boolean consumeOptionWithShortName(final String input, final String valueToConsume) {
for (final Option option : options) {
if (input.equals(option.shortName)) {
if (option.hasArg) {
if (valueToConsume == null) {
throw new CliException("Option value not provided for: " + input);
}
option.consumer.accept(valueToConsume);
return true;
}
else {
option.consumer.accept(input);
return false;
}
}
if (option.shortName != null && input.startsWith(option.shortName + "=")) {
option.consumer.accept(input.substring(option.shortName.length() + 1));
return false;
}
}
throw new CliException("Unknown option: " + input);
}
private void consumeOptionWithShortNameAndNoArguments(final String shortName) {
for (final Option option : options) {
if (shortName.equals(option.shortName) && !option.hasArg) {
option.consumer.accept(shortName);
return;
}
}
throw new CliException("Unknown option: " + shortName);
}
@Override
public void accept(final String... args) {
assertConfigurationIsValid();
boolean dontParseOptionsAnyMore = false;
int i;
int paramsIndex = 0;
for (i = 0; i < args.length; i++) {
final String arg = args[i];
if (arg.isEmpty()) {
continue;
}
final String value = (i + 1 < args.length) ? args[i + 1] : null;
if (arg.equals("--")) {
dontParseOptionsAnyMore = true;
continue;
}
if (!dontParseOptionsAnyMore) {
// long names
if (arg.startsWith("--")) {
final String argLongName = arg.substring(2);
consumeOptionWithLongName(argLongName, value);
args[i] = null;
continue;
}
// short names
if (arg.startsWith("-")) {
final String argShortName = arg.substring(1);
if (argShortName.length() > 1 && argShortName.charAt(1) != '=') {
// compressed options
final char[] allShortNames = argShortName.toCharArray();
for (final char c : allShortNames) {
final String argName = String.valueOf(c);
consumeOptionWithShortNameAndNoArguments(argName);
}
args[i] = null;
continue;
}
final boolean valueConsumed = consumeOptionWithShortName(argShortName, value);
// mark argument as consumed
args[i] = null;
if (valueConsumed) {
// mark value as consumed, too
i++;
args[i] = null;
}
continue;
}
}
// params
if (paramsIndex == params.size()) {
// we are done here
break;
}
final Param param = params.get(paramsIndex++);
final List<String> paramArguments = new ArrayList<>();
int from = 0;
final int to = param.required + param.optional;
for (; from < to; from++, i++) {
final String paramValue = (i < args.length) ? args[i] : null;
if (paramValue == null) {
break;
}
paramArguments.add(paramValue);
}
i--;
if (paramArguments.size() < param.required) {
throw new CliException("Parameter required: " + param.label);
}
if (paramArguments.isEmpty()) {
// parameter not found
continue;
}
param.consumer.accept(paramArguments.toArray(new String[0]));
}
// must check if remaining parameters are not satisfied
while (paramsIndex < params.size()) {
final Param param = params.get(paramsIndex++);
if (param.required > 0) {
throw new CliException("Parameter required: " + param.label);
}
}
}
private void assertConfigurationIsValid() {
for (final Option option : options) {
if (option.consumer == null) {
throw new CliException("Option has no registered consumer: " + option);
}
}
}
/**
* Prints the usage line.
*/
public void printUsage(final String commandName) {
final StringBuilder usage = new StringBuilder(commandName);
for (final Option option : options) {
if (option.shortName != null) {
usage.append(" [-").append(option.shortName).append("]");
} else if (option.longName != null) {
usage.append(" [--").append(option.longName).append("]");
}
}
for (final Param param : params) {
usage.append(" ").append(param.label);
}
System.out.println(usage);
}
}

37
fine-jodd/src/main/java/com/fr/third/jodd/cli/CliException.java

@ -1,37 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cli;
import com.fr.third.jodd.exception.UncheckedException;
/**
* CLI exception.
*/
public class CliException extends UncheckedException {
public CliException(final String message) {
super(message);
}
}

96
fine-jodd/src/main/java/com/fr/third/jodd/cli/Option.java

@ -1,96 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cli;
import java.util.function.Consumer;
public class Option {
String label;
String shortName;
String longName;
String description;
boolean hasArg;
String argLabel;
Consumer<String> consumer;
public Option shortName(final String shortName) {
this.shortName = shortName;
return this;
}
public Option longName(final String longName) {
this.longName = longName;
return this;
}
public Option names(final String shortName, final String longName) {
this.shortName = shortName;
this.longName = longName;
return this;
}
public Option description(final String description) {
this.description = description;
return this;
}
public Option hasArg() {
this.hasArg = true;
return this;
}
public Option hasArg(final String argLabel) {
this.hasArg = true;
this.argLabel = argLabel;
return this;
}
public Option label(final String label) {
this.label = label;
return this;
}
public Option with(final Consumer<String> consumer) {
this.consumer = consumer;
return this;
}
@Override
public String toString() {
String out = "";
if (shortName != null) {
out += "-" + shortName;
}
if (longName != null) {
if (!out.isEmpty()) {
out += " | ";
}
out += "--" + longName;
}
return out;
}
}

84
fine-jodd/src/main/java/com/fr/third/jodd/cli/Param.java

@ -1,84 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.cli;
import java.util.function.Consumer;
public class Param {
String label;
int required = 0;
int optional = 1;
String description;
Consumer<String[]> consumer;
public Param required(final int required) {
this.required = required;
return this;
}
public Param optional(final int optional) {
this.optional = optional;
return this;
}
public Param required() {
this.required = 1;
this.optional = 0;
return this;
}
public Param optional() {
this.required = 0;
this.optional = 1;
return this;
}
public Param all() {
this.optional = 1_000_000; // magic number indicating *ALL* parameters
return this;
}
public Param range(final int required, final int max) {
this.required = required;
this.optional = max - required;
return this;
}
public Param label(final String label) {
this.label = label;
return this;
}
public Param description(final String description) {
this.description = description;
return this;
}
public Param with(final Consumer<String[]> consumer) {
this.consumer = consumer;
return this;
}
}

29
fine-jodd/src/main/java/com/fr/third/jodd/cli/package-info.java

@ -1,29 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/**
* Small parser for command line arguments.
*/
package com.fr.third.jodd.cli;

65
fine-jodd/src/main/java/com/fr/third/jodd/core/JoddCore.java

@ -1,65 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.core;
import com.fr.third.jodd.util.StringPool;
import java.security.Security;
/**
* Jodd library-wide properties.
*/
public class JoddCore {
static {
// Starting from Java8 u151, the `Unlimited Strength Jurisdiction Policy Files`
// are included with Java, but has to be enabled.
// They are enabled on Java9 by default.
Security.setProperty("crypto.policy", "unlimited");
}
// ---------------------------------------------------------------- settings
/**
* Default prefix for temporary files.
*/
public static String tempFilePrefix = "jodd-";
/**
* The encoding used across the Jodd classes, "UTF-8" by default.
*/
public static String encoding = StringPool.UTF_8;
/**
* Buffer size for various I/O operations.
*/
public static int ioBufferSize = 16384;
/**
* Flag that controls the {@code Unsafe} usage (if system detects it). Enabled by default.
*/
public static boolean unsafeUsageEnabled = true;
}

29
fine-jodd/src/main/java/com/fr/third/jodd/core/package-info.java

@ -1,29 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/**
* Jodd Core module.
*/
package com.fr.third.jodd.core;

303
fine-jodd/src/main/java/com/fr/third/jodd/datetime/DateTimeStamp.java

@ -1,303 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.datetime;
import com.fr.third.jodd.util.HashCode;
import static com.fr.third.jodd.util.HashCode.hash;
import java.io.Serializable;
/**
* Generic date time stamp just stores and holds date and time information.
* This class does not contain any date/time logic, neither guarantees
* that date is valid.
*
* @see JDateTime
* @see JulianDateStamp
* @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
@Deprecated
public class DateTimeStamp implements Comparable, Serializable, Cloneable {
/**
* Default empty constructor.
*/
public DateTimeStamp() {
}
/**
* Constructor that sets date and time.
*/
public DateTimeStamp(int year, int month, int day, int hour, int minute, int second, int millisecond) {
this.year = year;
this.month = month;
this.day = day;
this.hour = hour;
this.minute = minute;
this.second = second;
this.millisecond = millisecond;
}
/**
* Constructor that sets just date. Time is set to zeros.
*/
public DateTimeStamp(int year, int month, int day) {
this(year, month, day, 0, 0, 0, 0);
}
/**
* Year.
*/
public int year;
/**
* Month, range: [1 - 12]
*/
public int month = 1;
/**
* Day, range: [1 - 31]
*/
public int day = 1;
/**
* Hour, range: [0 - 23]
*/
public int hour;
/**
* Minute, range [0 - 59]
*/
public int minute;
/**
* Second, range: [0 - 59]
*/
public int second;
/**
* Millisecond, range: [0 - 1000]
*/
public int millisecond;
// ---------------------------------------------------------------- get/set
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public int getMinute() {
return minute;
}
public void setMinute(int minute) {
this.minute = minute;
}
public int getSecond() {
return second;
}
public void setSecond(int second) {
this.second = second;
}
public int getMillisecond() {
return millisecond;
}
public void setMillisecond(int millisecond) {
this.millisecond = millisecond;
}
// ---------------------------------------------------------------- compare
/**
* Compares this object with the specified object for order. Returns a
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
*
* @param o the Object to be compared.
* @return a negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
*
* @throws ClassCastException if the specified object's type prevents it
* from being compared to this Object.
*/
public int compareTo(Object o) {
DateTimeStamp dts = (DateTimeStamp) o;
int date1 = year * 10000 + month * 100 + day;
int date2 = dts.year * 10000 + dts.month * 100 + dts.day;
if (date1 < date2) {
return -1;
}
if (date1 > date2) {
return 1;
}
date1 = (hour * 10000000) + (minute * 100000) + (second * 1000) + millisecond;
date2 = (dts.hour * 10000000) + (dts.minute * 100000) + (dts.second * 1000) + dts.millisecond;
if (date1 < date2) {
return -1;
}
if (date1 > date2) {
return 1;
}
return 0;
}
/**
* Compares just date component of two date time stamps.
*/
public int compareDateTo(Object o) {
DateTimeStamp dts = (DateTimeStamp) o;
int date1 = year * 10000 + month * 100 + day;
int date2 = dts.year * 10000 + dts.month * 100 + dts.day;
if (date1 < date2) {
return -1;
}
if (date1 > date2) {
return 1;
}
return 0;
}
// ---------------------------------------------------------------- toString
/**
* Simple to string conversion.
*
* @return date/time string in 'y-m-d h:m:m.s' format
*/
@Override
public String toString() {
return new StringBuilder(25).append(year).append('-').append(month)
.append('-').append(day).append(' ').append(hour).append(':')
.append(minute).append(':').append(second).append('.')
.append(millisecond).toString();
}
// ---------------------------------------------------------------- equals & hashCode
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (this.getClass() != object.getClass()) {
return false;
}
DateTimeStamp stamp = (DateTimeStamp) object;
return (stamp.year == this.year) &&
(stamp.month == this.month) &&
(stamp.day == this.day) &&
(stamp.hour == this.hour) &&
(stamp.minute == this.minute) &&
(stamp.second == this.second) &&
(stamp.millisecond == this.millisecond);
}
@Override
public int hashCode() {
int result = HashCode.SEED;
result = hash(result, year);
result = hash(result, month);
result = hash(result, day);
result = hash(result, hour);
result = hash(result, minute);
result = hash(result, second);
result = hash(result, millisecond);
return result;
}
// ---------------------------------------------------------------- clone
@Override
protected DateTimeStamp clone() {
DateTimeStamp dts = new DateTimeStamp();
dts.year = this.year;
dts.month = this.month;
dts.day = this.day;
dts.hour = this.hour;
dts.minute = this.minute;
dts.second = this.second;
dts.millisecond = this.millisecond;
return dts;
}
// ---------------------------------------------------------------- equals
public boolean isEqualDate(DateTimeStamp date) {
return date.day == this.day
&& date.month == this.month
&& date.year == this.year;
}
public boolean isEqualTime(DateTimeStamp time) {
return time.hour == this.hour
&& time.minute == this.minute
&& time.second == this.second
&& time.millisecond == this.millisecond;
}
}

1776
fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTime.java

File diff suppressed because it is too large Load Diff

88
fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTimeDefault.java

@ -1,88 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.datetime;
import com.fr.third.jodd.datetime.format.Iso8601JdtFormatter;
import com.fr.third.jodd.datetime.format.JdtFormatter;
import java.util.TimeZone;
import java.util.Locale;
/**
* Defaults for {@link JDateTime}.
* @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
@Deprecated
@SuppressWarnings({"RedundantFieldInitialization"})
public class JDateTimeDefault {
/**
* Default value for month fix.
*/
public static boolean monthFix = true;
/**
* Default time zone. Set it to <code>null</code>
* for system default timezone.
*/
public static TimeZone timeZone = null; // system default
/**
* Default locale for date names. Set it to <code>null</code>
* for system default locale.
*/
public static Locale locale = null; // system default
/**
* Default format template.
*/
public static String format = JDateTime.DEFAULT_FORMAT;
/**
* Default formatter.
*/
public static JdtFormatter formatter = new Iso8601JdtFormatter();
/**
* Default definition of first day of week.
*/
public static int firstDayOfWeek = JDateTime.MONDAY;
/**
* Default number of days first week of year must have.
*/
public static int mustHaveDayOfFirstWeek = 4;
/**
* Default minimal number of days firs week of year must have.
*/
public static int minDaysInFirstWeek = 4;
/**
* Default value for tracking DST.
*/
public static boolean trackDST = false;
}

302
fine-jodd/src/main/java/com/fr/third/jodd/datetime/JStopWatch.java

@ -1,302 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.datetime;
import java.util.List;
import java.util.ArrayList;
/**
* Nice thread-aware stopwatch that supports time spans, cumulative times and laps.
* Useful for all kind of profiling, time measurements etc.
*
* @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
@Deprecated
public class JStopWatch {
/**
* Optional stopwatch name.
*/
protected String name;
/**
* Last start time.
*/
protected long startTime;
/**
* Last stop time.
*/
protected long stopTime;
/**
* Last elapsed time.
*/
protected long spanTime;
/**
* Cumulative elapsed time.
*/
protected long totalTime;
/**
* Running flag.
*/
protected boolean running;
// ---------------------------------------------------------------- ctors
/**
* Starts the stopwatch.
*/
public JStopWatch() {
this("#jStopWatch");
}
/**
* Starts the named stopwatch.
*/
public JStopWatch(String name) {
this.name = name;
start();
}
/**
* Returns stopwatch name.
*/
public String getName() {
return name;
}
/**
* Returns <code>true</code> if stopwatch is running.
*/
public boolean isRunning() {
return running;
}
// ---------------------------------------------------------------- basic
/**
* Starts the stopwatch. {@link #stop()} must be called prior to restart.
* Returns starting time in milliseconds.
*/
public long start() {
if (!running) {
startTime = System.currentTimeMillis();
running = true;
}
return startTime;
}
/**
* Restarts the stopwatch.
*/
public long restart() {
startTime = System.currentTimeMillis();
running = true;
return startTime;
}
/**
* Stops the stopwatch if running. Returns span time.
* If laps are used, marks the last lap.
*/
public long stop() {
if (running) {
stopTime = System.currentTimeMillis();
if (laps != null) {
lap(stopTime);
}
spanTime = stopTime - startTime;
totalTime += stopTime - startTime;
running = false;
}
return spanTime;
}
/**
* Returns total elapsed time from the {@link #start()} in ms.
*/
public long elapsed() {
return System.currentTimeMillis() - startTime;
}
/**
* Stops the stopwatch and returns total cumulative time in ms.
*/
public long total() {
stop();
return totalTime;
}
/**
* Stops the stopwatch and returns total time span for last
* start-stop sequence.
*/
public long span() {
stop();
return spanTime;
}
// ---------------------------------------------------------------- laps
/**
* List of all laps. Contains long arrays in following format:
* <ul>
* <li>lap time - current lap time,</li>
* <li>lap span time - elapsed time from start,</li>
* <li>lap millis - lap milliseconds.
* </ul>
*/
protected List<long[]> laps;
/**
* Marks a lap and returns its length. May be called only while stop watch is running.
*/
public long lap() {
return lap(System.currentTimeMillis());
}
protected long lap(long lap) {
if (!running) {
return 0;
}
long lapSpanTime = lap - startTime;
long lapTime;
if (laps == null) {
lapTime = lapSpanTime;
laps = new ArrayList<long[]>();
} else {
long[] previous = laps.get(laps.size() - 1);
lapTime = lap - previous[2];
}
laps.add(new long[] {lapTime, lapSpanTime, lap});
return lapTime;
}
/**
* Returns the total number of laps up to this moment.
*/
public int totalLaps() {
if (laps == null) {
return 0;
}
return laps.size();
}
/**
* Returns lap times for 1-based lap index.
* Returns <code>null</code> if laps are not used or if index is invalid.
*/
public long[] getLapTimes(int index) {
if (laps == null) {
return null;
}
if ((index <= 0) || (index > laps.size())) {
return null;
}
return laps.get(index - 1);
}
// ---------------------------------------------------------------- output
/**
* Returns total elapsed time as formatted string from the last start.
*/
@Override
public String toString() {
long elapsed = elapsed();
StringBuilder sb = new StringBuilder();
sb.append("JStopWatch ").append(name).append(running ? " is running." : "").append('\n');
if (running) {
sb.append("elapsed: ").append(formatTimeSpan(elapsed));
} else {
if (spanTime != totalTime) {
sb.append("span: ").append(formatTimeSpan(spanTime)).append('\n');
}
sb.append("\ntotal: ").append(formatTimeSpan(totalTime));
}
if (laps != null) {
if (!laps.isEmpty()) {
sb.append('\n');
sb.append("\n\t\t\tlap\t\telapsed\n");
}
for (int i = 0; i < laps.size(); i++) {
long[] longs = laps.get(i);
sb.append(" lap #").append(i + 1).append(':').append('\t');
sb.append(formatTimeSpan(longs[0])).append('\t');
sb.append(formatTimeSpan(longs[1])).append('\n');
}
}
return sb.toString();
}
/**
* Formats time spans.
*/
public static String formatTimeSpan(long millis) {
long seconds = 0;
long minutes = 0;
long hours = 0;
if (millis > 1000) {
seconds = millis / 1000;
millis %= 1000;
}
if (seconds > 60) {
minutes = seconds / 60;
seconds %= 60;
}
if (minutes > 60) {
hours = minutes / 60;
minutes %= 60;
}
StringBuilder result = new StringBuilder(20);
boolean out = false;
if (hours > 0) {
result.append(hours).append(':');
out = true;
}
if (out || (minutes > 0)) {
if (minutes < 10) {
result.append('0');
}
result.append(minutes).append(':');
}
if (seconds < 10) {
result.append('0');
}
result.append(seconds).append('.');
if (millis < 10) {
result.append('0');
}
if (millis < 100) {
result.append('0');
}
result.append(millis);
return result.toString();
}
}

337
fine-jodd/src/main/java/com/fr/third/jodd/datetime/JulianDateStamp.java

@ -1,337 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.datetime;
import com.fr.third.jodd.util.HashCode;
import static com.fr.third.jodd.util.HashCode.hash;
import java.math.BigDecimal;
import java.io.Serializable;
/**
* Julian Date stamp, for high precision calculations. Julian date is a real
* number and it basically consist of two parts: integer and fraction. Integer
* part carries date information, fraction carries time information.
*
* <p>
* The Julian day or Julian day number (JDN) is the (integer) number of days that
* have elapsed since Monday, January 1, 4713 BC in the proleptic Julian calendar 1.
* That day is counted as Julian day zero. Thus the multiples of 7 are Mondays.
* Negative values can also be used.
*
* <p>
* The Julian Date (JD) is the number of days (with decimal fraction of the day) that
* have elapsed since 12 noon Greenwich Mean Time (UT or TT) of that day.
* Rounding to the nearest integer gives the Julian day number.
* <p>
* For calculations that will have time precision of 1e-3 seconds, both
* fraction and integer part must have enough digits in it. The problem is
* that integer part is big and, on the other hand fractional is small, and
* since final julian date is a sum of this two values, some fraction
* numerals may be lost. Therefore, for higher precision both
* fractional and integer part of julian date real number has to be
* preserved.
* <p>
* This class stores the unmodified fraction part, but not all digits
* are significant! For 1e-3 seconds precision, only 8 digits after
* the decimal point are significant.
*
* @see TimeUtil
* @see JDateTime
* @see DateTimeStamp
* @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
@Deprecated
public class JulianDateStamp implements Serializable, Cloneable {
/**
* Integer part of the Julian Date (JD).
*/
protected int integer;
/**
* Returns integer part of the Julian Date (JD).
*/
public int getInteger() {
return integer;
}
/**
* Fraction part of the Julian Date (JD).
* Should be always in [0.0, 1.0) range.
*/
protected double fraction;
/**
* Returns the fraction part of Julian Date (JD).
* Returned value is always in [0.0, 1.0) range.
*/
public double getFraction() {
return fraction;
}
/**
* Calculates and returns significant fraction only as an int.
*/
public int getSignificantFraction() {
return (int) (fraction * 100000000);
}
/**
* Returns JDN. Note that JDN is not equal to {@link #integer}. It is calculated by
* rounding to the nearest integer.
*/
public int getJulianDayNumber() {
if (fraction >= 0.5) {
return integer + 1;
}
return integer;
}
// ---------------------------------------------------------------- ctors
/**
* Default empty constructor.
*/
public JulianDateStamp() {
}
/**
* Creates JD from a <code>double</code>.
*/
public JulianDateStamp(double jd) {
set(jd);
}
/**
* Creates JD from both integer and fractional part using normalization.
* Normalization occurs when fractional part is out of range.
*
* @see #set(int, double)
*
* @param i integer part
* @param f fractional part should be in range [0.0, 1.0)
*/
public JulianDateStamp(int i, double f) {
set(i, f);
}
/**
* Creates JD from <code>BigDecimal</code>.
*/
public JulianDateStamp(BigDecimal bd) {
double d = bd.doubleValue();
integer = (int) d;
bd = bd.subtract(new BigDecimal(integer));
fraction = bd.doubleValue();
}
// ---------------------------------------------------------------- conversion
/**
* Returns <code>double</code> value of JD.
* <b>CAUTION</b>: double values may not be suit for precision math due to
* loss of precision.
*/
public double doubleValue() {
return (double)integer + fraction;
}
/**
* Returns <code>BigDecimal</code> value of JD.
*/
@SuppressWarnings({"UnpredictableBigDecimalConstructorCall"})
public BigDecimal toBigDecimal() {
BigDecimal bd = new BigDecimal(integer);
return bd.add(new BigDecimal(fraction));
}
/**
* Returns string representation of JD.
*
* @return julian integer as string
*/
@Override
public String toString() {
String s = Double.toString(fraction);
int i = s.indexOf('.');
s = s.substring(i);
return integer + s;
}
// ---------------------------------------------------------------- math
/**
* Adds a JD to current instance.
*/
public JulianDateStamp add(JulianDateStamp jds) {
int i = this.integer + jds.integer;
double f = this.fraction + jds.fraction;
set(i, f);
return this;
}
/**
* Adds a double to current instance.
*/
public JulianDateStamp add(double delta) {
set(this.integer, this.fraction + delta);
return this;
}
/**
* Subtracts a JD from current instance.
*/
public JulianDateStamp sub(JulianDateStamp jds) {
int i = this.integer - jds.integer;
double f = this.fraction -jds.fraction;
set(i, f);
return this;
}
/**
* Subtracts a double from current instance.
*/
public JulianDateStamp sub(double delta) {
set(this.integer, this.fraction - delta);
return this;
}
/**
* Sets integer and fractional part with normalization.
* Normalization means that if double is out of range,
* values will be correctly fixed.
*/
public void set(int i, double f) {
integer = i;
int fi = (int) f;
f -= fi;
integer += fi;
if (f < 0) {
f += 1;
integer--;
}
this.fraction = f;
}
public void set(double jd) {
integer = (int)jd;
fraction = jd - (double)integer;
}
// ---------------------------------------------------------------- between
/**
* Calculates the number of days between two dates. Returned value is always positive.
*/
public int daysBetween(JulianDateStamp otherDate) {
int difference = daysSpan(otherDate);
return difference >= 0 ? difference : -difference;
}
/**
* Returns span between two days. Returned value may be positive (when this date
* is after the provided one) or negative (when comparing to future date).
*/
public int daysSpan(JulianDateStamp otherDate) {
int now = getJulianDayNumber();
int then = otherDate.getJulianDayNumber();
return now - then;
}
// ---------------------------------------------------------------- equals & hashCode
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (this.getClass() != object.getClass()) {
return false;
}
JulianDateStamp stamp = (JulianDateStamp) object;
return (stamp.integer == this.integer) &&
(Double.compare(stamp.fraction, this.fraction) == 0);
}
@Override
public int hashCode() {
int result = HashCode.SEED;
result = hash(result, integer);
result = hash(result, fraction);
return result;
}
// ---------------------------------------------------------------- clone
@Override
protected JulianDateStamp clone() {
return new JulianDateStamp(this.integer, this.fraction);
}
// ---------------------------------------------------------------- conversion
/**
* Returns Reduced Julian Date (RJD), used by astronomers.
* RJD = JD 2400000
*/
public JulianDateStamp getReducedJulianDate() {
return new JulianDateStamp(integer - 2400000, fraction);
}
public void setReducedJulianDate(double rjd) {
set(rjd + 2400000);
}
/**
* Returns Modified Julian Date (MJD), where date starts from midnight rather than noon.
* RJD = JD 2400000.5
*/
public JulianDateStamp getModifiedJulianDate() {
return new JulianDateStamp(integer - 2400000, fraction - 0.5);
}
public void setModifiedJulianDate(double mjd) {
set(mjd + 2400000.5);
}
/**
* Returns Truncated Julian Day (TJD), introduced by NASA for the space program.
* TJD began at midnight at the beginning of May 24, 1968 (Friday).
*/
public JulianDateStamp getTruncatedJulianDate() {
return new JulianDateStamp(integer - 2440000, fraction - 0.5);
}
public void setTruncatedJulianDate(double tjd) {
set(tjd + 2440000.5);
}
}

118
fine-jodd/src/main/java/com/fr/third/jodd/datetime/Period.java

@ -1,118 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.datetime;
/**
* Holds a time period. With julian dates and {@link JDateTime} it is quite
* easy to calculate period in days - just by subtracting two julian day numbers.
* However, calculating hours, minutes and seconds would require more calculation
* and this class provides simple and faster period calculation.
*
* @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
@Deprecated
public class Period {
protected final long days;
protected final int hours;
protected final int minutes;
protected final int seconds;
protected final int milliseconds;
public Period(JDateTime jdt1, JDateTime jdt2) {
if (jdt2.isBefore(jdt1)) {
JDateTime temp = jdt1;
jdt1 = jdt2;
jdt2 = temp;
}
long julian2 = jdt2.getJulianDayNumber();
long julian1 = jdt1.getJulianDayNumber();
long days = julian2 - julian1;
int milliseconds = jdt2.getMillisecond() - jdt1.getMillisecond();
int seconds = jdt2.getSecond() - jdt1.getSecond();
int minutes = jdt2.getMinute() - jdt1.getMinute();
int hours = jdt2.getHour() - jdt1.getHour();
if (milliseconds < 0) {
seconds--;
milliseconds += 1000;
}
if (seconds < 0) {
minutes--;
seconds += 60;
}
if (minutes < 0) {
hours--;
minutes += 60;
}
if (hours < 0) {
days--;
hours += 24;
}
this.days = days;
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
this.milliseconds = milliseconds;
}
/**
* Returns number of days in period.
*/
public long getDays() {
return days;
}
/**
* Returns hours in period.
*/
public int getHours() {
return hours;
}
/**
* Returns minutes in period.
*/
public int getMinutes() {
return minutes;
}
/**
* Returns seconds in period.
*/
public int getSeconds() {
return seconds;
}
/**
* Returns milliseconds in period.
*/
public int getMilliseconds() {
return milliseconds;
}
}

398
fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeUtil.java

@ -1,398 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.datetime;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Date time calculations and utilities. <code>TimeUtil</code> is used by
* {@link JDateTime} and it contains few utilities that may be used
* elsewhere, although {@link JDateTime} is recommended for all time
* manipulation.
*
* @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
@Deprecated
public class TimeUtil {
public static final int SECONDS_IN_DAY = 60 * 60 * 24;
public static final long MILLIS_IN_DAY = 1000L * SECONDS_IN_DAY;
// ---------------------------------------------------------------- misc calc
/**
* Calculates day of year from given time stamp.
* It may not work for some dates in 1582.
*
* @return day of year in range: [1-366]
*/
public static int dayOfYear(int year, int month, int day) {
int day_of_year;
if (isLeapYear(year)) {
day_of_year = ((275 * month) / 9) - ((month + 9) / 12) + day - 30;
} else {
day_of_year = ((275 * month) / 9) - (((month + 9) / 12) << 1) + day - 30;
}
return day_of_year;
}
/**
* Check if the given year is leap year.
*
* @return <code>true</code> if the year is a leap year
*/
public static boolean isLeapYear(int y) {
boolean result = false;
if (((y % 4) == 0) && // must be divisible by 4...
((y < 1582) || // and either before reform year...
((y % 100) != 0) || // or not a century...
((y % 400) == 0))) { // or a multiple of 400...
result = true; // for leap year.
}
return result;
}
static final int[] MONTH_LENGTH = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/**
* Returns the length of the specified month in days. Month is 1 for January
* and 12 for December.
*
* @return length of the specified month in days
*/
public static int getMonthLength(int year, int month) {
return getMonthLength(year, month, isLeapYear(year));
}
static int getMonthLength(int year, int month, boolean leap) {
if ((month < 1) || (month > 12)) {
throw new IllegalArgumentException("Invalid month: " + month);
}
if (month == 2) {
return leap ? 29 : 28;
}
if ((year == 1582) && (month == 10)) {
return 21;
}
return MONTH_LENGTH[month];
}
// ---------------------------------------------------------------- valid
/**
* Checks if date is valid.
*
* @return <code>true</code> if date is valid, otherwise <code>false</code>
*/
public static boolean isValidDate(int year, int month, int day) {
if ((month < 1) || (month > 12)) {
return false;
}
int ml = getMonthLength(year, month);
//noinspection RedundantIfStatement
if ((day < 1) || (day > ml)) {
return false;
}
return true;
}
/**
* Checks if time is valid.
*
* @param hour hour to check
* @param minute minute to check
* @param second second to check
*
* @return <code>true</code> if time is valid, otherwise <code>false</code>
*/
public static boolean isValidTime(int hour, int minute, int second, int millisecond) {
if ((hour < 0) || (hour >= 24)) {
return false;
}
if ((minute < 0) || (minute >= 60)) {
return false;
}
if ((second < 0) || (second >= 60)) {
return false;
}
//noinspection RedundantIfStatement
if ((millisecond < 0) || (millisecond >= 1000)) {
return false;
}
return true;
}
/**
* Checks if date and time are valid.
*
* @param year year to check
* @param month month to check
* @param day day to check
* @param hour hour to check
* @param minute minute to check
* @param second second to check
*
* @return <code>true</code> if date and time are valid, otherwise <code>false</code>
*/
public static boolean isValidDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond) {
return (isValidDate(year, month, day) && isValidTime(hour, minute, second, millisecond));
}
/**
* Checks if date and time are valid.
*
* @param dts date/time stamp
*
* @return <code>true</code> if date and time are valid, otherwise <code>false</code>
*/
public static boolean isValidDateTime(DateTimeStamp dts) {
return (isValidDate(dts.year, dts.month, dts.day) && isValidTime(dts.hour, dts.minute, dts.second, dts.millisecond));
}
// ---------------------------------------------------------------- julian date
/**
* Calculates Astronomical Julian Date from given time stamp.
*
* @return Julian Date stamp
*/
public static JulianDateStamp toJulianDate(DateTimeStamp time) {
return toJulianDate(time.year, time.month, time.day, time.hour, time.minute, time.second, time.millisecond);
}
/**
* Calculates Astronomical Julian Date from given time.<p>
*
* Astronomical Julian Dates are counting from noon of the January 1st, -4712
* (julian date 0 is -4712/01/01 12:00:00). Zero year exist. Julian Date
* is always GMT, there are no timezones.
* <p>
*
* Algorithm based on Numerical Recipesin C, 2nd ed., Cambridge University
* Press 1992, modified and enhanced by Igor Spasic.
*
* @param year year
* @param month month
* @param day day
* @param hour hour
* @param minute minute
* @param second second
*
* @return julian time stamp
*/
public static JulianDateStamp toJulianDate(int year, int month, int day, int hour, int minute, int second, int millisecond) {
// month range fix
if ((month > 12) || (month < -12)) {
month--;
int delta = month / 12;
year += delta;
month -= delta * 12;
month++;
}
if (month < 0) {
year--;
month += 12;
}
// decimal day fraction
double frac = (hour / 24.0) + (minute / 1440.0) + (second / 86400.0) + (millisecond / 86400000.0);
if (frac < 0) { // negative time fix
int delta = ((int)(-frac)) + 1;
frac += delta;
day -= delta;
}
//double gyr = year + (0.01 * month) + (0.0001 * day) + (0.0001 * frac) + 1.0e-9;
double gyr = year + (0.01 * month) + (0.0001 * (day + frac)) + 1.0e-9;
// conversion factors
int iy0;
int im0;
if (month <= 2) {
iy0 = year - 1;
im0 = month + 12;
} else {
iy0 = year;
im0 = month;
}
int ia = iy0 / 100;
int ib = 2 - ia + (ia >> 2);
// calculate julian date
int jd;
if (year <= 0) {
jd = (int)((365.25 * iy0) - 0.75) + (int)(30.6001 * (im0 + 1)) + day + 1720994;
} else {
jd = (int)(365.25 * iy0) + (int)(30.6001 * (im0 + 1)) + day + 1720994;
}
if (gyr >= 1582.1015) { // on or after 15 October 1582
jd += ib;
}
//return jd + frac + 0.5;
return new JulianDateStamp(jd, frac + 0.5);
}
/**
* Calculates time stamp from Astronomical Julian Date.
*
* @param JD julian date
*
* @return time stamp
*/
public static DateTimeStamp fromJulianDate(double JD) {
return fromJulianDate(new JulianDateStamp(JD));
}
/**
* Calculates time stamp from Astronomical Julian Date.
* Algorithm based on Numerical Recipesin C, 2nd ed., Cambridge University
* Press 1992.
*
* @param jds julian date stamp
*
* @return time stamp
*/
public static DateTimeStamp fromJulianDate(JulianDateStamp jds) {
DateTimeStamp time = new DateTimeStamp();
int year, month, day;
double frac;
int jd, ka, kb, kc, kd, ke, ialp;
//double JD = jds.doubleValue();//jdate;
//jd = (int)(JD + 0.5); // integer julian date
//frac = JD + 0.5 - (double)jd + 1.0e-10; // day fraction
ka = (int)(jds.fraction + 0.5);
jd = jds.integer + ka;
frac = jds.fraction + 0.5 - ka + 1.0e-10;
ka = jd;
if (jd >= 2299161) {
ialp = (int)(((double)jd - 1867216.25) / (36524.25));
ka = jd + 1 + ialp - (ialp >> 2);
}
kb = ka + 1524;
kc = (int)(((double)kb - 122.1) / 365.25);
kd = (int)((double)kc * 365.25);
ke = (int)((double)(kb - kd) / 30.6001);
day = kb - kd - ((int)((double)ke * 30.6001));
if (ke > 13) {
month = ke - 13;
} else {
month = ke - 1;
}
if ((month == 2) && (day > 28)){
day = 29;
}
if ((month == 2) && (day == 29) && (ke == 3)) {
year = kc - 4716;
} else if (month > 2) {
year = kc - 4716;
} else {
year = kc - 4715;
}
time.year = year;
time.month = month;
time.day = day;
// hour with minute and second included as fraction
double d_hour = frac * 24.0;
time.hour = (int) d_hour; // integer hour
// minute with second included as a fraction
double d_minute = (d_hour - (double)time.hour) * 60.0;
time.minute = (int) d_minute; // integer minute
double d_second = (d_minute - (double)time.minute) * 60.0;
time.second = (int) d_second; // integer seconds
double d_millis = (d_second - (double)time.second) * 1000.0;
// fix calculation errors
time.millisecond = (int) (((d_millis * 10) + 0.5) / 10);
return time;
}
// ---------------------------------------------------------------- gc
/**
* Returns Calendar month from provided JDateTime month.
*/
public static int toCalendarMonth(int month) {
return month - 1;
}
/**
* Returns Calendar day-of-week from provided JDateTime.
*/
public static int toCalendarDayOfWeek(int dayOfWeek) {
return (dayOfWeek % 7) + 1;
}
// ---------------------------------------------------------------- format
public static final SimpleDateFormat HTTP_DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
/**
* Formats time to HTTP date/time format. Note that number of milliseconds
* is lost.
*/
public static String formatHttpDate(long millis) {
Date date = new Date(millis);
return HTTP_DATE_FORMAT.format(date);
}
/**
* Parses the HTTP date/time format. Returns <code>-1</code> if given string
* is invalid.
*/
public static long parseHttpTime(String time) {
if (time == null) {
return -1;
}
try {
return TimeUtil.HTTP_DATE_FORMAT.parse(time).getTime();
}
catch (ParseException e) {
return -1;
}
}
}

75
fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeZoneUtil.java

@ -1,75 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.datetime;
import java.util.TimeZone;
/**
* Misc timezone utilities.
*
* @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
@Deprecated
public class TimeZoneUtil {
/**
* Returns raw offset difference in milliseconds.
*/
public static int getRawOffsetDifference(TimeZone from, TimeZone to) {
int offsetBefore = from.getRawOffset();
int offsetAfter = to.getRawOffset();
return offsetAfter - offsetBefore;
}
/**
* Returns offset difference in milliseconds for given time.
*/
public static int getOffsetDifference(long now, TimeZone from, TimeZone to) {
int offsetBefore = from.getOffset(now);
int offsetAfter = to.getOffset(now);
return offsetAfter - offsetBefore;
}
/**
* Get offset difference in milliseconds for given jdatetime.
*/
public static int getOffset(JDateTime jdt, TimeZone tz) {
return tz.getOffset(
jdt.getEra(),
jdt.getYear(),
jdt.getMonth() - 1,
jdt.getDay(),
TimeUtil.toCalendarDayOfWeek(jdt.getDayOfWeek()),
jdt.getMillisOfDay()
);
}
public static int getOffsetDifference(JDateTime jdt, TimeZone from, TimeZone to) {
int offsetBefore = getOffset(jdt, from);
int offsetAfter = getOffset(jdt, to);
return offsetAfter - offsetBefore;
}
}

330
fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/AbstractFormatter.java

@ -1,330 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.datetime.format;
import com.fr.third.jodd.datetime.DateTimeStamp;
import com.fr.third.jodd.datetime.JDateTime;
import com.fr.third.jodd.util.CharUtil;
/**
* Abstract formatter for easier {@link JdtFormatter} implementations.
* <p>
* For setting date and time, default formatter parses input String against
* specified format. It extracts parts of input string upon patterns
* and then each part is converted to a number for a date/time information.
* It doesn't ignore any non-number character. If conversion fails,
* <code>null</code> is returned.
*
* <p>
* Getting date time is also user friendly. Specified format may not only
* contains patterns but also any text. To remove errors in decoding when
* text may be recognize as one of patterns, format text may be quoted
* with the special escape sign. Double quote in the text will be decoded
* as a single quote, of course.
* <p>
*
* It is not necessary to have parsers for all patterns.
*
* @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
@Deprecated
public abstract class AbstractFormatter implements JdtFormatter {
/**
* Available patterns list. Used by {@link #findPattern(char[], int)}
* when parsing date time format. Each formatter will have its own set of
* patterns, in strictly defined order.
*/
protected char[][] patterns;
/**
* Escape character.
*/
protected char escapeChar = '\'';
/**
* Converts String array of patterns to char arrays.
*/
protected void preparePatterns(String[] spat) {
patterns = new char[spat.length][];
for (int i = 0; i < spat.length; i++) {
patterns[i] = spat[i].toCharArray();
}
}
/**
* Finds the longest pattern in provided format starting from specified position.
* All available patterns are stored in {@link #patterns}.
*
* @param format date time format to examine
* @param i starting index
*
* @return 0-based index of founded pattern, or <code>-1</code> if pattern not found
*/
protected int findPattern(char[] format, int i) {
int frmtc_len = format.length;
boolean match;
int n, lastn = -1;
int maxLen = 0;
for (n = 0; n < patterns.length; n++) {
char[] curr = patterns[n]; // current pattern from the pattern list
if (i > frmtc_len - curr.length) {
continue;
}
match = true;
int delta = 0;
while (delta < curr.length) { // match given pattern
if (curr[delta] != format[i + delta]) {
match = false; // no match, go to next
break;
}
delta++;
}
if (match) { // match
if (patterns[n].length > maxLen) { // find longest match
lastn = n;
maxLen = patterns[n].length;
}
}
}
return lastn;
}
// ---------------------------------------------------------------- convert
/**
* Creates a date-time string for founded pattern. Founded patterns
* is identified by its {@link #patterns} index.
*
* @param patternIndex index of founded pattern
* @param jdt date time information
*/
protected abstract String convertPattern(int patternIndex, JDateTime jdt);
/**
* {@inheritDoc}
* @see JdtFormatter#convert(JDateTime, String)
*/
public String convert(JDateTime jdt, String format) {
char[] fmtc = format.toCharArray();
int fmtc_len = fmtc.length;
StringBuilder result = new StringBuilder(fmtc_len);
int i = 0;
while (i < fmtc_len) {
if (fmtc[i] == escapeChar) { // quote founded
int end = i + 1;
while (end < fmtc_len) {
if (fmtc[end] == escapeChar) { // second quote founded
if (end + 1 < fmtc_len) {
end++;
if (fmtc[end] == escapeChar) { // skip double quotes
result.append(escapeChar); // and continue
} else {
break;
}
}
} else {
result.append(fmtc[end]);
}
end++;
}
i = end;
continue; // end of quoted string, continue the main loop
}
int n = findPattern(fmtc, i);
if (n != -1) { // pattern founded
result.append(convertPattern(n, jdt));
i += patterns[n].length;
} else {
result.append(fmtc[i]);
i++;
}
}
return result.toString();
}
// ---------------------------------------------------------------- parse
/**
* Parses value for matched pattern. Founded patterns
* is identified by its {@link #patterns} index.
* Note that value may represent both integer and decimals.
* May throw {@link NumberFormatException}.
*
* @param patternIndex index of founded pattern
* @param value value to parse, no spaces or tabs
* @param destination destination to modify
*/
protected abstract void parseValue(int patternIndex, String value, DateTimeStamp destination);
/**
* {@inheritDoc}
* @see JdtFormatter#parse(String, String)
*/
public DateTimeStamp parse(String value, String format) {
char[] valueChars = value.toCharArray();
char[] formatChars = format.toCharArray();
int i = 0, j = 0;
int valueLen = valueChars.length;
int formatLen = formatChars.length;
// detect if separators are used
boolean useSeparators = true;
if (valueLen == formatLen) {
useSeparators = false;
for (char valueChar : valueChars) {
if (!CharUtil.isDigit(valueChar)) {
useSeparators = true;
break;
}
}
}
DateTimeStamp time = new DateTimeStamp();
StringBuilder sb = new StringBuilder();
while (true) {
int n = findPattern(formatChars, i);
if (n != -1) { // pattern founded
int patternLen = patterns[n].length;
i += patternLen;
sb.setLength(0);
if (!useSeparators) {
for (int k = 0; k < patternLen; k++) {
sb.append(valueChars[j++]);
}
} else {
char next = 0xFFFF;
if (i < formatLen) {
next = formatChars[i]; // next = delimiter
}
while ((j < valueLen) && (valueChars[j] != next)) {
char scj = valueChars[j];
if ((scj != ' ') && (scj != '\t')) { // ignore surrounding whitespaces
sb.append(valueChars[j]);
}
j++;
}
}
parseValue(n, sb.toString(), time);
} else {
if (!useSeparators) {
throw new IllegalArgumentException("Invalid value: " + value);
}
if (formatChars[i] == valueChars[j]) {
j++;
}
i++;
}
if ((i == formatLen) || (j == valueLen)) {
break;
}
}
return time;
}
// ---------------------------------------------------------------- util
/**
* Prints values 00 - 99.
*/
protected String print2(int value) {
if (value < 0) {
throw new IllegalArgumentException("Value must be positive: " + value);
}
if (value < 10) {
return '0' + Integer.toString(value);
}
if (value < 100) {
return Integer.toString(value);
}
throw new IllegalArgumentException("Value too big: " + value);
}
/**
* Prints values 00 - 999.
*/
protected String print3(int value) {
if (value < 0) {
throw new IllegalArgumentException("Value must be positive: " + value);
}
if (value < 10) {
return "00" + Integer.toString(value);
}
if (value < 100) {
return '0' + Integer.toString(value);
}
if (value < 1000) {
return Integer.toString(value);
}
throw new IllegalArgumentException("Value too big: " + value);
}
/**
* Prints 4 digits and optional minus sign.
*/
protected String printPad4(int value) {
char[] result = new char[4];
int count = 0;
if (value < 0) {
result[count++] = '-';
value = -value;
}
String str = Integer.toString(value);
if (value < 10) {
result[count++] = '0';
result[count++] = '0';
result[count++] = '0';
result[count++] = str.charAt(0);
} else if (value < 100) {
result[count++] = '0';
result[count++] = '0';
result[count++] = str.charAt(0);
result[count++] = str.charAt(1);
} else if (value < 1000) {
result[count++] = '0';
result[count++] = str.charAt(0);
result[count++] = str.charAt(1);
result[count++] = str.charAt(2);
} else {
if (count > 0) {
return '-' + str;
}
return str;
}
return new String(result, 0, count);
}
}

170
fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/Iso8601JdtFormatter.java

@ -1,170 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.datetime.format;
import com.fr.third.jodd.datetime.DateTimeStamp;
import com.fr.third.jodd.datetime.JDateTime;
import com.fr.third.jodd.datetime.DateTimeStamp;
import com.fr.third.jodd.datetime.JDateTime;
import com.fr.third.jodd.util.LocaleUtil;
import com.fr.third.jodd.util.DateFormatSymbolsEx;
import java.util.TimeZone;
/**
* Default {@link JdtFormatter} uses <b>ISO 8601</b> specification, enhanced by some
* custom patterns. For more information see:
* <a href="http://en.wikipedia.org/wiki/ISO_8601">ISO 8601 on Wikipedia</a>
*
* <p>
* Patterns list:
*
* <ul>
* <li>YYYY + year</li>
* <li>MM + month</li>
* <li>DD + day of month</li>
* <li>D - day of week</li>
* <li>MML - month name (add-on)</li>
* <li>MMS - month abbreviation (add-on)</li>
* <li>DL - day of week name (add-on)</li>
* <li>DS - day of week abbreviation (add-on)</li>
* <li>hh + hour</li>
* <li>mm + minute</li>
* <li>ss + seconds (no milliseconds)</li>
* <li>mss + milliseconds (add-on)</li>
* <li>DDD - day of year</li>
* <li>WW - week of year</li>
* <li>WWW - week of year with 'W' prefix</li>
* <li>W - week of month (add-on)</li>
* <li>E - era</li>
* <li>TLZ - time zone long</li>
* <li>TLS - time zone short</li>
* </ul>
*
* <p>
* Patterns noted with + sign are used both for conversion and parsing.
* All patterns are used for conversion.
*
* @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
@Deprecated
public class Iso8601JdtFormatter extends AbstractFormatter {
public Iso8601JdtFormatter() {
preparePatterns(
new String[] {
"YYYY", // 0 + year
"MM", // 1 + month
"DD", // 2 + day of month
"D", // 3 - day of week
"MML", // 4 - month long name
"MMS", // 5 - month short name
"DL", // 6 - day of week long name
"DS", // 7 - day of week short name
"hh", // 8 + hour
"mm", // 9 + minute
"ss", // 10 + seconds
"mss", // 11 + milliseconds
"DDD", // 12 - day of year
"WW", // 13 - week of year
"WWW", // 14 - week of year with 'W' prefix
"W", // 15 - week of month
"E", // 16 - era
"TZL", // 17 - timezone long name
"TZS", // 18 - timezone short name
}
);
}
@Override
protected String convertPattern(int patternIndex, JDateTime jdt) {
DateFormatSymbolsEx dfs = LocaleUtil.getDateFormatSymbols(jdt.getLocale());
switch (patternIndex) {
case 0:
return printPad4(jdt.getYear());
case 1:
return print2(jdt.getMonth());
case 2:
return print2(jdt.getDay());
case 3:
return Integer.toString(jdt.getDayOfWeek());
case 4:
return dfs.getMonth(jdt.getMonth() - 1);
case 5:
return dfs.getShortMonth(jdt.getMonth() - 1);
case 6:
return dfs.getWeekday((jdt.getDayOfWeek() % 7) + 1);
case 7:
return dfs.getShortWeekday((jdt.getDayOfWeek() % 7) + 1);
case 8:
return print2(jdt.getHour());
case 9:
return print2(jdt.getMinute());
case 10:
return print2(jdt.getSecond());
case 11:
return print3(jdt.getMillisecond());
case 12:
return print3(jdt.getDayOfYear());
case 13:
return print2(jdt.getWeekOfYear());
case 14:
return 'W' + print2(jdt.getWeekOfYear());
case 15:
return Integer.toString(jdt.getWeekOfMonth());
case 16:
return jdt.getEra() == 1 ? dfs.getAdEra() : dfs.getBcEra();
case 17:
return jdt.getTimeZone().getDisplayName(
jdt.isInDaylightTime(),
TimeZone.LONG,
jdt.getLocale());
case 18:
return jdt.getTimeZone().getDisplayName(
jdt.isInDaylightTime(),
TimeZone.SHORT,
jdt.getLocale());
default:
return new String(patterns[patternIndex]);
}
}
@Override
protected void parseValue(int patternIndex, String value, DateTimeStamp destination) {
int v = Integer.parseInt(value);
switch (patternIndex) {
case 0: destination.year = v; break;
case 1: destination.month = v; break;
case 2: destination.day = v; break;
case 8: destination.hour = v; break;
case 9: destination.minute = v; break;
case 10: destination.second = v; break;
case 11: destination.millisecond = v; break;
default:
throw new IllegalArgumentException("Invalid template: " + new String(patterns[patternIndex]));
}
}
}

75
fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormat.java

@ -1,75 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.datetime.format;
import com.fr.third.jodd.datetime.DateTimeStamp;
import com.fr.third.jodd.datetime.JDateTime;
/**
* Immutable format-formatter pair.
*
* @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
@Deprecated
public class JdtFormat {
protected final String format;
protected final JdtFormatter formatter;
public JdtFormat(JdtFormatter formatter, String format) {
this.format = format;
this.formatter = formatter;
}
/**
* Returns format.
*/
public String getFormat() {
return format;
}
/**
* Returns formatter.
*/
public JdtFormatter getFormatter() {
return formatter;
}
/**
* Delegates for {@link JdtFormatter#convert(JDateTime, String)}.
*/
public String convert(JDateTime jdt) {
return formatter.convert(jdt, format);
}
/**
* Delegates for {@link JdtFormatter#parse(String, String)}.
*/
public DateTimeStamp parse(String value) {
return formatter.parse(value, format);
}
}

62
fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormatter.java

@ -1,62 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.datetime.format;
import com.fr.third.jodd.datetime.DateTimeStamp;
import com.fr.third.jodd.datetime.JDateTime;
import java.io.Serializable;
/**
* Date time formatter performs conversion both from and to string representation of time.
*
* @see AbstractFormatter
* @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
@Deprecated
public interface JdtFormatter extends Serializable {
/**
* Converts date time to a string using specified format.
*
* @param jdt JDateTime to read from
* @param format format
*
* @return formatted string with date time information
*/
String convert(JDateTime jdt, String format);
/**
* Parses string given in specified format and extracts time information.
* It returns a new instance of <code>DateTimeStamp</code> or <code>null</code> if error occurs.
*
* @param value string containing date time values
* @param format format
*
* @return DateTimeStamp instance with populated data
*/
DateTimeStamp parse(String value, String format);
}

29
fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/package-info.java

@ -1,29 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/**
* JDateTime formatters for converting date/time informations to/from strings.
*/
package com.fr.third.jodd.datetime.format;

29
fine-jodd/src/main/java/com/fr/third/jodd/datetime/package-info.java

@ -1,29 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/**
* Finally, easy manipulation of date and time!
*/
package com.fr.third.jodd.datetime;

301
fine-jodd/src/main/java/com/fr/third/jodd/exception/ExceptionUtil.java

@ -1,301 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.exception;
import com.fr.third.jodd.io.StreamUtil;
import com.fr.third.jodd.util.StringUtil;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
/**
* Few exception utilities.
*/
public class ExceptionUtil {
/**
* Returns current stack trace in form of array of stack trace elements.
* First stack trace element is removed.
* Since an exception is thrown internally, this method is slow.
*/
@SuppressWarnings({"ThrowCaughtLocally"})
public static StackTraceElement[] getCurrentStackTrace() {
StackTraceElement[] ste = new Exception().getStackTrace();
if (ste.length > 1) {
StackTraceElement[] result = new StackTraceElement[ste.length - 1];
System.arraycopy(ste, 1, result, 0, ste.length - 1);
return result;
} else {
return ste;
}
}
// ---------------------------------------------------------------- exception stack trace
/**
* Returns stack trace filtered by class names.
*/
public static StackTraceElement[] getStackTrace(final Throwable t, final String[] allow, final String[] deny) {
StackTraceElement[] st = t.getStackTrace();
ArrayList<StackTraceElement> result = new ArrayList<>(st.length);
elementLoop:
for (StackTraceElement element : st) {
String className = element.getClassName();
if (allow != null) {
boolean validElemenet = false;
for (String filter : allow) {
if (className.contains(filter)) {
validElemenet = true;
break;
}
}
if (!validElemenet) {
continue;
}
}
if (deny != null) {
for (String filter : deny) {
if (className.contains(filter)) {
continue elementLoop;
}
}
}
result.add(element);
}
st = new StackTraceElement[result.size()];
return result.toArray(st);
}
/**
* Returns stack trace chain filtered by class names.
*/
public static StackTraceElement[][] getStackTraceChain(Throwable t, final String[] allow, final String[] deny) {
ArrayList<StackTraceElement[]> result = new ArrayList<>();
while (t != null) {
StackTraceElement[] stack = getStackTrace(t, allow, deny);
result.add(stack);
t = t.getCause();
}
StackTraceElement[][] allStacks = new StackTraceElement[result.size()][];
for (int i = 0; i < allStacks.length; i++) {
allStacks[i] = result.get(i);
}
return allStacks;
}
/**
* Returns exception chain starting from top up to root cause.
*/
public static Throwable[] getExceptionChain(Throwable throwable) {
ArrayList<Throwable> list = new ArrayList<>();
list.add(throwable);
while ((throwable = throwable.getCause()) != null) {
list.add(throwable);
}
Throwable[] result = new Throwable[list.size()];
return list.toArray(result);
}
// ---------------------------------------------------------------- exception to string
/**
* Prints stack trace into a String.
*/
public static String exceptionStackTraceToString(final Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
t.printStackTrace(pw);
StreamUtil.close(pw);
StreamUtil.close(sw);
return sw.toString();
}
/**
* Prints full exception stack trace, from top to root cause, into a String.
*/
public static String exceptionChainToString(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
while (t != null) {
t.printStackTrace(pw);
t = t.getCause();
}
StreamUtil.close(pw);
StreamUtil.close(sw);
return sw.toString();
}
/**
* Build a message for the given base message and its cause.
*/
public static String buildMessage(final String message, Throwable cause) {
if (cause != null) {
cause = getRootCause(cause);
StringBuilder buf = new StringBuilder();
if (message != null) {
buf.append(message).append("; ");
}
buf.append("<--- ").append(cause);
return buf.toString();
} else {
return message;
}
}
// ---------------------------------------------------------------- root cause
/**
* Introspects the <code>Throwable</code> to obtain the root cause.
* <p>
* This method walks through the exception chain to the last element,
* "root" of the tree, and returns that exception. If no root cause found
* returns provided throwable.
*/
public static Throwable getRootCause(final Throwable throwable) {
Throwable cause = throwable.getCause();
if (cause == null) {
return throwable;
}
Throwable t = throwable;
// defend against (malicious?) circularity
for (int i = 0; i < 1000; i++) {
cause = t.getCause();
if (cause == null) {
return t;
}
t = cause;
}
return throwable;
}
/**
* Finds throwing cause in exception stack. Returns throwable object if cause class is matched.
* Otherwise, returns <code>null</code>.
*/
@SuppressWarnings({"unchecked"})
public static <T extends Throwable> T findCause(Throwable throwable, final Class<T> cause) {
while (throwable != null) {
if (throwable.getClass().equals(cause)) {
return (T) throwable;
}
throwable = throwable.getCause();
}
return null;
}
// ---------------------------------------------------------------- sql
/**
* Rolls up SQL exceptions by taking each proceeding exception
* and making it a child of the previous using the <code>setNextException</code>
* method of SQLException.
*/
public static SQLException rollupSqlExceptions(final Collection<SQLException> exceptions) {
SQLException parent = null;
for (SQLException exception : exceptions) {
if (parent != null) {
exception.setNextException(parent);
}
parent = exception;
}
return parent;
}
// ---------------------------------------------------------------- misc
/**
* Throws checked exceptions in un-checked manner.
*/
public static void throwRuntimeException(final Throwable throwable) {
throw wrapToRuntimeException(throwable);
}
/**
* Returns <code>non-null</code> message for a throwable.
*/
public static String message(final Throwable throwable) {
String message = throwable.getMessage();
if (StringUtil.isBlank(message)) {
message = throwable.toString();
}
return message;
}
/**
* Wraps exception to {@code RuntimeException}.
*/
public static RuntimeException wrapToRuntimeException(final Throwable throwable) {
if (throwable instanceof RuntimeException) {
return (RuntimeException) throwable;
}
return new RuntimeException(throwable);
}
public static Exception wrapToException(final Throwable throwable) {
if (throwable instanceof Exception) {
return (Exception) throwable;
}
return new RuntimeException(throwable);
}
/**
* Unwraps invocation and undeclared exceptions to real cause.
*/
public static Throwable unwrapThrowable(final Throwable wrappedThrowable) {
Throwable unwrapped = wrappedThrowable;
while (true) {
if (unwrapped instanceof InvocationTargetException) {
unwrapped = ((InvocationTargetException) unwrapped).getTargetException();
}
else if (unwrapped instanceof UndeclaredThrowableException) {
unwrapped = ((UndeclaredThrowableException) unwrapped).getUndeclaredThrowable();
}
else {
return unwrapped;
}
}
}
}

212
fine-jodd/src/main/java/com/fr/third/jodd/exception/UncheckedException.java

@ -1,212 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.exception;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.UncheckedIOException;
import java.util.concurrent.Callable;
/**
* Unchecked exception and also a wrapper for checked exceptions.
*/
@SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter"})
public class UncheckedException extends RuntimeException {
protected final Throwable cause;
/**
* Divider between causes printouts.
*/
protected static final String CAUSE_DIV = "---[cause]------------------------------------------------------------------------";
/**
* If set to <code>true</code> stack trace will be enhanced with cause's stack traces.
*/
protected final boolean showCauseDetails;
// ---------------------------------------------------------------- constructors
public UncheckedException(final Throwable t) {
super(t.getMessage());
cause = t;
this.showCauseDetails = true;
}
public UncheckedException(final Throwable t, final boolean showCauseDetails) {
super(t.getMessage());
cause = t;
this.showCauseDetails = showCauseDetails;
}
public UncheckedException() {
super();
cause = null;
this.showCauseDetails = false;
}
public UncheckedException(final String message) {
super(message);
cause = null;
this.showCauseDetails = false;
}
public UncheckedException(final String message, final Throwable t) {
super(message, t);
cause = t;
this.showCauseDetails = true;
}
public UncheckedException(final String message, final Throwable t, final boolean showCauseDetails) {
super(message, t);
cause = t;
this.showCauseDetails = showCauseDetails;
}
// ---------------------------------------------------------------- stack trace
@Override
public void printStackTrace() {
printStackTrace(System.err);
}
@Override
public void printStackTrace(final PrintStream ps) {
synchronized (ps) {
super.printStackTrace(ps);
if ((cause != null) && showCauseDetails) {
Throwable rootCause = ExceptionUtil.getRootCause(cause);
ps.println(CAUSE_DIV);
rootCause.printStackTrace(ps);
}
}
}
@Override
public void printStackTrace(final PrintWriter pw) {
synchronized (pw) {
super.printStackTrace(pw);
if ((cause != null) && showCauseDetails) {
Throwable rootCause = ExceptionUtil.getRootCause(cause);
pw.println(CAUSE_DIV);
rootCause.printStackTrace(pw);
}
}
}
// ---------------------------------------------------------------- txt
/**
* Returns the detail message, including the message from the nested exception if there is one.
*/
@Override
public String getMessage() {
return ExceptionUtil.buildMessage(super.getMessage(), cause);
}
// ---------------------------------------------------------------- wrap
/**
* Wraps checked exceptions in a <code>UncheckedException</code>.
* Unchecked exceptions are not wrapped.
*/
public static <V> V callAndWrapException(final Callable<V> callable) {
try {
return callable.call();
}
catch (IOException ioex) {
throw new UncheckedIOException(ioex);
}
catch (RuntimeException rtex) {
throw rtex;
}
catch (Exception t) {
throw new UncheckedException(t);
}
}
@FunctionalInterface
public interface CallableVoid {
public void call() throws Exception;
}
/**
* Wraps checked exceptions in a <code>UncheckedException</code>.
* Unchecked exceptions are not wrapped.
*/
public static void runAndWrapException(final CallableVoid callable) {
try {
callable.call();
}
catch (IOException ioex) {
throw new UncheckedIOException(ioex);
}
catch (RuntimeException rtex) {
throw rtex;
}
catch (Exception t) {
throw new UncheckedException(t);
}
}
/**
* Wraps all exceptions in a <code>UncheckedException</code>
*/
public static RuntimeException wrap(final Throwable t) {
return new UncheckedException(t);
}
/**
* Wraps all exceptions in a <code>UncheckedException</code>
*/
public static RuntimeException wrap(final Throwable t, final String message) {
return new UncheckedException(message, t);
}
// ---------------------------------------------------------------- cause
/**
* Re-throws cause if exists.
*/
public void rethrow() throws Throwable {
if (cause == null) {
return;
}
throw cause;
}
/**
* Returns exception cause.
*/
@Override
public Throwable getCause() {
return cause;
}
}

29
fine-jodd/src/main/java/com/fr/third/jodd/exception/package-info.java

@ -1,29 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/**
* Jodds exceptions.
*/
package com.fr.third.jodd.exception;

52
fine-jodd/src/main/java/com/fr/third/jodd/inex/InExRuleMatcher.java

@ -1,52 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.inex;
import com.fr.third.jodd.util.Wildcard;
/**
* Rule matcher.
*/
@FunctionalInterface
public interface InExRuleMatcher<T, R> {
/**
* {@link com.fr.third.jodd.util.Wildcard#match(CharSequence, CharSequence) Wilcard} rule matcher.
*/
InExRuleMatcher<String, String> WILDCARD_RULE_MATCHER =
(value, rule, include) -> Wildcard.match(value, rule);
/**
* {@link com.fr.third.jodd.util.Wildcard#matchPath(String, String) Wilcard path} rule matcher.
*/
InExRuleMatcher<String, String> WILDCARD_PATH_RULE_MATCHER =
(value, rule, include) -> Wildcard.matchPath(value, rule);
/**
* Matches the value against the rule.
*/
boolean accept(T value, R rule, boolean include);
}

381
fine-jodd/src/main/java/com/fr/third/jodd/inex/InExRules.java

@ -1,381 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.inex;
import java.util.ArrayList;
import java.util.List;
/**
* A single-class rule engine for includes/excludes filtering logic. It can be used when
* set of objects has to filtered using includes and excludes rules.
* For example, when filtering files by file name etc.
* <p>
* Rule engine works in one of two modes:
* <ul>
* <li><i>blacklist</i> - when any input is allowed by default and when you specify
* explicit excludes.
* </li>
* <li><i>whitelist</i> - when any input is disabled by default and when you specify
* explicit includes.
* </li>
* </ul>
* <p>
* The logic of this rule engine depends on the current mode. In both cases,
* always the inverse rules are considered first. For example, for <i>blacklist</i>
* mode, engine first examine excludes, and then includes. This way you can
* set any filter combination.
* <p>
* All Jodd classes that filters something uses this class to unify the
* behavior across the Jodd library.
* <p>
* About generics: rule engine examine Values (V). Rules are defined as Definitions (D).
* They are stored internally as R, that is used with Values.
*/
public class InExRules<V, D, R> implements InExRuleMatcher<V, R> {
public InExRules<String, String, String> create() {
return new InExRules<>();
}
protected List<Rule<R>> rules;
protected final InExRuleMatcher<V, R> inExRuleMatcher;
protected int includesCount;
protected int excludesCount;
protected boolean blacklist = true;
/**
* Creates default instance.
*/
public InExRules() {
this.inExRuleMatcher = this;
}
/**
* Creates instance that uses provided matcher.
*/
public InExRules(final InExRuleMatcher<V, R> inExRuleMatcher) {
this.inExRuleMatcher = inExRuleMatcher;
}
/**
* Returns total number of all rules.
*/
public int totalRules() {
if (rules == null) {
return 0;
}
return rules.size();
}
/**
* Returns total number of include rules.
*/
public int totalIncludeRules() {
return includesCount;
}
/**
* Returns total number of exclude rules.
*/
public int totalExcludeRules() {
return excludesCount;
}
/**
* Returns <code>true</code> if rule engine has at least one rule set.
*/
public boolean hasRules() {
if (rules == null) {
return false;
}
return !rules.isEmpty();
}
/**
* Rule definition.
*/
public static class Rule<R> {
public final R value;
public final boolean include;
public Rule(final R value, final boolean include) {
this.value = value;
this.include = include;
}
@Override
public String toString() {
return (include ? "+" : "-") + value.toString();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Rule rule = (Rule) o;
if (include != rule.include) {
return false;
}
if (!value.equals(rule.value)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = value.hashCode();
result = 31 * result + (include ? 1 : 0);
return result;
}
}
/**
* Returns rule's value on given index.
*/
public R getRule(final int index) {
return rules.get(index).value;
}
/**
* Resets all the rules in this rule engine.
*/
public void reset() {
if (rules != null) {
rules.clear();
}
includesCount = excludesCount = 0;
blacklist = true;
}
/**
* Enables <i>blacklist</i> mode - everything is <b>included</b> by default,
* and user sets explicit excludes.
*/
public void blacklist() {
blacklist = true;
}
/**
* Returns <code>true</code> if blacklist mode is set.
*/
public boolean isBlacklist() {
return blacklist;
}
/**
* Enables <i>whitelist</i> mode - everything is <b>excluded</b> by default,
* and user set explicit includes.
*/
public void whitelist() {
blacklist = false;
}
/**
* Returns <code>true</code> if whitelist mode is set.
*/
public boolean isWhitelist() {
return !blacklist;
}
/**
* Sets blacklist or whitelist mode depending on rules. Smart mode
* determines the following:
* <ul>
* <li>If there are only include rules, then the {@link #whitelist() whitelist} mode is set.</li>
* <li>If there are only excluded rules, then the {@link #blacklist() blacklist} mode is set.</li>
* <li>In any other case (both type of rules exist or no rules are set), then mode is not changed.</li>
* </ul>
* Should be called <b>after</b> all the rules are set, before matching starts.
*/
public void detectMode() {
if (excludesCount == 0 && includesCount > 0) {
whitelist();
}
else if (excludesCount > 0 && includesCount == 0) {
blacklist();
}
}
/**
* Adds include rule.
*/
public void include(final D rule) {
addRule(rule, true);
}
/**
* Adds exclude rule.
*/
public void exclude(final D rule) {
addRule(rule, false);
}
/**
* Adds a rule. Duplicates are not allowed and will be ignored.
*/
protected void addRule(final D ruleDefinition, final boolean include) {
if (rules == null) {
rules = new ArrayList<>();
}
if (include) {
includesCount++;
} else {
excludesCount++;
}
Rule<R> newRule = new Rule<>(makeRule(ruleDefinition), include);
if (rules.contains(newRule)) {
return;
}
rules.add(newRule);
}
protected R makeRule(final D rule) {
return (R) rule;
}
/**
* Matches value against the set of rules using current white/black list mode.
*/
public boolean match(final V value) {
return match(value, blacklist);
}
/**
* Matches value against the set of rules using provided white/black list mode.
*/
public boolean match(final V value, final boolean blacklist) {
if (rules == null) {
return blacklist;
}
boolean include = blacklist;
if (include) {
include = processExcludes(value, true);
include = processIncludes(value, include);
}
else {
include = processIncludes(value, false);
include = processExcludes(value, include);
}
return include;
}
/**
* Applies rules on given flag using current black/white list mode.
* @see #apply(Object, boolean, boolean)
*/
public boolean apply(final V value, final boolean flag) {
return apply(value, blacklist, flag);
}
/**
* Applies rules on given flag. Flag is only changed if at least one rule
* matched. Otherwise, the same value is returned. This way you can
* chain several rules and have the rule engine change the flag
* only when a rule is matched.
*/
public boolean apply(final V value, final boolean blacklist, boolean flag) {
if (rules == null) {
return flag;
}
if (blacklist) {
flag = processExcludes(value, flag);
flag = processIncludes(value, flag);
}
else {
flag = processIncludes(value, flag);
flag = processExcludes(value, flag);
}
return flag;
}
/**
* Process includes rules.
*/
protected boolean processIncludes(final V value, boolean include) {
if (includesCount > 0) {
if (!include) {
for (Rule<R> rule : rules) {
if (!rule.include) {
continue;
}
if (inExRuleMatcher.accept(value, rule.value, true)) {
include = true;
break;
}
}
}
}
return include;
}
/**
* Process excludes rules.
*/
protected boolean processExcludes(final V value, boolean include) {
if (excludesCount > 0) {
if (include) {
for (Rule<R> rule : rules) {
if (rule.include) {
continue;
}
if (inExRuleMatcher.accept(value, rule.value, false)) {
include = false;
break;
}
}
}
}
return include;
}
/**
* Matches value against single rule. By default performs <code>equals</code> on value
* against the rule.
*/
@Override
public boolean accept(final V value, final R rule, final boolean include) {
return value.equals(rule);
}
}

29
fine-jodd/src/main/java/com/fr/third/jodd/inex/package-info.java

@ -1,29 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/**
* Include-Exclude rules engine.
*/
package com.fr.third.jodd.inex;

86
fine-jodd/src/main/java/com/fr/third/jodd/introspector/CachingIntrospector.java

@ -1,86 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import com.fr.third.jodd.cache.TypeCache;
/**
* Default {@link com.fr.third.jodd.introspector.ClassIntrospector introspector} that caches all class descriptors.
* It can examine either <b>accessible</b> or <b>supported</b> fields/methods/constructors.
* <p>
* It simply caches <b>all</b> class descriptors.
*/
public class CachingIntrospector implements ClassIntrospector {
protected final TypeCache<ClassDescriptor> cache;
protected final boolean scanAccessible;
protected final boolean enhancedProperties;
protected final boolean includeFieldsAsProperties;
protected final String[] propertyFieldPrefix;
/**
* Default constructor.
*/
public CachingIntrospector() {
this(true, true, true, null);
}
/**
* Creates new caching {@link ClassIntrospector}. It may scan
* <b>accessible</b> or <b>supported</b> fields, methods or
* constructors.
*/
public CachingIntrospector(final boolean scanAccessible, final boolean enhancedProperties, final boolean includeFieldsAsProperties, final String[] propertyFieldPrefix) {
this.cache = TypeCache.createDefault();
this.scanAccessible = scanAccessible;
this.enhancedProperties = enhancedProperties;
this.includeFieldsAsProperties = includeFieldsAsProperties;
this.propertyFieldPrefix = propertyFieldPrefix;
}
/**
* {@inheritDoc}
*/
@Override
public ClassDescriptor lookup(final Class type) {
return cache.get(type, (t) ->
new ClassDescriptor(
t,
scanAccessible,
enhancedProperties,
includeFieldsAsProperties,
propertyFieldPrefix));
}
/**
* {@inheritDoc}
*/
@Override
public void reset() {
cache.clear();
}
}

378
fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassDescriptor.java

@ -1,378 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import com.fr.third.jodd.util.ClassUtil;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
/**
* A descriptor class for all methods/fields/properties/constructors of a class.
* Static methods/fields are ignored.
* <p>
* Descriptors are 'lazy': various internal caches are created on first request.
* <p>
* Throughout this class, public members are defined as members
* defined with "public" keyword and declared in a public type.
* Public members declared by a non-public class is considered non-public
* because access to it from outside is prohibited by the java access control
* anyway.
* <p>
* Public members defined in public classes are always preferred even
* when we allow private/protected members and types to be visible.
* So if a non-public subtype and a public super type both have a field
* with the same name, the field in the public super type is always used.
*/
public class ClassDescriptor {
protected final Class type;
protected final boolean scanAccessible;
protected final boolean extendedProperties;
protected final boolean includeFieldsAsProperties;
protected final String[] propertyFieldPrefix;
protected final Class[] interfaces;
protected final Class[] superclasses;
public ClassDescriptor(final Class type, final boolean scanAccessible, final boolean extendedProperties, final boolean includeFieldsAsProperties, final String[] propertyFieldPrefix) {
this.type = type;
this.scanAccessible = scanAccessible;
this.extendedProperties = extendedProperties;
this.includeFieldsAsProperties = includeFieldsAsProperties;
this.propertyFieldPrefix = propertyFieldPrefix;
isArray = type.isArray();
isMap = ClassUtil.isTypeOf(type, Map.class);
isList = ClassUtil.isTypeOf(type, List.class);
isSet = ClassUtil.isTypeOf(type, Set.class);
isCollection = ClassUtil.isTypeOf(type, Collection.class);
isSupplier = ClassUtil.isTypeOf(type, Supplier.class);
interfaces = ClassUtil.resolveAllInterfaces(type);
superclasses = ClassUtil.resolveAllSuperclasses(type);
isSystemClass = type.getName().startsWith("java.") &&
!type.getName().startsWith("java.awt.geom.");
}
/**
* Get the class object that this descriptor describes.
*/
public Class getType() {
return type;
}
/**
* Returns <code>true</code> if this class descriptor
* works with accessible fields/methods/constructors or with
* all supported.
*/
public boolean isScanAccessible() {
return scanAccessible;
}
/**
* Returns <code>true</code> if properties in this class descriptor
* are extended and include field description.
*/
public boolean isExtendedProperties() {
return extendedProperties;
}
/**
* Include fields as properties.
*/
public boolean isIncludeFieldsAsProperties() {
return includeFieldsAsProperties;
}
/**
* Returns property field prefixes. May be <code>null</code>
* if prefixes are not set. If you need to access both prefixed
* and non-prefixed fields, use empty string as one of the prefixes.
*/
public String[] getPropertyFieldPrefix() {
return propertyFieldPrefix;
}
// ---------------------------------------------------------------- special
private final boolean isArray;
/**
* Returns <code>true</code> if class is an array.
*/
public boolean isArray() {
return isArray;
}
private final boolean isMap;
/**
* Returns <code>true</code> if class is a <code>Map</code>.
*/
public boolean isMap() {
return isMap;
}
private final boolean isList;
/**
* Returns <code>true</code> if class is a <code>List</code>.
*/
public boolean isList() {
return isList;
}
private final boolean isSet;
/**
* Returns <code>true</code> if type is a <code>Set</code>.
*/
public boolean isSet() {
return isSet;
}
private final boolean isCollection;
/**
* Returns <code>true</code> if type is a collection.
*/
public boolean isCollection() {
return isCollection;
}
private final boolean isSupplier;
/**
* Returns <code>true</code> if type is a supplier.
*/
public boolean isSupplier() {
return isSupplier;
}
private boolean isSystemClass;
/**
* Returns <code>true</code> is class is a system class and should not
* expose fields or declared methods.
*/
public boolean isSystemClass() {
return isSystemClass;
}
// ---------------------------------------------------------------- fields
private Fields fields;
/**
* Returns {@link Fields fields collection}.
* Creates new fields collection on first usage.
*/
protected Fields getFields() {
if (fields == null) {
fields = new Fields(this);
}
return fields;
}
/**
* Returns field descriptor.
*/
public FieldDescriptor getFieldDescriptor(final String name, final boolean declared) {
final FieldDescriptor fieldDescriptor = getFields().getFieldDescriptor(name);
if (fieldDescriptor != null) {
if (!fieldDescriptor.matchDeclared(declared)) {
return null;
}
}
return fieldDescriptor;
}
/**
* Returns all field descriptors, including declared ones.
*/
public FieldDescriptor[] getAllFieldDescriptors() {
return getFields().getAllFieldDescriptors();
}
// ---------------------------------------------------------------- methods
private Methods methods;
/**
* Returns methods collection.
* Creates new collection on first access.
*/
protected Methods getMethods() {
if (methods == null) {
methods = new Methods(this);
}
return methods;
}
/**
* Returns {@link MethodDescriptor method descriptor} identified by name and parameters.
*/
public MethodDescriptor getMethodDescriptor(final String name, final boolean declared) {
final MethodDescriptor methodDescriptor = getMethods().getMethodDescriptor(name);
if ((methodDescriptor != null) && methodDescriptor.matchDeclared(declared)) {
return methodDescriptor;
}
return methodDescriptor;
}
/**
* Returns {@link MethodDescriptor method descriptor} identified by name and parameters.
*/
public MethodDescriptor getMethodDescriptor(final String name, final Class[] params, final boolean declared) {
final MethodDescriptor methodDescriptor = getMethods().getMethodDescriptor(name, params);
if ((methodDescriptor != null) && methodDescriptor.matchDeclared(declared)) {
return methodDescriptor;
}
return null;
}
/**
* Returns an array of all methods with the same name.
*/
public MethodDescriptor[] getAllMethodDescriptors(final String name) {
return getMethods().getAllMethodDescriptors(name);
}
/**
* Returns an array of all methods.
*/
public MethodDescriptor[] getAllMethodDescriptors() {
return getMethods().getAllMethodDescriptors();
}
// ---------------------------------------------------------------- properties
private Properties properties;
/**
* Returns properties collection.
* Creates new collection on first access.
*/
protected Properties getProperties() {
if (properties == null) {
properties = new Properties(this);
}
return properties;
}
/**
* Returns property descriptor. Declared flag is matched on both read and write
* methods.
*/
public PropertyDescriptor getPropertyDescriptor(final String name, final boolean declared) {
PropertyDescriptor propertyDescriptor = getProperties().getPropertyDescriptor(name);
if ((propertyDescriptor != null) && propertyDescriptor.matchDeclared(declared)) {
return propertyDescriptor;
}
return null;
}
/**
* Returns all properties descriptors.
*/
public PropertyDescriptor[] getAllPropertyDescriptors() {
return getProperties().getAllPropertyDescriptors();
}
// ---------------------------------------------------------------- ctors
private Ctors ctors;
/**
* Returns constructors collection.
* Creates new collection of first access.
*/
protected Ctors getCtors() {
if (ctors == null) {
ctors = new Ctors(this);
}
return ctors;
}
/**
* Returns the default ctor or <code>null</code> if not found.
*/
public CtorDescriptor getDefaultCtorDescriptor(final boolean declared) {
CtorDescriptor defaultCtor = getCtors().getDefaultCtor();
if ((defaultCtor != null) && defaultCtor.matchDeclared(declared)) {
return defaultCtor;
}
return null;
}
/**
* Returns the constructor identified by arguments or <code>null</code> if not found.
*/
public CtorDescriptor getCtorDescriptor(final Class[] args, final boolean declared) {
CtorDescriptor ctorDescriptor = getCtors().getCtorDescriptor(args);
if ((ctorDescriptor != null) && ctorDescriptor.matchDeclared(declared)) {
return ctorDescriptor;
}
return null;
}
/**
* Returns an array of all {@link CtorDescriptor constructor descriptors}.
*/
public CtorDescriptor[] getAllCtorDescriptors() {
return getCtors().getAllCtorDescriptors();
}
// ---------------------------------------------------------------- interfaces
/**
* Returns <b>all</b> interfaces of this class.
*/
public Class[] getAllInterfaces() {
return interfaces;
}
/**
* Returns <b>all</b> superclasses of this class.
* <code>Object.class</code> is <b>not</b> included in the
* returned list.
*/
public Class[] getAllSuperclasses() {
return superclasses;
}
}

66
fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassIntrospector.java

@ -1,66 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import java.util.Objects;
/**
* Default class {@link ClassIntrospector} simply delegates method calls for
* more convenient usage.
*/
public interface ClassIntrospector {
class Implementation {
private static ClassIntrospector classIntrospector = new CachingIntrospector();
/**
* Sets default implementation.
*/
public static void set(final ClassIntrospector classIntrospector) {
Objects.requireNonNull(classIntrospector);
Implementation.classIntrospector = classIntrospector;
}
}
/**
* Returns default implementation.
*/
static ClassIntrospector get() {
return Implementation.classIntrospector;
}
/**
* Returns class descriptor for specified type.
*/
ClassDescriptor lookup(Class type);
/**
* Clears all cached data.
*/
void reset();
}

79
fine-jodd/src/main/java/com/fr/third/jodd/introspector/CtorDescriptor.java

@ -1,79 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Constructor;
/**
* Constructor descriptor.
*/
public class CtorDescriptor extends Descriptor {
protected final Constructor constructor;
protected final Class[] parameters;
public CtorDescriptor(final ClassDescriptor classDescriptor, final Constructor constructor) {
super(classDescriptor, ClassUtil.isPublic(constructor));
this.constructor = constructor;
this.parameters = constructor.getParameterTypes();
ClassUtil.forceAccess(constructor);
}
/**
* Returns constructor name.
*/
@Override
public String getName() {
return constructor.getName();
}
/**
* Returns constructor.
*/
public Constructor getConstructor() {
return constructor;
}
/**
* Returns constructors parameters. The returned array
* is not cloned.
*/
public Class[] getParameters() {
return parameters;
}
/**
* Returns <code>true</code> if this is a default constructor
* (with no parameters).
*/
public boolean isDefault() {
return parameters.length == 0;
}
}

113
fine-jodd/src/main/java/com/fr/third/jodd/introspector/Ctors.java

@ -1,113 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import java.lang.reflect.Constructor;
/**
* Constructors collection.
*/
public class Ctors {
protected final ClassDescriptor classDescriptor;
protected final CtorDescriptor[] allCtors;
protected CtorDescriptor defaultCtor;
public Ctors(final ClassDescriptor classDescriptor) {
this.classDescriptor = classDescriptor;
this.allCtors = inspectConstructors();
}
/**
* Inspects all declared constructors of a target type.
*/
protected CtorDescriptor[] inspectConstructors() {
Class type = classDescriptor.getType();
Constructor[] ctors = type.getDeclaredConstructors();
CtorDescriptor[] allCtors = new CtorDescriptor[ctors.length];
for (int i = 0; i < ctors.length; i++) {
Constructor ctor = ctors[i];
CtorDescriptor ctorDescriptor = createCtorDescriptor(ctor);
allCtors[i] = ctorDescriptor;
if (ctorDescriptor.isDefault()) {
defaultCtor = ctorDescriptor;
}
}
return allCtors;
}
/**
* Creates new {@link CtorDescriptor}.
*/
protected CtorDescriptor createCtorDescriptor(final Constructor ctor) {
return new CtorDescriptor(classDescriptor, ctor);
}
// ---------------------------------------------------------------- get
/**
* Returns default (no-args) constructor descriptor.
*/
public CtorDescriptor getDefaultCtor() {
return defaultCtor;
}
/**
* Finds constructor description that matches given argument types.
*/
public CtorDescriptor getCtorDescriptor(final Class... args) {
ctors:
for (CtorDescriptor ctorDescriptor : allCtors) {
Class[] arg = ctorDescriptor.getParameters();
if (arg.length != args.length) {
continue;
}
for (int j = 0; j < arg.length; j++) {
if (arg[j] != args[j]) {
continue ctors;
}
}
return ctorDescriptor;
}
return null;
}
/**
* Returns all constructor descriptors.
*/
CtorDescriptor[] getAllCtorDescriptors() {
return allCtors;
}
}

70
fine-jodd/src/main/java/com/fr/third/jodd/introspector/Descriptor.java

@ -1,70 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
/**
* Common descriptor stuff.
*/
public abstract class Descriptor {
protected final ClassDescriptor classDescriptor;
protected final boolean isPublic;
protected Descriptor(final ClassDescriptor classDescriptor, final boolean isPublic) {
this.classDescriptor = classDescriptor;
this.isPublic = isPublic;
}
/**
* Returns belonging class descriptor.
*/
public ClassDescriptor getClassDescriptor() {
return classDescriptor;
}
/**
* Returns <code>true</code> if descriptor content is public.
*/
public boolean isPublic() {
return isPublic;
}
/**
* Returns <code>true</code> if descriptor content matches required declared flag.
*/
public boolean matchDeclared(final boolean declared) {
if (!declared) {
return isPublic;
}
return true;
}
/**
* Returns the name of descriptors target.
*/
public abstract String getName();
}

134
fine-jodd/src/main/java/com/fr/third/jodd/introspector/FieldDescriptor.java

@ -1,134 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
/**
* Field descriptor. Holds additional field data,
* that might be specific to implementation class.
*/
public class FieldDescriptor extends Descriptor {
public static final FieldDescriptor[] EMPTY_ARRAY = new FieldDescriptor[0];
protected final Field field;
protected final Type type;
protected final Class rawType;
protected final Class rawComponentType;
protected final Class rawKeyComponentType;
protected final MapperFunction mapperFunction;
/**
* Creates new field descriptor and resolve all additional field data.
* Also, forces access to a field.
*/
public FieldDescriptor(final ClassDescriptor classDescriptor, final Field field) {
super(classDescriptor, ClassUtil.isPublic(field));
this.field = field;
this.type = field.getGenericType();
this.rawType = ClassUtil.getRawType(type, classDescriptor.getType());
final Class[] componentTypes = ClassUtil.getComponentTypes(type, classDescriptor.getType());
if (componentTypes != null) {
this.rawComponentType = componentTypes[componentTypes.length - 1];
this.rawKeyComponentType = componentTypes[0];
} else {
this.rawComponentType = null;
this.rawKeyComponentType = null;
}
// force access
ClassUtil.forceAccess(field);
// mapper
final Mapper mapper = field.getAnnotation(Mapper.class);
if (mapper != null) {
mapperFunction = MapperFunctionInstances.get().lookup(mapper.value());
} else {
mapperFunction = null;
}
}
/**
* Returns field name.
*/
@Override
public String getName() {
return field.getName();
}
/**
* Returns field.
*/
public Field getField() {
return field;
}
/**
* Returns fields raw type.
*/
public Class getRawType() {
return rawType;
}
/**
* Returns fields raw component type. Returns <code>null</code>
* if field has no component type.
*/
public Class getRawComponentType() {
return rawComponentType;
}
/**
* Returns fields raw component type. Returns <code>null</code>
* if field has no component type.
*/
public Class getRawKeyComponentType() {
return rawKeyComponentType;
}
/**
* Resolves raw component type for given index. This value is NOT cached.
*/
public Class[] resolveRawComponentTypes() {
return ClassUtil.getComponentTypes(type, classDescriptor.getType());
}
// ---------------------------------------------------------------- toString
@Override
public String toString() {
return classDescriptor.getType().getSimpleName() + '#' + field.getName();
}
}

130
fine-jodd/src/main/java/com/fr/third/jodd/introspector/Fields.java

@ -1,130 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
/**
* Collection of {@link FieldDescriptor field descriptors}.
*/
public class Fields {
protected final ClassDescriptor classDescriptor;
protected final Map<String, FieldDescriptor> fieldsMap;
// cache
private FieldDescriptor[] allFields;
/**
* Creates new fields collection.
*/
public Fields(final ClassDescriptor classDescriptor) {
this.classDescriptor = classDescriptor;
this.fieldsMap = inspectFields();
}
/**
* Inspects fields and returns map of {@link FieldDescriptor field descriptors}.
*/
private Map<String, FieldDescriptor> inspectFields() {
if (classDescriptor.isSystemClass()) {
return emptyFields();
}
final boolean scanAccessible = classDescriptor.isScanAccessible();
final Class type = classDescriptor.getType();
final Field[] fields = scanAccessible ? ClassUtil.getAccessibleFields(type) : ClassUtil.getSupportedFields(type);
final HashMap<String, FieldDescriptor> map = new HashMap<>(fields.length);
for (final Field field : fields) {
final String fieldName = field.getName();
if (fieldName.equals("serialVersionUID")) {
continue;
}
map.put(fieldName, createFieldDescriptor(field));
}
return map;
}
/**
* Defines empty fields for special cases.
*/
private Map<String, FieldDescriptor> emptyFields() {
allFields = FieldDescriptor.EMPTY_ARRAY;
return Collections.emptyMap();
}
/**
* Creates new {@code FieldDescriptor}.
*/
protected FieldDescriptor createFieldDescriptor(final Field field) {
return new FieldDescriptor(classDescriptor, field);
}
// ---------------------------------------------------------------- get
/**
* Returns {@link FieldDescriptor field descriptor} for given field name
* or <code>null</code> if field does not exist.
*/
public FieldDescriptor getFieldDescriptor(final String name) {
return fieldsMap.get(name);
}
/**
* Returns all fields of this collection. Returns empty array
* if no fields exist. Initialized lazy.
*/
public FieldDescriptor[] getAllFieldDescriptors() {
if (allFields == null) {
FieldDescriptor[] allFields = new FieldDescriptor[fieldsMap.size()];
int index = 0;
for (FieldDescriptor fieldDescriptor : fieldsMap.values()) {
allFields[index] = fieldDescriptor;
index++;
}
Arrays.sort(allFields, Comparator.comparing(fd -> fd.getField().getName()));
this.allFields = allFields;
}
return allFields;
}
}

94
fine-jodd/src/main/java/com/fr/third/jodd/introspector/Getter.java

@ -1,94 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import java.lang.reflect.InvocationTargetException;
/**
* Unified getter property interface for both methods and fields.
*/
public interface Getter {
static Getter of(final MethodDescriptor methodDescriptor) {
return new Getter() {
@Override
public Object invokeGetter(final Object target) throws InvocationTargetException, IllegalAccessException {
return methodDescriptor.method.invoke(target);
}
@Override
public Class getGetterRawType() {
return methodDescriptor.getRawReturnType();
}
@Override
public Class getGetterRawComponentType() {
return methodDescriptor.getRawReturnComponentType();
}
@Override
public Class getGetterRawKeyComponentType() {
return methodDescriptor.getRawReturnKeyComponentType();
}
};
}
static Getter of(final FieldDescriptor fieldDescriptor) {
return new Getter() {
@Override
public Object invokeGetter(final Object target) throws IllegalAccessException {
return fieldDescriptor.field.get(target);
}
@Override
public Class getGetterRawType() {
return fieldDescriptor.getRawType();
}
@Override
public Class getGetterRawComponentType() {
return fieldDescriptor.getRawComponentType();
}
@Override
public Class getGetterRawKeyComponentType() {
return fieldDescriptor.getRawKeyComponentType();
}
};
}
Object invokeGetter(Object target) throws InvocationTargetException, IllegalAccessException;
Class getGetterRawType();
Class getGetterRawComponentType();
Class getGetterRawKeyComponentType();
}

43
fine-jodd/src/main/java/com/fr/third/jodd/introspector/Mapper.java

@ -1,43 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
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;
/**
* Value or type mapper.
* @see MapperFunction
*/
@Documented
@Retention(value = RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
public @interface Mapper {
Class<? extends MapperFunction> value();
}

37
fine-jodd/src/main/java/com/fr/third/jodd/introspector/MapperFunction.java

@ -1,37 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import java.util.function.Function;
/**
* Mapper function allows object to be converted before actually used - usually before injected using
* {@link com.fr.third.jodd.bean.BeanUtil}.
*/
@FunctionalInterface
public interface MapperFunction<IN, OUT> extends Function<IN, OUT> {
}

57
fine-jodd/src/main/java/com/fr/third/jodd/introspector/MapperFunctionInstances.java

@ -1,57 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import com.fr.third.jodd.cache.TypeCache;
import com.fr.third.jodd.util.ClassUtil;
/**
* Simple cache of {@link MapperFunction} instances.
*/
public class MapperFunctionInstances {
private static final MapperFunctionInstances MAPPER_FUNCTION_INSTANCES = new MapperFunctionInstances();
/**
* Returns the instance.
*/
public static MapperFunctionInstances get() {
return MAPPER_FUNCTION_INSTANCES;
}
protected TypeCache<MapperFunction> typeCache = TypeCache.createDefault();
public MapperFunction lookup(final Class<? extends MapperFunction> mapperFunctionClass) {
return typeCache.get(mapperFunctionClass, (c) -> {
try {
return ClassUtil.newInstance(mapperFunctionClass);
} catch (final Exception ex) {
throw new IllegalArgumentException("Invalid mapper class " + c, ex);
}
});
}
}

193
fine-jodd/src/main/java/com/fr/third/jodd/introspector/MethodDescriptor.java

@ -1,193 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
/**
* Method descriptor. Holds additional method data,
* that might be specific to implementation class.
*/
public class MethodDescriptor extends Descriptor {
private static final MethodParamDescriptor[] NO_PARAMS = new MethodParamDescriptor[0];
protected final Method method;
protected final Type returnType;
protected final Class rawReturnType;
protected final Class rawReturnComponentType;
protected final Class rawReturnKeyComponentType;
protected final MethodParamDescriptor[] parameters;
protected final MapperFunction mapperFunction;
// protected final Function getterFunction;
public MethodDescriptor(final ClassDescriptor classDescriptor, final Method method) {
super(classDescriptor, ClassUtil.isPublic(method));
this.method = method;
this.returnType = method.getGenericReturnType();
this.rawReturnType = ClassUtil.getRawType(returnType, classDescriptor.getType());
final Class[] componentTypes = ClassUtil.getComponentTypes(returnType, classDescriptor.getType());
if (componentTypes != null) {
this.rawReturnComponentType = componentTypes[componentTypes.length - 1];
this.rawReturnKeyComponentType = componentTypes[0];
} else {
this.rawReturnComponentType = null;
this.rawReturnKeyComponentType = null;
}
// force access
ClassUtil.forceAccess(method);
// mapper
final Mapper mapper = method.getAnnotation(Mapper.class);
if (mapper != null) {
mapperFunction = MapperFunctionInstances.get().lookup(mapper.value());
} else {
mapperFunction = null;
}
// parameters
if (method.getParameterCount() == 0) {
parameters = NO_PARAMS;
}
else {
parameters = new MethodParamDescriptor[method.getParameterCount()];
Class[] params = method.getParameterTypes();
Type[] genericParams = method.getGenericParameterTypes();
for (int i = 0; i < params.length; i++) {
final Class parameterType = params[i];
final Class rawParameterType = genericParams.length == 0 ?
parameterType :
ClassUtil.getRawType(genericParams[i], classDescriptor.getType());
final Class rawParameterComponentType = genericParams.length == 0 ?
null :
ClassUtil.getComponentType(genericParams[i], classDescriptor.getType(), -1);
parameters[i] = new MethodParamDescriptor(parameterType, rawParameterType, rawParameterComponentType);
}
}
// try {
// MethodHandles.Lookup lookup = MethodHandles.lookup();
// CallSite callSite = LambdaMetafactory.metafactory(lookup,
// "apply",
// MethodType.methodType(Function.class),
// MethodType.methodType(Object.class, Object.class),
// lookup.findVirtual(
// classDescriptor.getType(),
// method.getName(),
// MethodType.methodType(method.getReturnType())),
// MethodType.methodType(method.getReturnType(), classDescriptor.type)
// );
//
// this.getterFunction = (Function) callSite.getTarget().invokeExact();
// }
// catch (Throwable ex) {
// throw new IllegalArgumentException(ex);
// }
}
/**
* Returns method name.
*/
@Override
public String getName() {
return method.getName();
}
/**
* Returns method.
*/
public Method getMethod() {
return method;
}
/**
* Returns raw return type.
*/
public Class getRawReturnType() {
return rawReturnType;
}
/**
* Returns raw component type of return type.
* May be <code>null</code> if return type does not have
* components.
*/
public Class getRawReturnComponentType() {
return rawReturnComponentType;
}
/**
* Returns raw component type of return type.
* May be <code>null</code> if return type does not have
* components.
*/
public Class getRawReturnKeyComponentType() {
return rawReturnKeyComponentType;
}
/**
* Resolves raw return component types
* This value is NOT cached.
*/
public Class[] resolveRawReturnComponentTypes() {
return ClassUtil.getComponentTypes(returnType, classDescriptor.getType());
}
/**
* Returns {@link MethodParamDescriptor method parameteres}.
*/
public MethodParamDescriptor[] getParameters() {
return parameters;
}
/**
* Returns number of parameters.
*/
public int getParameterCount() {
return parameters.length;
}
// ---------------------------------------------------------------- toString
@Override
public String toString() {
return classDescriptor.getType().getSimpleName() + '#' + method.getName() + "()";
}
}

53
fine-jodd/src/main/java/com/fr/third/jodd/introspector/MethodParamDescriptor.java

@ -1,53 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
/**
* Method parameter descriptor.
*/
public class MethodParamDescriptor {
protected final Class type;
protected final Class rawType;
protected final Class rawComponentType;
public MethodParamDescriptor(final Class parameterType, final Class rawParameterType, final Class rawParameterComponentType) {
this.type = parameterType;
this.rawType = rawParameterType;
this.rawComponentType = rawParameterComponentType;
}
public Class getType() {
return type;
}
public Class getRawType() {
return rawType;
}
public Class getRawComponentType() {
return rawComponentType;
}
}

162
fine-jodd/src/main/java/com/fr/third/jodd/introspector/Methods.java

@ -1,162 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import com.fr.third.jodd.util.ArraysUtil;
import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
/**
* Methods collection.
*/
public class Methods {
protected final ClassDescriptor classDescriptor;
protected final HashMap<String, MethodDescriptor[]> methodsMap;
// cache
private MethodDescriptor[] allMethods;
public Methods(final ClassDescriptor classDescriptor) {
this.classDescriptor = classDescriptor;
this.methodsMap = inspectMethods();
}
/**
* Inspects types methods and return map of {@link MethodDescriptor method descriptors}.
*/
protected HashMap<String, MethodDescriptor[]> inspectMethods() {
boolean scanAccessible = classDescriptor.isScanAccessible();
if (classDescriptor.isSystemClass()) {
scanAccessible = false;
}
final Class type = classDescriptor.getType();
final Method[] methods = scanAccessible ? ClassUtil.getAccessibleMethods(type) : ClassUtil.getSupportedMethods(type);
final HashMap<String, MethodDescriptor[]> map = new HashMap<>(methods.length);
for (final Method method : methods) {
final String methodName = method.getName();
MethodDescriptor[] mds = map.get(methodName);
if (mds == null) {
mds = new MethodDescriptor[1];
} else {
mds = ArraysUtil.resize(mds, mds.length + 1);
}
map.put(methodName, mds);
mds[mds.length - 1] = createMethodDescriptor(method);
}
return map;
}
/**
* Creates new {@code MethodDescriptor}.
*/
protected MethodDescriptor createMethodDescriptor(final Method method) {
return new MethodDescriptor(classDescriptor, method);
}
// ---------------------------------------------------------------- get
/**
* Returns a method that matches given name and parameter types.
* Returns <code>null</code> if method is not found.
*/
public MethodDescriptor getMethodDescriptor(final String name, final Class[] paramTypes) {
final MethodDescriptor[] methodDescriptors = methodsMap.get(name);
if (methodDescriptors == null) {
return null;
}
for (MethodDescriptor methodDescriptor : methodDescriptors) {
final Method m = methodDescriptor.getMethod();
if (ClassUtil.compareParameters(m.getParameterTypes(), paramTypes)) {
return methodDescriptor;
}
}
return null;
}
/**
* Returns method descriptor for given name. If more then one methods with
* the same name exists, one method will be returned (not determined which one).
* Returns <code>null</code> if no method exist in this collection by given name.
* @see #getMethodDescriptor(String, Class[])
*/
public MethodDescriptor getMethodDescriptor(final String name) {
final MethodDescriptor[] methodDescriptors = methodsMap.get(name);
if (methodDescriptors == null) {
return null;
}
if (methodDescriptors.length != 1) {
throw new IllegalArgumentException("Method name not unique: " + name);
}
return methodDescriptors[0];
}
/**
* Returns all methods for given name. Returns <code>null</code> if method not found.
*/
public MethodDescriptor[] getAllMethodDescriptors(final String name) {
return methodsMap.get(name);
}
/**
* Returns all methods. Cached. Lazy.
*/
public MethodDescriptor[] getAllMethodDescriptors() {
if (allMethods == null) {
final List<MethodDescriptor> allMethodsList = new ArrayList<>();
for (MethodDescriptor[] methodDescriptors : methodsMap.values()) {
Collections.addAll(allMethodsList, methodDescriptors);
}
final MethodDescriptor[] allMethods = allMethodsList.toArray(new MethodDescriptor[0]);
Arrays.sort(allMethods, Comparator.comparing(md -> md.getMethod().getName()));
this.allMethods = allMethods;
}
return allMethods;
}
}

255
fine-jodd/src/main/java/com/fr/third/jodd/introspector/Properties.java

@ -1,255 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import static com.fr.third.jodd.util.ClassUtil.METHOD_GET_PREFIX;
import static com.fr.third.jodd.util.ClassUtil.METHOD_IS_PREFIX;
/**
* Bean properties collection. Property in Java is defined as a pair of
* read and write method. In Jodd, property can be extended with field
* definition. Moreover, properties will include just single fields.
* This behavior can be controlled via {@link ClassDescriptor}.
*/
public class Properties {
protected final ClassDescriptor classDescriptor;
protected final HashMap<String, PropertyDescriptor> propertyDescriptors;
// cache
private PropertyDescriptor[] allProperties;
public Properties(final ClassDescriptor classDescriptor) {
this.classDescriptor = classDescriptor;
this.propertyDescriptors = inspectProperties();
}
/**
* Inspects all properties of target type.
*/
protected HashMap<String, PropertyDescriptor> inspectProperties() {
boolean scanAccessible = classDescriptor.isScanAccessible();
Class type = classDescriptor.getType();
HashMap<String, PropertyDescriptor> map = new HashMap<>();
Method[] methods = scanAccessible ? ClassUtil.getAccessibleMethods(type) : ClassUtil.getSupportedMethods(type);
for (int iteration = 0; iteration < 2; iteration++) {
// first find the getters, and then the setters!
for (Method method : methods) {
if (Modifier.isStatic(method.getModifiers())) {
continue; // ignore static methods
}
boolean add = false;
boolean issetter = false;
String propertyName;
if (iteration == 0) {
propertyName = ClassUtil.getBeanPropertyGetterName(method);
if (propertyName != null) {
add = true;
issetter = false;
}
} else {
propertyName = ClassUtil.getBeanPropertySetterName(method);
if (propertyName != null) {
add = true;
issetter = true;
}
}
if (add) {
MethodDescriptor methodDescriptor = classDescriptor.getMethodDescriptor(method.getName(), method.getParameterTypes(), true);
addProperty(map, propertyName, methodDescriptor, issetter);
}
}
}
if (classDescriptor.isIncludeFieldsAsProperties()) {
FieldDescriptor[] fieldDescriptors = classDescriptor.getAllFieldDescriptors();
String[] prefix = classDescriptor.getPropertyFieldPrefix();
for (FieldDescriptor fieldDescriptor : fieldDescriptors) {
Field field = fieldDescriptor.getField();
if (Modifier.isStatic(field.getModifiers())) {
continue; // ignore static fields
}
String name = field.getName();
if (prefix != null) {
for (String p : prefix) {
if (!name.startsWith(p)) {
continue;
}
name = name.substring(p.length());
break;
}
}
if (!map.containsKey(name)) {
// add missing field as a potential property
map.put(name, createPropertyDescriptor(name, fieldDescriptor));
}
}
}
return map;
}
/**
* Adds a setter and/or getter method to the property.
* If property is already defined, the new, updated, definition will be created.
*/
protected void addProperty(final HashMap<String, PropertyDescriptor> map, final String name, final MethodDescriptor methodDescriptor, final boolean isSetter) {
MethodDescriptor setterMethod = isSetter ? methodDescriptor : null;
MethodDescriptor getterMethod = isSetter ? null : methodDescriptor;
PropertyDescriptor existing = map.get(name);
if (existing == null) {
// new property, just add it
PropertyDescriptor propertyDescriptor = createPropertyDescriptor(name, getterMethod, setterMethod);
map.put(name, propertyDescriptor);
return;
}
// property exist
if (!isSetter) {
// use existing setter
setterMethod = existing.getWriteMethodDescriptor();
// check existing
MethodDescriptor existingMethodDescriptor = existing.getReadMethodDescriptor();
if (existingMethodDescriptor != null) {
// check for special case of double get/is
// getter with the same name already exist
String methodName = methodDescriptor.getMethod().getName();
String existingMethodName = existingMethodDescriptor.getMethod().getName();
if (
existingMethodName.startsWith(METHOD_IS_PREFIX) &&
methodName.startsWith(METHOD_GET_PREFIX)) {
// ignore getter when ister exist
return;
}
}
} else {
// setter
// use existing getter
getterMethod = existing.getReadMethodDescriptor();
if (getterMethod != null) {
Class returnType = getterMethod.getMethod().getReturnType();
if (setterMethod != null) {
Class parameterType = setterMethod.getMethod().getParameterTypes()[0];
if (returnType != parameterType) {
// getter's type is different then setter's
return;
}
}
}
}
PropertyDescriptor propertyDescriptor = createPropertyDescriptor(name, getterMethod, setterMethod);
map.put(name, propertyDescriptor);
}
/**
* Creates new {@link PropertyDescriptor}. Note that this method may be called
* up to three times (depends on use case) for the same property. Each time when
* a property is updated, a new definition is created with updated information.
*/
protected PropertyDescriptor createPropertyDescriptor(final String name, final MethodDescriptor getterMethod, final MethodDescriptor setterMethod) {
return new PropertyDescriptor(classDescriptor, name, getterMethod, setterMethod);
}
/**
* Creates new field-only {@link PropertyDescriptor}. It will be invoked only once.
*/
protected PropertyDescriptor createPropertyDescriptor(final String name, final FieldDescriptor fieldDescriptor) {
return new PropertyDescriptor(classDescriptor, name, fieldDescriptor);
}
// ---------------------------------------------------------------- get
/**
* Returns {@link PropertyDescriptor property descriptor}.
*/
public PropertyDescriptor getPropertyDescriptor(final String name) {
return propertyDescriptors.get(name);
}
/**
* Returns all property descriptors.
* Properties are sorted by name.
*/
public PropertyDescriptor[] getAllPropertyDescriptors() {
if (allProperties == null) {
PropertyDescriptor[] allProperties = new PropertyDescriptor[propertyDescriptors.size()];
int index = 0;
for (PropertyDescriptor propertyDescriptor : propertyDescriptors.values()) {
allProperties[index] = propertyDescriptor;
index++;
}
Arrays.sort(allProperties, new Comparator<PropertyDescriptor>() {
@Override
public int compare(final PropertyDescriptor pd1, final PropertyDescriptor pd2) {
return pd1.getName().compareTo(pd2.getName());
}
});
this.allProperties = allProperties;
}
return allProperties;
}
}

313
fine-jodd/src/main/java/com/fr/third/jodd/introspector/PropertyDescriptor.java

@ -1,313 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
/**
* Property descriptor. It consist of read, write and field descriptor.
* Only one of those three descriptors may exist.
*/
public class PropertyDescriptor extends Descriptor {
protected final String name;
protected final MethodDescriptor readMethodDescriptor;
protected final MethodDescriptor writeMethodDescriptor;
protected final FieldDescriptor fieldDescriptor;
/**
* Creates field-only property descriptor.
*/
public PropertyDescriptor(final ClassDescriptor classDescriptor, final String propertyName, final FieldDescriptor fieldDescriptor) {
super(classDescriptor, false);
this.name = propertyName;
this.readMethodDescriptor = null;
this.writeMethodDescriptor = null;
this.fieldDescriptor = fieldDescriptor;
}
/**
* Creates property descriptor.
*/
public PropertyDescriptor(final ClassDescriptor classDescriptor, final String propertyName, final MethodDescriptor readMethod, final MethodDescriptor writeMethod) {
super(classDescriptor,
((readMethod == null) || readMethod.isPublic()) & (writeMethod == null || writeMethod.isPublic())
);
this.name = propertyName;
this.readMethodDescriptor = readMethod;
this.writeMethodDescriptor = writeMethod;
if (classDescriptor.isExtendedProperties()) {
String[] prefix = classDescriptor.getPropertyFieldPrefix();
FieldDescriptor fd = null;
if (prefix != null) {
for (String p : prefix) {
fd = findField(p + propertyName);
if (fd != null) {
break;
}
}
}
else {
fd = findField(propertyName);
}
this.fieldDescriptor = fd;
} else {
this.fieldDescriptor = null;
}
}
/**
* Locates property field. Field is being searched also in all
* superclasses of current class.
*/
protected FieldDescriptor findField(final String fieldName) {
FieldDescriptor fieldDescriptor = classDescriptor.getFieldDescriptor(fieldName, true);
if (fieldDescriptor != null) {
return fieldDescriptor;
}
// field descriptor not found in this class
// try to locate it in the superclasses
Class[] superclasses = classDescriptor.getAllSuperclasses();
for (Class superclass : superclasses) {
ClassDescriptor classDescriptor = ClassIntrospector.get().lookup(superclass);
fieldDescriptor = classDescriptor.getFieldDescriptor(fieldName, true);
if (fieldDescriptor != null) {
return fieldDescriptor;
}
}
// nothing found
return null;
}
/**
* Returns property name.
*/
@Override
public String getName() {
return name;
}
/**
* Returns read method of this property.
* May be <code>null</code> if read method is not defined.
*/
public MethodDescriptor getReadMethodDescriptor() {
return readMethodDescriptor;
}
/**
* Returns write method of this property.
* May be <code>null</code> for read-only properties.
*/
public MethodDescriptor getWriteMethodDescriptor() {
return writeMethodDescriptor;
}
/**
* Returns the associated field of this property.
* May be <code>null</code> if properties are not enhanced by field description.
*/
public FieldDescriptor getFieldDescriptor() {
return fieldDescriptor;
}
/**
* Returns <code>true</code> if this is an extended property with
* only field definition and without getter and setter.
*/
public boolean isFieldOnly() {
return (readMethodDescriptor == null) && (writeMethodDescriptor == null);
}
/**
* Returns <code>true</code> if this property has only a getter method.
*/
public boolean isGetterOnly() {
return (fieldDescriptor == null) && (writeMethodDescriptor == null);
}
/**
* Returns <code>true</code> if this property has only a setter method.
*/
public boolean isSetterOnly() {
return (fieldDescriptor == null) && (readMethodDescriptor == null);
}
// ---------------------------------------------------------------- type
protected Class type;
/**
* Returns property type. Raw types are detected.
*/
public Class getType() {
if (type == null) {
if (fieldDescriptor != null) {
type = fieldDescriptor.getRawType();
}
else if (readMethodDescriptor != null) {
type = getGetter(true).getGetterRawType();
//type = readMethodDescriptor.getGetterRawType();
}
else if (writeMethodDescriptor != null) {
type = getSetter(true).getSetterRawType();
//type = writeMethodDescriptor.getSetterRawType();
}
}
return type;
}
// ---------------------------------------------------------------- getters & setters
protected Getter[] getters;
protected Setter[] setters;
/**
* Returns {@link Getter}. May return <code>null</code>
* if no matched getter is found.
*/
public Getter getGetter(final boolean declared) {
if (getters == null) {
getters = new Getter[] {
createGetter(false),
createGetter(true),
};
}
return getters[declared ? 1 : 0];
}
/**
* Creates a {@link Getter}.
*/
protected Getter createGetter(final boolean declared) {
if (readMethodDescriptor != null) {
if (readMethodDescriptor.matchDeclared(declared)) {
return Getter.of(readMethodDescriptor);
}
}
if (fieldDescriptor != null) {
if (fieldDescriptor.matchDeclared(declared)) {
return Getter.of(fieldDescriptor);
}
}
return null;
}
/**
* Returns {@link Setter}. May return <code>null</code>
* if no matched setter is found.
*/
public Setter getSetter(final boolean declared) {
if (setters == null) {
setters = new Setter[] {
createSetter(false),
createSetter(true),
};
}
return setters[declared ? 1 : 0];
}
/**
* Creates a {@link Setter}.
*/
protected Setter createSetter(final boolean declared) {
if (writeMethodDescriptor != null) {
if (writeMethodDescriptor.matchDeclared(declared)) {
return Setter.of(writeMethodDescriptor);
}
}
if (fieldDescriptor != null) {
if (fieldDescriptor.matchDeclared(declared)) {
return Setter.of(fieldDescriptor);
}
}
return null;
}
// ---------------------------------------------------------------- resolvers
/**
* Resolves key type for given property descriptor.
*/
public Class resolveKeyType(final boolean declared) {
Class keyType = null;
Getter getter = getGetter(declared);
if (getter != null) {
keyType = getter.getGetterRawKeyComponentType();
}
if (keyType == null) {
FieldDescriptor fieldDescriptor = getFieldDescriptor();
if (fieldDescriptor != null) {
keyType = fieldDescriptor.getRawKeyComponentType();
}
}
return keyType;
}
/**
* Resolves component type for given property descriptor.
*/
public Class resolveComponentType(final boolean declared) {
Class componentType = null;
Getter getter = getGetter(declared);
if (getter != null) {
componentType = getter.getGetterRawComponentType();
}
if (componentType == null) {
FieldDescriptor fieldDescriptor = getFieldDescriptor();
if (fieldDescriptor != null) {
componentType = fieldDescriptor.getRawComponentType();
}
}
return componentType;
}
}

90
fine-jodd/src/main/java/com/fr/third/jodd/introspector/Setter.java

@ -1,90 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.introspector;
import java.lang.reflect.InvocationTargetException;
/**
* Unified setter property interface for both methods and fields.
*/
public interface Setter {
static Setter of(final MethodDescriptor methodDescriptor) {
return new Setter() {
@Override
public void invokeSetter(final Object target, final Object argument) throws InvocationTargetException, IllegalAccessException {
methodDescriptor.method.invoke(target, argument);
}
@Override
public Class getSetterRawType() {
return methodDescriptor.getParameters()[0].getRawType();
}
@Override
public Class getSetterRawComponentType() {
return methodDescriptor.getParameters()[0].getRawComponentType();
}
@Override
public MapperFunction getMapperFunction() {
return methodDescriptor.mapperFunction;
}
};
}
static Setter of(final FieldDescriptor fieldDescriptor) {
return new Setter() {
@Override
public void invokeSetter(final Object target, final Object argument) throws IllegalAccessException {
fieldDescriptor.field.set(target, argument);
}
@Override
public Class getSetterRawType() {
return fieldDescriptor.getRawType();
}
@Override
public Class getSetterRawComponentType() {
return fieldDescriptor.getRawComponentType();
}
@Override
public MapperFunction getMapperFunction() {
return fieldDescriptor.mapperFunction;
}
};
}
void invokeSetter(Object target, Object argument) throws IllegalAccessException, InvocationTargetException;
Class getSetterRawType();
Class getSetterRawComponentType();
MapperFunction getMapperFunction();
}

29
fine-jodd/src/main/java/com/fr/third/jodd/introspector/package-info.java

@ -1,29 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/**
* Very fast reflection introspector.
*/
package com.fr.third.jodd.introspector;

121
fine-jodd/src/main/java/com/fr/third/jodd/io/AppendableWriter.java

@ -1,121 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.io;
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.io.Writer;
import java.nio.CharBuffer;
/**
* Appendable writer adapter.
*/
public class AppendableWriter extends Writer {
private final Appendable appendable;
private final boolean flushable;
private boolean closed;
public AppendableWriter(final Appendable appendable) {
this.appendable = appendable;
this.flushable = appendable instanceof Flushable;
this.closed = false;
}
@Override
public void write(final char[] cbuf, final int off, final int len) throws IOException {
checkNotClosed();
appendable.append(CharBuffer.wrap(cbuf), off, off + len);
}
@Override
public void write(final int c) throws IOException {
checkNotClosed();
appendable.append((char) c);
}
@Override
public Writer append(final char c) throws IOException {
checkNotClosed();
appendable.append(c);
return this;
}
@Override
public Writer append(final CharSequence csq, final int start, final int end) throws IOException {
checkNotClosed();
appendable.append(csq, start, end);
return this;
}
@Override
public Writer append(final CharSequence csq) throws IOException {
checkNotClosed();
appendable.append(csq);
return this;
}
@Override
public void write(final String str, final int off, final int len) throws IOException {
checkNotClosed();
appendable.append(str, off, off + len);
}
@Override
public void write(final String str) throws IOException {
appendable.append(str);
}
@Override
public void write(final char[] cbuf) throws IOException {
appendable.append(CharBuffer.wrap(cbuf));
}
@Override
public void flush() throws IOException {
checkNotClosed();
if (flushable) {
((Flushable) appendable).flush();
}
}
private void checkNotClosed() throws IOException {
if (closed) {
throw new IOException("Cannot write to closed writer " + this);
}
}
@Override
public void close() throws IOException {
if (!closed) {
flush();
if (appendable instanceof Closeable) {
((Closeable) appendable).close();
}
closed = true;
}
}
}

60
fine-jodd/src/main/java/com/fr/third/jodd/io/CharBufferReader.java

@ -1,60 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.io;
import java.io.Reader;
import java.nio.CharBuffer;
/**
* Reader that wraps a <code>CharBuffer</code>.
*/
public class CharBufferReader extends Reader {
private final CharBuffer charBuffer;
public CharBufferReader(final CharBuffer charBuffer) {
// duplicate so to allow to move independently,
// but share the same underlying data.
this.charBuffer = charBuffer.duplicate();
}
@Override
public int read(final char[] chars, final int offset, final int length) {
int read = Math.min(charBuffer.remaining(), length);
charBuffer.get(chars, offset, read);
return read;
}
@Override
public int read() {
return charBuffer.position() < charBuffer.limit() ? charBuffer.get() : -1;
}
@Override
public void close() {
}
}

146
fine-jodd/src/main/java/com/fr/third/jodd/io/FastByteArrayOutputStream.java

@ -1,146 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.io;
import com.fr.third.jodd.util.StringUtil;
import com.fr.third.jodd.buffer.FastByteBuffer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* This class implements an {@link OutputStream} in which the data is
* written into a byte array. The buffer automatically grows as data
* is written to it.
* <p>
* The data can be retrieved using {@link #toByteArray()} and {@link #toString}.
* <p>
* Closing a {@link FastByteArrayOutputStream} has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an {@link IOException}.
* <p>
* This is an alternative implementation of the {@code java.io.FastByteArrayOutputStream}
* class. The original implementation only allocates 32 bytes at the beginning.
* As this class is designed for heavy duty it starts at 1024 bytes. In contrast
* to the original it doesn't reallocate the whole memory block but allocates
* additional buffers. This way no buffers need to be garbage collected and
* the contents don't have to be copied to the new buffer. This class is
* designed to behave exactly like the original. The only exception is the
* deprecated {@code java.io.FastByteArrayOutputStream#toString(int)} method that has been ignored.
*/
public class FastByteArrayOutputStream extends OutputStream {
private final FastByteBuffer buffer;
/**
* Creates a new byte array {@link OutputStream}. The buffer capacity is
* initially 1024 bytes, though its size increases if necessary.
*/
public FastByteArrayOutputStream() {
this(1024);
}
/**
* Creates a new byte array output stream, with a buffer capacity of
* the specified size, in bytes.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public FastByteArrayOutputStream(final int size) {
buffer = new FastByteBuffer(size);
}
/**
* @see OutputStream#write(byte[], int, int)
*/
@Override
public void write(final byte[] b, final int off, final int len) {
buffer.append(b, off, len);
}
/**
* Writes single byte.
*/
@Override
public void write(final int b) {
buffer.append((byte) b);
}
/**
* @see ByteArrayOutputStream#size()
*/
public int size() {
return buffer.size();
}
/**
* Closing a {@link FastByteArrayOutputStream} has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an {@link IOException}.
*/
@Override
public void close() {
//nop
}
/**
* @see ByteArrayOutputStream#reset()
*/
public void reset() {
buffer.clear();
}
/**
* @see ByteArrayOutputStream#writeTo(OutputStream)
*/
public void writeTo(final OutputStream out) throws IOException {
out.write(buffer.toArray());
}
/**
* @see ByteArrayOutputStream#toByteArray()
*/
public byte[] toByteArray() {
return buffer.toArray();
}
/**
* @see ByteArrayOutputStream#toString()
*/
@Override
public String toString() {
return new String(toByteArray());
}
/**
* @see ByteArrayOutputStream#toString(String)
*/
public String toString(final String enc) {
return StringUtil.newString(toByteArray(), enc);
}
}

134
fine-jodd/src/main/java/com/fr/third/jodd/io/FastCharArrayWriter.java

@ -1,134 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.io;
import com.fr.third.jodd.buffer.FastCharBuffer;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.Writer;
/**
* Similar to {@link FastByteArrayOutputStream} but for {@link Writer}.
*/
public class FastCharArrayWriter extends Writer {
private final FastCharBuffer buffer;
/**
* Creates a new writer. The buffer capacity is
* initially 1024 bytes, though its size increases if necessary.
*/
public FastCharArrayWriter() {
this(1024);
}
/**
* Creates a new char array {@link Writer}, with a buffer capacity of
* the specified size, in bytes.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public FastCharArrayWriter(final int size) {
buffer = new FastCharBuffer(size);
}
/**
* @see Writer#write(char[], int, int)
*/
@Override
public void write(final char[] b, final int off, final int len) {
buffer.append(b, off, len);
}
/**
* Writes single byte.
*/
@Override
public void write(final int b) {
buffer.append((char) b);
}
@Override
public void write(final String s, final int off, final int len) {
write(s.toCharArray(), off, len);
}
/**
* @see CharArrayWriter#size()
*/
public int size() {
return buffer.size();
}
/**
* Closing a {@link FastCharArrayWriter} has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an {@link IOException}.
*/
@Override
public void close() {
//nop
}
/**
* Flushing a {@link FastCharArrayWriter} has no effects.
*/
@Override
public void flush() {
//nop
}
/**
* @see CharArrayWriter#reset()
*/
public void reset() {
buffer.clear();
}
/**
* @see CharArrayWriter#writeTo(Writer)
*/
public void writeTo(final Writer out) throws IOException {
out.write(buffer.toArray());
}
/**
* @see CharArrayWriter#toCharArray()
*/
public char[] toCharArray() {
return buffer.toArray();
}
/**
* @see CharArrayWriter#toString()
*/
@Override
public String toString() {
return new String(toCharArray());
}
}

1006
fine-jodd/src/main/java/com/fr/third/jodd/io/FileNameUtil.java

File diff suppressed because it is too large Load Diff

1685
fine-jodd/src/main/java/com/fr/third/jodd/io/FileUtil.java

File diff suppressed because it is too large Load Diff

194
fine-jodd/src/main/java/com/fr/third/jodd/io/NetUtil.java

@ -1,194 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.io;
import com.fr.third.jodd.util.StringUtil;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.StandardOpenOption;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Network utilities.
*/
public class NetUtil {
public static final String LOCAL_HOST = "localhost";
public static final String LOCAL_IP = "127.0.0.1";
public static final String DEFAULT_MASK = "255.255.255.0";
public static final int INT_VALUE_127_0_0_1 = 0x7f000001;
/**
* Resolves IP address from a hostname.
*/
public static String resolveIpAddress(final String hostname) {
try {
InetAddress netAddress;
if (hostname == null || hostname.equalsIgnoreCase(LOCAL_HOST)) {
netAddress = InetAddress.getLocalHost();
} else {
netAddress = Inet4Address.getByName(hostname);
}
return netAddress.getHostAddress();
} catch (UnknownHostException ignore) {
return null;
}
}
/**
* Returns IP address as integer.
*/
public static int getIpAsInt(final String ipAddress) {
int ipIntValue = 0;
String[] tokens = StringUtil.splitc(ipAddress, '.');
for (String token : tokens) {
if (ipIntValue > 0) {
ipIntValue <<= 8;
}
ipIntValue += Integer.parseInt(token);
}
return ipIntValue;
}
public static int getMaskAsInt(String mask) {
if (!validateIPv4(mask)) {
mask = DEFAULT_MASK;
}
return getIpAsInt(mask);
}
public static boolean isSocketAccessAllowed(final int localIp, final int socketIp, final int mask) {
boolean _retVal = false;
if (socketIp == INT_VALUE_127_0_0_1 || (localIp & mask) == (socketIp & mask)) {
_retVal = true;
}
return _retVal;
}
private static final Pattern ip4RegExp = Pattern.compile("^((?:1?[1-9]?\\d|2(?:[0-4]\\d|5[0-5]))\\.){4}$");
/**
* Checks given string against IP address v4 format.
*
* @param input an ip address - may be null
* @return <tt>true</tt> if param has a valid ip v4 format <tt>false</tt> otherwise
* @see <a href="https://en.wikipedia.org/wiki/IP_address#IPv4_addresses">ip address v4</a>
*/
public static boolean validateIPv4(final String input) {
Matcher m = ip4RegExp.matcher(input + '.');
return m.matches();
}
/**
* Resolves host name from IP address bytes.
*/
public static String resolveHostName(final byte[] ip) {
try {
InetAddress address = InetAddress.getByAddress(ip);
return address.getHostName();
} catch (UnknownHostException ignore) {
return null;
}
}
// ---------------------------------------------------------------- download
/**
* Downloads resource as byte array.
*/
public static byte[] downloadBytes(final String url) throws IOException {
try (InputStream inputStream = new URL(url).openStream()) {
return StreamUtil.readBytes(inputStream);
}
}
/**
* Downloads resource as String.
*/
public static String downloadString(final String url, final String encoding) throws IOException {
try (InputStream inputStream = new URL(url).openStream()) {
return new String(StreamUtil.readChars(inputStream, encoding));
}
}
/**
* Downloads resource as String.
*/
public static String downloadString(final String url) throws IOException {
try (InputStream inputStream = new URL(url).openStream()) {
return new String(StreamUtil.readChars(inputStream));
}
}
/**
* Downloads resource to a file, potentially very efficiently.
*/
public static void downloadFile(final String url, final File file) throws IOException {
try (
InputStream inputStream = new URL(url).openStream();
ReadableByteChannel rbc = Channels.newChannel(inputStream);
FileChannel fileChannel = FileChannel.open(
file.toPath(),
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE)
) {
fileChannel.transferFrom(rbc, 0, Long.MAX_VALUE);
}
}
/**
* Get remote file size. Returns -1 if the content length is unknown
*
* @param url remote file url
* @return file size
* @throws IOException JDK-IOException
*/
public static long getRemoteFileSize(String url) throws IOException {
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(url).openConnection();
return connection.getContentLengthLong();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}

92
fine-jodd/src/main/java/com/fr/third/jodd/io/PathUtil.java

@ -1,92 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.io;
import com.fr.third.jodd.util.StringUtil;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
public class PathUtil {
/**
* Resolves subpath in safer way. For some reason, if child starts with
* a separator it gets resolved as a full path, ignoring the base.
* This method acts different.
*/
public static Path resolve(final Path base, String child) {
if (StringUtil.startsWithChar(child, File.separatorChar)) {
child = child.substring(1);
}
return base.resolve(child);
}
public static Path resolve(Path path, final String... childs) {
for (String child : childs) {
path = resolve(path, child);
}
return path;
}
/**
* Reads path content.
*/
public static String readString(final Path path) throws IOException {
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
StringWriter writer = new StringWriter(); // flush & close not needed for StringWriter-instance
StreamUtil.copy(reader, writer);
return writer.toString();
}
}
/**
* Deletes a directory recursively.
*/
public static void deleteFileTree(final Path directory) throws IOException {
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
}

125
fine-jodd/src/main/java/com/fr/third/jodd/io/StreamGobbler.java

@ -1,125 +0,0 @@
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package com.fr.third.jodd.io;
import com.fr.third.jodd.util.StringPool;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
/**
* Consumes a stream.
* For any <code>Process</code>, the input and error streams must read even
* if the data written to these streams is not used by the application.
* The generally accepted solution for this problem is a stream gobbler thread
* that does nothing but consume data from an input stream until stopped.
*/
public class StreamGobbler extends Thread {
protected final InputStream is;
protected final String prefix;
protected final OutputStream out;
protected final Object lock = new Object();
protected boolean end = false;
public StreamGobbler(final InputStream is) {
this(is, null, null);
}
public StreamGobbler(final InputStream is, final OutputStream output) {
this(is, output, null);
}
public StreamGobbler(final InputStream is, final OutputStream output, final String prefix) {
this.is = is;
this.prefix = prefix;
this.out = output;
}
@Override
public void run() {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
try {
String line;
while ((line = br.readLine()) != null) {
if (out != null) {
if (prefix != null) {
out.write(prefix.getBytes());
}
out.write(line.getBytes());
out.write(StringPool.BYTES_NEW_LINE);
}
}
}
catch (IOException ioe) {
if (out != null) {
ioe.printStackTrace(new PrintStream(out));
}
}
finally {
if (out != null) {
try {
out.flush();
}
catch (IOException ignore) {
}
}
try {
br.close();
}
catch (IOException ignore) {
}
}
synchronized (lock) {
lock.notifyAll();
end = true;
}
}
/**
* Waits for gobbler to end.
*/
public void waitFor() {
try {
synchronized (lock) {
if (!end) {
lock.wait();
}
}
}
catch (InterruptedException ignore) {
Thread.currentThread().interrupt();
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save