From 43ddad8941e5b18ba544e742b634049624c223bd Mon Sep 17 00:00:00 2001 From: cal101 Date: Sat, 13 Feb 2021 15:56:06 +0000 Subject: [PATCH 01/47] [cleanup] erefactor/EclipseJdt - Remove unused imports EclipseJdt cleanup 'RemoveUnusedImport' applied by erefactor. For EclipseJdt see https://www.eclipse.org/eclipse/news/4.18/jdt.php For erefactor see https://github.com/cal101/erefactor --- hutool-core/src/main/java/cn/hutool/core/util/PhoneUtil.java | 2 -- hutool-core/src/test/java/cn/hutool/core/codec/BCDTest.java | 2 -- .../test/java/cn/hutool/core/convert/ConvertOtherTest.java | 1 - .../java/cn/hutool/core/convert/ConverterRegistryTest.java | 3 --- hutool-db/src/test/java/cn/hutool/db/EntityTest.java | 1 - hutool-db/src/test/java/cn/hutool/db/PostgreTest.java | 4 ---- hutool-db/src/test/java/cn/hutool/db/SqlServerTest.java | 4 ---- hutool-http/src/test/java/cn/hutool/http/DownloadTest.java | 2 -- hutool-http/src/test/java/cn/hutool/http/HtmlUtilTest.java | 2 -- hutool-http/src/test/java/cn/hutool/http/HttpsTest.java | 1 - hutool-http/src/test/java/cn/hutool/http/RestTest.java | 3 --- hutool-poi/src/main/java/cn/hutool/poi/word/TableUtil.java | 1 - 12 files changed, 26 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/PhoneUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/PhoneUtil.java index 5762eb452..885bd705a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/PhoneUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/PhoneUtil.java @@ -3,8 +3,6 @@ package cn.hutool.core.util; import cn.hutool.core.lang.PatternPool; import cn.hutool.core.lang.Validator; -import java.util.regex.Pattern; - /** * 手机号工具类 diff --git a/hutool-core/src/test/java/cn/hutool/core/codec/BCDTest.java b/hutool-core/src/test/java/cn/hutool/core/codec/BCDTest.java index 1aca94c7a..0678887f4 100644 --- a/hutool-core/src/test/java/cn/hutool/core/codec/BCDTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/codec/BCDTest.java @@ -3,8 +3,6 @@ package cn.hutool.core.codec; import org.junit.Assert; import org.junit.Test; -import cn.hutool.core.codec.BCD; - public class BCDTest { @Test diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertOtherTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertOtherTest.java index de159184b..947b87455 100644 --- a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertOtherTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertOtherTest.java @@ -5,7 +5,6 @@ import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Test; -import cn.hutool.core.convert.Convert; import cn.hutool.core.util.CharsetUtil; /** diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/ConverterRegistryTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/ConverterRegistryTest.java index 2d5f0d8bd..a00591514 100644 --- a/hutool-core/src/test/java/cn/hutool/core/convert/ConverterRegistryTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/ConverterRegistryTest.java @@ -3,9 +3,6 @@ package cn.hutool.core.convert; import org.junit.Assert; import org.junit.Test; -import cn.hutool.core.convert.Converter; -import cn.hutool.core.convert.ConverterRegistry; - /** * ConverterRegistry 单元测试 * @author Looly diff --git a/hutool-db/src/test/java/cn/hutool/db/EntityTest.java b/hutool-db/src/test/java/cn/hutool/db/EntityTest.java index 3fe18f6c1..8d48a2557 100644 --- a/hutool-db/src/test/java/cn/hutool/db/EntityTest.java +++ b/hutool-db/src/test/java/cn/hutool/db/EntityTest.java @@ -3,7 +3,6 @@ package cn.hutool.db; import org.junit.Assert; import org.junit.Test; -import cn.hutool.db.Entity; import cn.hutool.db.pojo.User; /** diff --git a/hutool-db/src/test/java/cn/hutool/db/PostgreTest.java b/hutool-db/src/test/java/cn/hutool/db/PostgreTest.java index befd389a2..a19559a7e 100644 --- a/hutool-db/src/test/java/cn/hutool/db/PostgreTest.java +++ b/hutool-db/src/test/java/cn/hutool/db/PostgreTest.java @@ -6,10 +6,6 @@ import org.junit.Ignore; import org.junit.Test; import cn.hutool.core.lang.Console; -import cn.hutool.db.Db; -import cn.hutool.db.Entity; -import cn.hutool.db.Page; -import cn.hutool.db.PageResult; /** * PostgreSQL 单元测试 diff --git a/hutool-db/src/test/java/cn/hutool/db/SqlServerTest.java b/hutool-db/src/test/java/cn/hutool/db/SqlServerTest.java index da80f89e7..c9842b458 100644 --- a/hutool-db/src/test/java/cn/hutool/db/SqlServerTest.java +++ b/hutool-db/src/test/java/cn/hutool/db/SqlServerTest.java @@ -6,10 +6,6 @@ import org.junit.Ignore; import org.junit.Test; import cn.hutool.core.lang.Console; -import cn.hutool.db.Db; -import cn.hutool.db.Entity; -import cn.hutool.db.Page; -import cn.hutool.db.PageResult; /** * SQL Server操作单元测试 diff --git a/hutool-http/src/test/java/cn/hutool/http/DownloadTest.java b/hutool-http/src/test/java/cn/hutool/http/DownloadTest.java index 2732cbc1f..e084a54de 100644 --- a/hutool-http/src/test/java/cn/hutool/http/DownloadTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/DownloadTest.java @@ -4,8 +4,6 @@ import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.StreamProgress; import cn.hutool.core.lang.Console; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpUtil; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; diff --git a/hutool-http/src/test/java/cn/hutool/http/HtmlUtilTest.java b/hutool-http/src/test/java/cn/hutool/http/HtmlUtilTest.java index 6d4309e62..b0fda17ae 100644 --- a/hutool-http/src/test/java/cn/hutool/http/HtmlUtilTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/HtmlUtilTest.java @@ -3,8 +3,6 @@ package cn.hutool.http; import org.junit.Assert; import org.junit.Test; -import cn.hutool.http.HtmlUtil; - /** * Html单元测试 * diff --git a/hutool-http/src/test/java/cn/hutool/http/HttpsTest.java b/hutool-http/src/test/java/cn/hutool/http/HttpsTest.java index d0254316c..ece225ed5 100644 --- a/hutool-http/src/test/java/cn/hutool/http/HttpsTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/HttpsTest.java @@ -2,7 +2,6 @@ package cn.hutool.http; import cn.hutool.core.lang.Console; import cn.hutool.core.thread.ThreadUtil; -import cn.hutool.http.HttpUtil; import org.junit.Ignore; import org.junit.Test; diff --git a/hutool-http/src/test/java/cn/hutool/http/RestTest.java b/hutool-http/src/test/java/cn/hutool/http/RestTest.java index 0337868c6..15d022b1e 100644 --- a/hutool-http/src/test/java/cn/hutool/http/RestTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/RestTest.java @@ -1,9 +1,6 @@ package cn.hutool.http; import cn.hutool.core.lang.Console; -import cn.hutool.http.Header; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; import org.junit.Assert; import org.junit.Ignore; diff --git a/hutool-poi/src/main/java/cn/hutool/poi/word/TableUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/word/TableUtil.java index f33ed1fac..ef0bd8d17 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/word/TableUtil.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/word/TableUtil.java @@ -5,7 +5,6 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.IterUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Assert; -import cn.hutool.core.lang.Console; import cn.hutool.core.map.MapUtil; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFTable; From fff07de3d292533a8d3da6f461add3bd0f1c9701 Mon Sep 17 00:00:00 2001 From: cal101 Date: Sat, 13 Feb 2021 16:02:32 +0000 Subject: [PATCH 02/47] [cleanup] erefactor/EclipseJdt - Use diamond operator EclipseJdt cleanup 'UseDiamondOperator' applied by erefactor. For EclipseJdt see https://www.eclipse.org/eclipse/news/4.18/jdt.php For erefactor see https://github.com/cal101/erefactor --- .../src/main/java/cn/hutool/core/builder/HashCodeBuilder.java | 2 +- .../test/java/cn/hutool/json/test/bean/report/CaseReport.java | 2 +- .../test/java/cn/hutool/json/test/bean/report/SuiteReport.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/builder/HashCodeBuilder.java b/hutool-core/src/main/java/cn/hutool/core/builder/HashCodeBuilder.java index 2de15b49d..9991c7856 100644 --- a/hutool-core/src/main/java/cn/hutool/core/builder/HashCodeBuilder.java +++ b/hutool-core/src/main/java/cn/hutool/core/builder/HashCodeBuilder.java @@ -103,7 +103,7 @@ public class HashCodeBuilder implements Builder { * * @since 2.3 */ - private static final ThreadLocal> REGISTRY = new ThreadLocal>(); + private static final ThreadLocal> REGISTRY = new ThreadLocal<>(); /* * NOTE: we cannot store the actual objects in a HashSet, as that would use the very hashCode() diff --git a/hutool-json/src/test/java/cn/hutool/json/test/bean/report/CaseReport.java b/hutool-json/src/test/java/cn/hutool/json/test/bean/report/CaseReport.java index 37145cca7..670a3ff53 100644 --- a/hutool-json/src/test/java/cn/hutool/json/test/bean/report/CaseReport.java +++ b/hutool-json/src/test/java/cn/hutool/json/test/bean/report/CaseReport.java @@ -14,7 +14,7 @@ public class CaseReport { /** * 包含的测试步骤报告 */ - private List stepReports = new ArrayList(); + private List stepReports = new ArrayList<>(); public List getStepReports() { return stepReports; diff --git a/hutool-json/src/test/java/cn/hutool/json/test/bean/report/SuiteReport.java b/hutool-json/src/test/java/cn/hutool/json/test/bean/report/SuiteReport.java index 65bb5dedf..d6e0fe88b 100644 --- a/hutool-json/src/test/java/cn/hutool/json/test/bean/report/SuiteReport.java +++ b/hutool-json/src/test/java/cn/hutool/json/test/bean/report/SuiteReport.java @@ -14,7 +14,7 @@ public class SuiteReport { /** * 包含的用例测试报告 */ - private List caseReports = new ArrayList(); + private List caseReports = new ArrayList<>(); public List getCaseReports() { return caseReports; From ff533c96d8b74902699f9d9160db671d93dfe6ae Mon Sep 17 00:00:00 2001 From: cal101 Date: Sun, 14 Feb 2021 10:36:41 +0000 Subject: [PATCH 03/47] [cleanup] erefactor/EclipseJdt - Add missing Annotations - Implementations of interface methods (1.6 or higher) EclipseJdt cleanup 'AddMissingOverrideAnnotation' applied by erefactor. For EclipseJdt see https://www.eclipse.org/eclipse/news/4.18/jdt.php For erefactor see https://github.com/cal101/erefactor --- .../src/main/java/cn/hutool/cache/impl/AbstractCache.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java index f1c3ba7bf..863ac0c53 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java @@ -307,6 +307,7 @@ public abstract class AbstractCache implements Cache { * @return this * @since 5.5.2 */ + @Override public AbstractCache setListener(CacheListener listener) { this.listener = listener; return this; From b76aacdec8a76b526e69ece285c6bca845eda4bf Mon Sep 17 00:00:00 2001 From: cal101 Date: Sun, 14 Feb 2021 11:33:44 +0000 Subject: [PATCH 04/47] [cleanup] erefactor/EclipseJdt - Remove trailing whitespace - All lines EclipseJdt cleanup 'RemoveAllTrailingWhitespace' applied by erefactor. For EclipseJdt see https://www.eclipse.org/eclipse/news/4.18/jdt.php For erefactor see https://github.com/cal101/erefactor --- .../src/main/java/cn/hutool/package-info.java | 4 ++-- .../src/main/java/cn/hutool/aop/ProxyUtil.java | 16 ++++++++-------- .../java/cn/hutool/aop/aspects/package-info.java | 2 +- .../cn/hutool/aop/interceptor/package-info.java | 2 +- .../main/java/cn/hutool/aop/package-info.java | 2 +- .../cn/hutool/aop/proxy/CglibProxyFactory.java | 2 +- .../aop/proxy/SpringCglibProxyFactory.java | 2 +- .../java/cn/hutool/aop/proxy/package-info.java | 2 +- .../cn/hutool/bloomfilter/BitSetBloomFilter.java | 16 ++++++++-------- .../java/cn/hutool/bloomfilter/BloomFilter.java | 4 ++-- .../cn/hutool/bloomfilter/BloomFilterUtil.java | 6 +++--- .../cn/hutool/bloomfilter/bitMap/BitMap.java | 8 ++++---- .../cn/hutool/bloomfilter/bitMap/IntMap.java | 4 ++-- .../cn/hutool/bloomfilter/bitMap/LongMap.java | 4 ++-- .../hutool/bloomfilter/bitMap/package-info.java | 2 +- .../bloomfilter/filter/AbstractFilter.java | 10 +++++----- .../cn/hutool/bloomfilter/filter/ELFFilter.java | 4 ++-- .../cn/hutool/bloomfilter/filter/HfFilter.java | 4 ++-- .../cn/hutool/bloomfilter/filter/JSFilter.java | 4 ++-- .../hutool/bloomfilter/filter/package-info.java | 2 +- 20 files changed, 50 insertions(+), 50 deletions(-) diff --git a/hutool-all/src/main/java/cn/hutool/package-info.java b/hutool-all/src/main/java/cn/hutool/package-info.java index a38c4abce..d824ccabd 100644 --- a/hutool-all/src/main/java/cn/hutool/package-info.java +++ b/hutool-all/src/main/java/cn/hutool/package-info.java @@ -1,11 +1,11 @@ /** * Hutool是Hu + tool的自造词,前者致敬我的“前任公司”,后者为工具之意,谐音“糊涂”,寓意追求“万事都作糊涂观,无所谓失,无所谓得”的境界。 - * + * *

* Hutool是一个Java工具包,也只是一个工具包,它帮助我们简化每一行代码,减少每一个方法,让Java语言也可以“甜甜的”。
* Hutool最初是我项目中“util”包的一个整理,后来慢慢积累并加入更多非业务相关功能,并广泛学习其它开源项目精髓,经过自己整理修改,最终形成丰富的开源工具集。 *

- * + * * @author looly * */ diff --git a/hutool-aop/src/main/java/cn/hutool/aop/ProxyUtil.java b/hutool-aop/src/main/java/cn/hutool/aop/ProxyUtil.java index 7239278f9..92bd4760d 100644 --- a/hutool-aop/src/main/java/cn/hutool/aop/ProxyUtil.java +++ b/hutool-aop/src/main/java/cn/hutool/aop/ProxyUtil.java @@ -13,10 +13,10 @@ import cn.hutool.core.util.ClassUtil; * */ public final class ProxyUtil { - + /** * 使用切面代理对象 - * + * * @param 切面对象类型 * @param target 目标对象 * @param aspectClass 切面对象类 @@ -25,10 +25,10 @@ public final class ProxyUtil { public static T proxy(T target, Class aspectClass){ return ProxyFactory.createProxy(target, aspectClass); } - + /** * 使用切面代理对象 - * + * * @param 被代理对象类型 * @param target 被代理对象 * @param aspect 切面对象 @@ -47,8 +47,8 @@ public final class ProxyUtil { * 3、调用$Proxy0的$Proxy0(InvocationHandler)构造函数 创建$Proxy0的对象,并且用interfaces参数遍历其所有接口的方法,这些实现方法的实现本质上是通过反射调用被代理对象的方法
* 4、将$Proxy0的实例返回给客户端。
* 5、当调用代理类的相应方法时,相当于调用 {@link InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[])} 方法 - * - * + * + * * @param 被代理对象类型 * @param classloader 被代理类对应的ClassLoader * @param invocationHandler {@link InvocationHandler} ,被代理类通过实现此接口提供动态代理功能 @@ -59,10 +59,10 @@ public final class ProxyUtil { public static T newProxyInstance(ClassLoader classloader, InvocationHandler invocationHandler, Class... interfaces) { return (T) Proxy.newProxyInstance(classloader, interfaces, invocationHandler); } - + /** * 创建动态代理对象 - * + * * @param 被代理对象类型 * @param invocationHandler {@link InvocationHandler} ,被代理类通过实现此接口提供动态代理功能 * @param interfaces 代理类中需要实现的被代理类的接口方法 diff --git a/hutool-aop/src/main/java/cn/hutool/aop/aspects/package-info.java b/hutool-aop/src/main/java/cn/hutool/aop/aspects/package-info.java index d377d9ae4..fab914fbd 100644 --- a/hutool-aop/src/main/java/cn/hutool/aop/aspects/package-info.java +++ b/hutool-aop/src/main/java/cn/hutool/aop/aspects/package-info.java @@ -1,6 +1,6 @@ /** * 切面实现,提供一些基本的切面实现 - * + * * @author looly * */ diff --git a/hutool-aop/src/main/java/cn/hutool/aop/interceptor/package-info.java b/hutool-aop/src/main/java/cn/hutool/aop/interceptor/package-info.java index 5c189b36e..54c58158f 100644 --- a/hutool-aop/src/main/java/cn/hutool/aop/interceptor/package-info.java +++ b/hutool-aop/src/main/java/cn/hutool/aop/interceptor/package-info.java @@ -1,6 +1,6 @@ /** * 代理拦截器实现 - * + * * @author looly * */ diff --git a/hutool-aop/src/main/java/cn/hutool/aop/package-info.java b/hutool-aop/src/main/java/cn/hutool/aop/package-info.java index d089f3d0b..3b2d2a93a 100644 --- a/hutool-aop/src/main/java/cn/hutool/aop/package-info.java +++ b/hutool-aop/src/main/java/cn/hutool/aop/package-info.java @@ -1,6 +1,6 @@ /** * JDK动态代理封装,提供非IOC下的切面支持 - * + * * @author looly * */ diff --git a/hutool-aop/src/main/java/cn/hutool/aop/proxy/CglibProxyFactory.java b/hutool-aop/src/main/java/cn/hutool/aop/proxy/CglibProxyFactory.java index 517b639ae..d7510035c 100644 --- a/hutool-aop/src/main/java/cn/hutool/aop/proxy/CglibProxyFactory.java +++ b/hutool-aop/src/main/java/cn/hutool/aop/proxy/CglibProxyFactory.java @@ -6,7 +6,7 @@ import net.sf.cglib.proxy.Enhancer; /** * 基于Cglib的切面代理工厂 - * + * * @author looly * */ diff --git a/hutool-aop/src/main/java/cn/hutool/aop/proxy/SpringCglibProxyFactory.java b/hutool-aop/src/main/java/cn/hutool/aop/proxy/SpringCglibProxyFactory.java index 36d50de59..caa43e596 100644 --- a/hutool-aop/src/main/java/cn/hutool/aop/proxy/SpringCglibProxyFactory.java +++ b/hutool-aop/src/main/java/cn/hutool/aop/proxy/SpringCglibProxyFactory.java @@ -6,7 +6,7 @@ import org.springframework.cglib.proxy.Enhancer; /** * 基于Spring-cglib的切面代理工厂 - * + * * @author looly * */ diff --git a/hutool-aop/src/main/java/cn/hutool/aop/proxy/package-info.java b/hutool-aop/src/main/java/cn/hutool/aop/proxy/package-info.java index 90b5d6d07..b75feeeab 100644 --- a/hutool-aop/src/main/java/cn/hutool/aop/proxy/package-info.java +++ b/hutool-aop/src/main/java/cn/hutool/aop/proxy/package-info.java @@ -1,6 +1,6 @@ /** * 代理实现 - * + * * @author looly * */ diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BitSetBloomFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BitSetBloomFilter.java index 54e0ae74b..5e9703a36 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BitSetBloomFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BitSetBloomFilter.java @@ -16,7 +16,7 @@ import java.util.BitSet; */ public class BitSetBloomFilter implements BloomFilter{ private static final long serialVersionUID = 1L; - + private final BitSet bitSet; private final int bitSetSize; private final int addedElements; @@ -24,7 +24,7 @@ public class BitSetBloomFilter implements BloomFilter{ /** * 构造一个布隆过滤器,过滤器的容量为c * n 个bit. - * + * * @param c 当前过滤器预先开辟的最大包含记录,通常要比预计存入的记录多一倍. * @param n 当前过滤器预计所要包含的记录. * @param k 哈希函数的个数,等同每条记录要占用的bit数. @@ -38,7 +38,7 @@ public class BitSetBloomFilter implements BloomFilter{ /** * 通过文件初始化过滤器. - * + * * @param path 文件路径 * @param charset 字符集 * @throws IOException IO异常 @@ -58,7 +58,7 @@ public class BitSetBloomFilter implements BloomFilter{ IoUtil.close(reader); } } - + @Override public boolean add(String str) { if (contains(str)) { @@ -72,7 +72,7 @@ public class BitSetBloomFilter implements BloomFilter{ } return true; } - + /** * 判定是否包含指定字符串 * @param str 字符串 @@ -89,7 +89,7 @@ public class BitSetBloomFilter implements BloomFilter{ } return true; } - + /** * @return 得到当前过滤器的错误率. */ @@ -100,7 +100,7 @@ public class BitSetBloomFilter implements BloomFilter{ /** * 将字符串的字节表示进行多哈希编码. - * + * * @param str 待添加进过滤器的字符串字节表示. * @param hashNumber 要经过的哈希个数. * @return 各个哈希的结果数组. @@ -109,7 +109,7 @@ public class BitSetBloomFilter implements BloomFilter{ int[] result = new int[hashNumber]; for(int i = 0; i < hashNumber; i++) { result[i] = hash(str, i); - + } return result; } diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilter.java index 8a33af0b9..e7c9cc9fc 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilter.java @@ -12,7 +12,7 @@ import java.io.Serializable; public interface BloomFilter extends Serializable{ /** - * + * * @param str 字符串 * @return 判断一个字符串是否bitMap中存在 */ @@ -21,7 +21,7 @@ public interface BloomFilter extends Serializable{ /** * 在boolean的bitMap中增加一个字符串
* 如果存在就返回false .如果不存在.先增加这个字符串.再返回true - * + * * @param str 字符串 * @return 是否加入成功,如果存在就返回false .如果不存在返回true */ diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilterUtil.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilterUtil.java index 4e2cd7aca..6ba79067e 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilterUtil.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilterUtil.java @@ -2,7 +2,7 @@ package cn.hutool.bloomfilter; /** * 布隆过滤器工具 - * + * * @author looly * @since 4.1.5 */ @@ -10,7 +10,7 @@ public class BloomFilterUtil { /** * 创建一个BitSet实现的布隆过滤器,过滤器的容量为c * n 个bit. - * + * * @param c 当前过滤器预先开辟的最大包含记录,通常要比预计存入的记录多一倍. * @param n 当前过滤器预计所要包含的记录. * @param k 哈希函数的个数,等同每条记录要占用的bit数. @@ -22,7 +22,7 @@ public class BloomFilterUtil { /** * 创建BitMap实现的布隆过滤器 - * + * * @param m BitMap的大小 * @return BitMapBloomFilter */ diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/BitMap.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/BitMap.java index 0e8eecf4d..b877bf395 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/BitMap.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/BitMap.java @@ -2,7 +2,7 @@ package cn.hutool.bloomfilter.bitMap; /** * BitMap接口,用于将某个int或long值映射到一个数组中,从而判定某个值是否存在 - * + * * @author looly * */ @@ -13,14 +13,14 @@ public interface BitMap{ /** * 加入值 - * + * * @param i 值 */ void add(long i); /** * 检查是否包含值 - * + * * @param i 值 * @return 是否包含 */ @@ -28,7 +28,7 @@ public interface BitMap{ /** * 移除值 - * + * * @param i 值 */ void remove(long i); diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/IntMap.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/IntMap.java index 498129f8f..f941d0696 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/IntMap.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/IntMap.java @@ -4,7 +4,7 @@ import java.io.Serializable; /** * 过滤器BitMap在32位机器上.这个类能发生更好的效果.一般情况下建议使用此类 - * + * * @author loolly * */ @@ -22,7 +22,7 @@ public class IntMap implements BitMap, Serializable { /** * 构造 - * + * * @param size 容量 */ public IntMap(int size) { diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/LongMap.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/LongMap.java index 7ee584663..93f0d6d99 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/LongMap.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/LongMap.java @@ -4,7 +4,7 @@ import java.io.Serializable; /** * 过滤器BitMap在64位机器上.这个类能发生更好的效果.一般机器不建议使用 - * + * * @author loolly * */ @@ -22,7 +22,7 @@ public class LongMap implements BitMap, Serializable { /** * 构造 - * + * * @param size 容量 */ public LongMap(int size) { diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/package-info.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/package-info.java index bc24ee883..37d547426 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/package-info.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/package-info.java @@ -1,6 +1,6 @@ /** * BitMap实现 - * + * * @author looly * */ diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/AbstractFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/AbstractFilter.java index b1ac316e9..a19d55527 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/AbstractFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/AbstractFilter.java @@ -7,7 +7,7 @@ import cn.hutool.bloomfilter.bitMap.LongMap; /** * 抽象Bloom过滤器 - * + * * @author loolly * */ @@ -20,7 +20,7 @@ public abstract class AbstractFilter implements BloomFilter { /** * 构造 - * + * * @param maxValue 最大值 * @param machineNum 机器位数 */ @@ -30,7 +30,7 @@ public abstract class AbstractFilter implements BloomFilter { /** * 构造32位 - * + * * @param maxValue 最大值 */ public AbstractFilter(long maxValue) { @@ -39,7 +39,7 @@ public abstract class AbstractFilter implements BloomFilter { /** * 初始化 - * + * * @param maxValue 最大值 * @param machineNum 机器位数 */ @@ -75,7 +75,7 @@ public abstract class AbstractFilter implements BloomFilter { /** * 自定义Hash方法 - * + * * @param str 字符串 * @return HashCode */ diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/ELFFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/ELFFilter.java index 1b292db60..81c44a37f 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/ELFFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/ELFFilter.java @@ -8,11 +8,11 @@ public class ELFFilter extends AbstractFilter { public ELFFilter(long maxValue, int machineNumber) { super(maxValue, machineNumber); } - + public ELFFilter(long maxValue) { super(maxValue); } - + @Override public long hash(String str) { return HashUtil.elfHash(str) % size; diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfFilter.java index 79f95da48..fc2814149 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfFilter.java @@ -7,11 +7,11 @@ public class HfFilter extends AbstractFilter { public HfFilter(long maxValue, int machineNum) { super(maxValue, machineNum); } - + public HfFilter(long maxValue) { super(maxValue); } - + @Override public long hash(String str) { int length = str.length() ; diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/JSFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/JSFilter.java index 9bc5e7394..af9d5837f 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/JSFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/JSFilter.java @@ -19,11 +19,11 @@ public class JSFilter extends AbstractFilter { for (int i = 0; i < str.length(); i++) { hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2)); } - + if(hash<0) { hash*=-1 ; } - + return hash % size; } diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/package-info.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/package-info.java index 811eb3d2a..157177d8e 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/package-info.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/package-info.java @@ -1,6 +1,6 @@ /** * 各种Hash算法的过滤器实现 - * + * * @author looly * */ From efe95c5f7bf0f0d4d6d4e551477909371c76b06c Mon Sep 17 00:00:00 2001 From: cal101 Date: Sun, 14 Feb 2021 11:45:07 +0000 Subject: [PATCH 05/47] [cleanup] erefactor/EclipseJdt - Remove redundant super() call in constructor EclipseJdt cleanup 'RemoveUnnecessarySuperCall' applied by erefactor. For EclipseJdt see https://www.eclipse.org/eclipse/news/4.18/jdt.php For erefactor see https://github.com/cal101/erefactor --- .../src/main/java/cn/hutool/http/ssl/DefaultSSLFactory.java | 1 - .../src/test/java/cn/hutool/json/test/bean/ResultDto.java | 1 - .../java/cn/hutool/json/test/bean/report/EnvSettingInfo.java | 1 - .../src/main/java/cn/hutool/setting/dialect/Props.java | 1 - .../src/main/java/cn/hutool/setting/profile/Profile.java | 1 - 5 files changed, 5 deletions(-) diff --git a/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLFactory.java b/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLFactory.java index a2626c6aa..7f9d06b98 100644 --- a/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLFactory.java +++ b/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLFactory.java @@ -12,7 +12,6 @@ import java.security.NoSuchAlgorithmException; public class DefaultSSLFactory extends CustomProtocolsSSLFactory { public DefaultSSLFactory() throws KeyManagementException, NoSuchAlgorithmException { - super(); } } \ No newline at end of file diff --git a/hutool-json/src/test/java/cn/hutool/json/test/bean/ResultDto.java b/hutool-json/src/test/java/cn/hutool/json/test/bean/ResultDto.java index c6626fc94..277ffc6f0 100644 --- a/hutool-json/src/test/java/cn/hutool/json/test/bean/ResultDto.java +++ b/hutool-json/src/test/java/cn/hutool/json/test/bean/ResultDto.java @@ -75,7 +75,6 @@ public class ResultDto implements Serializable { * @param result the result */ public ResultDto(int code, String message, T result) { - super(); this.code(code).message(message).result(result); } diff --git a/hutool-json/src/test/java/cn/hutool/json/test/bean/report/EnvSettingInfo.java b/hutool-json/src/test/java/cn/hutool/json/test/bean/report/EnvSettingInfo.java index dfe790fe1..e7a2dd98a 100644 --- a/hutool-json/src/test/java/cn/hutool/json/test/bean/report/EnvSettingInfo.java +++ b/hutool-json/src/test/java/cn/hutool/json/test/bean/report/EnvSettingInfo.java @@ -66,7 +66,6 @@ public class EnvSettingInfo { private String sqlitePath; public EnvSettingInfo() { - super(); } public void setSqlitePath(String sqlitePath) { diff --git a/hutool-setting/src/main/java/cn/hutool/setting/dialect/Props.java b/hutool-setting/src/main/java/cn/hutool/setting/dialect/Props.java index 9541d1aba..4a15cfe7e 100644 --- a/hutool-setting/src/main/java/cn/hutool/setting/dialect/Props.java +++ b/hutool-setting/src/main/java/cn/hutool/setting/dialect/Props.java @@ -105,7 +105,6 @@ public final class Props extends Properties implements BasicTypeGetter, * 构造 */ public Props() { - super(); } /** diff --git a/hutool-setting/src/main/java/cn/hutool/setting/profile/Profile.java b/hutool-setting/src/main/java/cn/hutool/setting/profile/Profile.java index 6a0586745..c66c82b8f 100644 --- a/hutool-setting/src/main/java/cn/hutool/setting/profile/Profile.java +++ b/hutool-setting/src/main/java/cn/hutool/setting/profile/Profile.java @@ -63,7 +63,6 @@ public class Profile implements Serializable { * @param useVar 是否使用变量 */ public Profile(String profile, Charset charset, boolean useVar) { - super(); this.profile = profile; this.charset = charset; this.useVar = useVar; From 3bc5054a9a76966cb26dbeecf1ff0cf4cd7e2a76 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 19 Feb 2021 17:41:49 +0800 Subject: [PATCH 06/47] fix sm2 bugs --- CHANGELOG.md | 2 + .../java/cn/hutool/core/util/HexUtil.java | 8 ++-- .../main/java/cn/hutool/crypto/BCUtil.java | 19 ++++++++-- .../main/java/cn/hutool/crypto/ECKeyUtil.java | 5 ++- .../main/java/cn/hutool/crypto/SmUtil.java | 2 +- .../java/cn/hutool/crypto/asymmetric/SM2.java | 21 +++++++++++ .../crypto/test/asymmetric/SM2Test.java | 37 +++++++++++++++++-- 7 files changed, 82 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f1a63c30..f48d23439 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,11 +9,13 @@ * 【crypto 】 PemUtil.readPemKey支持EC(pr#1366@Github) * 【extra 】 Ftp等cd方法增加同步(issue#1397@Github) * 【core 】 StrUtil增加endWithAnyIgnoreCase(issue#I37I0B@Gitee) +* 【crypto 】 Sm2增加getD和getQ方法(issue#I37Z4C@Gitee) ### Bug修复 * 【json 】 JSONUtil.isJson方法改变trim策略,解决特殊空白符导致判断失败问题 * 【json 】 修复SQLEXception导致的栈溢出(issue#1399@Github) * 【extra 】 修复Ftp中异常参数没有传入问题(issue#1397@Github) +* 【crypto 】 修复Sm2使用D构造空指针问题(issue#I37Z4C@Gitee) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/util/HexUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/HexUtil.java index 5872918eb..cf59864ed 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/HexUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/HexUtil.java @@ -26,7 +26,7 @@ public class HexUtil { /** * 判断给定字符串是否为16进制数
- * 如果是,需要使用对应数字类型对象的decode方法解码
+ * 如果是,需要使用对应数字类型对象的{@code decode}方法解码
* 例如:{@code Integer.decode}方法解码int类型的16进制数字 * * @param value 值 @@ -74,7 +74,7 @@ public class HexUtil { * 将字节数组转换为十六进制字符数组 * * @param data byte[] - * @param toLowerCase true 传换成小写格式 , false 传换成大写格式 + * @param toLowerCase {@code true} 传换成小写格式 , {@code false} 传换成大写格式 * @return 十六进制char[] */ public static char[] encodeHex(byte[] data, boolean toLowerCase) { @@ -116,7 +116,7 @@ public class HexUtil { * 将字节数组转换为十六进制字符串 * * @param data byte[] - * @param toLowerCase true 传换成小写格式 , false 传换成大写格式 + * @param toLowerCase {@code true} 传换成小写格式 , {@code false} 传换成大写格式 * @return 十六进制String */ public static String encodeHexStr(byte[] data, boolean toLowerCase) { @@ -421,4 +421,4 @@ public class HexUtil { return digit; } // ---------------------------------------------------------------------------------------- Private method end -} \ No newline at end of file +} diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/BCUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/BCUtil.java index 412e0cca2..918b1086b 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/BCUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/BCUtil.java @@ -41,15 +41,28 @@ public class BCUtil { } /** - * 编码压缩EC公钥(基于BouncyCastle)
+ * 编码压缩EC公钥(基于BouncyCastle),即Q值
* 见:https://www.cnblogs.com/xinzhao/p/8963724.html * * @param publicKey {@link PublicKey},必须为org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey - * @return 压缩得到的X + * @return 压缩得到的Q * @since 4.4.4 */ public static byte[] encodeECPublicKey(PublicKey publicKey) { - return ((BCECPublicKey) publicKey).getQ().getEncoded(true); + return encodeECPublicKey(publicKey, true); + } + + /** + * 编码压缩EC公钥(基于BouncyCastle),即Q值
+ * 见:https://www.cnblogs.com/xinzhao/p/8963724.html + * + * @param publicKey {@link PublicKey},必须为org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey + * @param isCompressed 是否压缩 + * @return 得到的Q + * @since 5.5.9 + */ + public static byte[] encodeECPublicKey(PublicKey publicKey, boolean isCompressed) { + return ((BCECPublicKey) publicKey).getQ().getEncoded(isCompressed); } /** diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java index 30d5264c7..73b12a8c1 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java @@ -87,7 +87,7 @@ public class ECKeyUtil { * @param x 公钥X * @param y 公钥Y * @param domainParameters ECDomainParameters - * @return ECPublicKeyParameters + * @return ECPublicKeyParameters,x或y为{@code null}则返回{@code null} */ public static ECPublicKeyParameters toPublicParams(String x, String y, ECDomainParameters domainParameters) { return toPublicParams(SecureUtil.decode(x), SecureUtil.decode(y), domainParameters); @@ -102,6 +102,9 @@ public class ECKeyUtil { * @return ECPublicKeyParameters */ public static ECPublicKeyParameters toPublicParams(byte[] xBytes, byte[] yBytes, ECDomainParameters domainParameters) { + if(null == xBytes || null == yBytes){ + return null; + } return toPublicParams(BigIntegers.fromUnsignedByteArray(xBytes), BigIntegers.fromUnsignedByteArray(yBytes), domainParameters); } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java index e5a3b8cac..861768492 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java @@ -26,7 +26,7 @@ import java.math.BigInteger; /** * SM国密算法工具类
- * 此工具类依赖org.bouncycastle:bcpkix-jdk15on + * 此工具类依赖org.bouncycastle:bcprov-jdk15to18 * * @author looly * @since 4.3.2 diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java index 84b0f6e18..e22c9402c 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java @@ -471,6 +471,27 @@ public class SM2 extends AbstractAsymmetricCrypto { return this; } + /** + * 获得私钥D值(编码后的私钥) + * + * @return D值 + * @since 5.5.9 + */ + public byte[] getD() { + return this.privateKeyParams.getD().toByteArray(); + } + + /** + * 获得公钥Q值(编码后的公钥) + * + * @param isCompressed 是否压缩 + * @return Q值 + * @since 5.5.9 + */ + public byte[] getQ(boolean isCompressed) { + return this.publicKeyParams.getQ().getEncoded(isCompressed); + } + // ------------------------------------------------------------------------------------------------------------------------- Private method start /** diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java index 5d74d706f..0c4bfe152 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java @@ -1,7 +1,6 @@ package cn.hutool.crypto.test.asymmetric; import cn.hutool.core.codec.Base64; -import cn.hutool.core.lang.Console; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.HexUtil; import cn.hutool.core.util.StrUtil; @@ -31,7 +30,6 @@ public class SM2Test { @Test public void generateKeyPairTest() { KeyPair pair = SecureUtil.generateKeyPair("SM2"); - Console.log(HexUtil.encodeHexStr(pair.getPublic().getEncoded())); Assert.assertNotNull(pair.getPrivate()); Assert.assertNotNull(pair.getPublic()); } @@ -114,6 +112,36 @@ public class SM2Test { Assert.assertEquals(text.toString(), decryptStr2); } + @Test + public void sm2SignTest(){ + //需要签名的明文,得到明文对应的字节数组 + byte[] dataBytes = "我是一段测试aaaa".getBytes(); + + //指定的私钥 + String privateKeyHex = "1ebf8b341c695ee456fd1a41b82645724bc25d79935437d30e7e4b0a554baa5e"; + final SM2 sm2 = new SM2(privateKeyHex, null, null); + sm2.usePlainEncoding(); + byte[] sign = sm2.sign(dataBytes, null); + // 64位签名 + Assert.assertEquals(64, sign.length); + } + + @Test + public void sm2VerifyTest(){ + //指定的公钥 + String publicKeyHex = "04db9629dd33ba568e9507add5df6587a0998361a03d3321948b448c653c2c1b7056434884ab6f3d1c529501f166a336e86f045cea10dffe58aa82ea13d7253763"; + //需要加密的明文,得到明文对应的字节数组 + byte[] dataBytes = "我是一段测试aaaa".getBytes(); + //签名值 + String signHex = "2881346e038d2ed706ccdd025f2b1dafa7377d5cf090134b98756fafe084dddbcdba0ab00b5348ed48025195af3f1dda29e819bb66aa9d4d088050ff148482a1"; + + final SM2 sm2 = new SM2(null, ECKeyUtil.toSm2PublicParams(publicKeyHex)); + sm2.usePlainEncoding(); + + boolean verify = sm2.verify(dataBytes, HexUtil.decodeHex(signHex)); + Assert.assertTrue(verify); + } + @Test public void sm2SignAndVerifyTest() { String content = "我是Hanley."; @@ -207,8 +235,12 @@ public class SM2Test { // 生成的签名是64位 sm2.usePlainEncoding(); + String sign = "DCA0E80A7F46C93714B51C3EFC55A922BCEF7ECF0FE9E62B53BA6A7438B543A76C145A452CA9036F3CB70D7E6C67D4D9D7FE114E5367A2F6F5A4D39F2B10F3D6"; Assert.assertTrue(sm2.verifyHex(data, sign)); + + String sign2 = sm2.signHex(data, id); + Assert.assertTrue(sm2.verifyHex(data, sign2)); } @Test @@ -224,7 +256,6 @@ public class SM2Test { final SM2 sm2 = new SM2(ecPrivateKeyParameters, ecPublicKeyParameters); sm2.setMode(SM2Engine.Mode.C1C2C3); final String encryptHex = sm2.encryptHex(data, KeyType.PublicKey); - Console.log(encryptHex); final String decryptStr = sm2.decryptStr(encryptHex, KeyType.PrivateKey); Assert.assertEquals(data, decryptStr); From 1f8bac4afa98ed97c84354fdc8463b9f8ab03e0f Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 19 Feb 2021 17:50:55 +0800 Subject: [PATCH 07/47] fix #I38857 --- CHANGELOG.md | 1 + .../java/cn/hutool/poi/excel/ExcelPicUtil.java | 17 ++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f48d23439..d03a8ea2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ * 【json 】 修复SQLEXception导致的栈溢出(issue#1399@Github) * 【extra 】 修复Ftp中异常参数没有传入问题(issue#1397@Github) * 【crypto 】 修复Sm2使用D构造空指针问题(issue#I37Z4C@Gitee) +* 【poi 】 修复ExcelPicUtil中图表报错问题(issue#I38857@Gitee) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelPicUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelPicUtil.java index 2bbbc5b4f..4d4eeb8ee 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelPicUtil.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelPicUtil.java @@ -25,14 +25,14 @@ import java.util.Map; /** * Excel图片工具类 - * + * * @author looly * @since 4.0.7 */ public class ExcelPicUtil { /** * 获取工作簿指定sheet中图片列表 - * + * * @param workbook 工作簿{@link Workbook} * @param sheetIndex sheet的索引 * @return 图片映射,键格式:行_列,值:{@link PictureData} @@ -55,7 +55,7 @@ public class ExcelPicUtil { // -------------------------------------------------------------------------------------------------------------- Private method start /** * 获取XLS工作簿指定sheet中图片列表 - * + * * @param workbook 工作簿{@link Workbook} * @param sheetIndex sheet的索引 * @return 图片映射,键格式:行_列,值:{@link PictureData} @@ -80,7 +80,7 @@ public class ExcelPicUtil { /** * 获取XLSX工作簿指定sheet中图片列表 - * + * * @param workbook 工作簿{@link Workbook} * @param sheetIndex sheet的索引 * @return 图片映射,键格式:行_列,值:{@link PictureData} @@ -96,9 +96,12 @@ public class ExcelPicUtil { XSSFPicture pic; CTMarker ctMarker; for (XSSFShape shape : shapes) { - pic = (XSSFPicture) shape; - ctMarker = pic.getPreferredSize().getFrom(); - sheetIndexPicMap.put(StrUtil.format("{}_{}", ctMarker.getRow(), ctMarker.getCol()), pic.getPictureData()); + if(shape instanceof XSSFPicture){ + pic = (XSSFPicture) shape; + ctMarker = pic.getPreferredSize().getFrom(); + sheetIndexPicMap.put(StrUtil.format("{}_{}", ctMarker.getRow(), ctMarker.getCol()), pic.getPictureData()); + } + // 其他类似于图表等忽略,see: https://gitee.com/loolly/hutool/issues/I38857 } } } From 7cee14373aaf14068c454fb432758b297017ebbf Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 19 Feb 2021 17:51:46 +0800 Subject: [PATCH 08/47] fix doc --- .../src/main/java/cn/hutool/core/collection/CollUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java index 2eea2a33a..9c8819f22 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java @@ -2780,11 +2780,11 @@ public class CollUtil { } /** - * 取最大值 + * 取最小值 * * @param 元素类型 * @param coll 集合 - * @return 最大值 + * @return 最小值 * @see Collections#min(Collection) * @since 4.6.5 */ From 7527f812cdd5804642d76d9821d3b2a6f29badf7 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 20 Feb 2021 09:52:17 +0800 Subject: [PATCH 09/47] add method --- CHANGELOG.md | 3 ++- .../main/java/cn/hutool/cache/impl/AbstractCache.java | 11 +++++++++++ .../src/main/java/cn/hutool/cache/impl/LRUCache.java | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d03a8ea2e..b332bdba5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,14 @@ ------------------------------------------------------------------------------------------------------------- -# 5.5.9 (2021-02-18) +# 5.5.9 (2021-02-20) ### 新特性 * 【crypto 】 PemUtil.readPemKey支持EC(pr#1366@Github) * 【extra 】 Ftp等cd方法增加同步(issue#1397@Github) * 【core 】 StrUtil增加endWithAnyIgnoreCase(issue#I37I0B@Gitee) * 【crypto 】 Sm2增加getD和getQ方法(issue#I37Z4C@Gitee) +* 【cache 】 AbstractCache增加keySet方法(issue#I37Z4C@Gitee) ### Bug修复 * 【json 】 JSONUtil.isJson方法改变trim策略,解决特殊空白符导致判断失败问题 diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java index f1c3ba7bf..ea40ed11d 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java @@ -7,6 +7,7 @@ import cn.hutool.core.lang.func.Func0; import java.util.Iterator; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Lock; @@ -312,6 +313,16 @@ public abstract class AbstractCache implements Cache { return this; } + /** + * 返回所有键 + * + * @return 所有键 + * @since 5.5.9 + */ + public Set keySet(){ + return this.cacheMap.keySet(); + } + /** * 对象移除回调。默认无动作
* 子类可重写此方法用于监听移除事件,如果重写,listener将无效 diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/LRUCache.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/LRUCache.java index ed003b721..b385b57fe 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/LRUCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/LRUCache.java @@ -48,7 +48,7 @@ public class LRUCache extends AbstractCache { // ---------------------------------------------------------------- prune /** - * 只清理超时对象,LRU的实现会交给LinkedHashMap + * 只清理超时对象,LRU的实现会交给{@code LinkedHashMap} */ @Override protected int pruneCache() { From 90e77eeff16d1c3ecf75f2308f076e5a447436a6 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 20 Feb 2021 10:02:59 +0800 Subject: [PATCH 10/47] fix comment --- .../main/java/cn/hutool/cron/Scheduler.java | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java b/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java index a44f23cc2..4673a585f 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java @@ -25,30 +25,30 @@ import java.util.concurrent.locks.ReentrantLock; /** * 任务调度器
- * + * * 调度器启动流程:
- * + * *
  * 启动Timer =》 启动TaskLauncher =》 启动TaskExecutor
  * 
- * + * * 调度器关闭流程:
- * + * *
  * 关闭Timer =》 关闭所有运行中的TaskLauncher =》 关闭所有运行中的TaskExecutor
  * 
- * + * * 其中: - * + * *
- * TaskLauncher:定时器每分钟调用一次(如果{@link Scheduler#isMatchSecond()}为true每秒调用一次),
+ * TaskLauncher:定时器每分钟调用一次(如果{@link Scheduler#isMatchSecond()}为{@code true}每秒调用一次),
  * 负责检查TaskTable是否有匹配到此时间运行的Task
  * 
- * + * *
  * TaskExecutor:TaskLauncher匹配成功后,触发TaskExecutor执行具体的作业,执行完毕销毁
  * 
- * + * * @author Looly * */ @@ -80,7 +80,7 @@ public class Scheduler implements Serializable { // --------------------------------------------------------- Getters and Setters start /** * 设置时区 - * + * * @param timeZone 时区 * @return this */ @@ -91,7 +91,7 @@ public class Scheduler implements Serializable { /** * 获得时区,默认为 {@link TimeZone#getDefault()} - * + * * @return 时区 */ public TimeZone getTimeZone() { @@ -101,8 +101,8 @@ public class Scheduler implements Serializable { /** * 设置是否为守护线程
* 如果为true,则在调用{@link #stop()}方法后执行的定时任务立即结束,否则等待执行完毕才结束。默认非守护线程 - * - * @param on true为守护线程,否则非守护线程 + * + * @param on {@code true}为守护线程,否则非守护线程 * @return this * @throws CronException 定时任务已经启动抛出此异常 */ @@ -121,7 +121,7 @@ public class Scheduler implements Serializable { /** * 是否为守护线程 - * + * * @return 是否为守护线程 */ public boolean isDaemon() { @@ -130,8 +130,8 @@ public class Scheduler implements Serializable { /** * 是否支持秒匹配 - * - * @return true使用,false不使用 + * + * @return {@code true}使用,{@code false}不使用 */ public boolean isMatchSecond() { return this.config.isMatchSecond(); @@ -139,8 +139,8 @@ public class Scheduler implements Serializable { /** * 设置是否支持秒匹配,默认不使用 - * - * @param isMatchSecond true支持,false不支持 + * + * @param isMatchSecond {@code true}支持,{@code false}不支持 * @return this */ public Scheduler setMatchSecond(boolean isMatchSecond) { @@ -150,7 +150,7 @@ public class Scheduler implements Serializable { /** * 增加监听器 - * + * * @param listener {@link TaskListener} * @return this */ @@ -161,7 +161,7 @@ public class Scheduler implements Serializable { /** * 移除监听器 - * + * * @param listener {@link TaskListener} * @return this */ @@ -175,7 +175,7 @@ public class Scheduler implements Serializable { /** * 批量加入配置文件中的定时任务
* 配置文件格式为: xxx.xxx.xxx.Class.method = * * * * * - * + * * @param cronSetting 定时任务设置文件 * @return this */ @@ -204,7 +204,7 @@ public class Scheduler implements Serializable { /** * 新增Task,使用随机UUID - * + * * @param pattern {@link CronPattern}对应的String表达式 * @param task {@link Runnable} * @return ID @@ -215,7 +215,7 @@ public class Scheduler implements Serializable { /** * 新增Task,使用随机UUID - * + * * @param pattern {@link CronPattern}对应的String表达式 * @param task {@link Task} * @return ID @@ -228,7 +228,7 @@ public class Scheduler implements Serializable { /** * 新增Task,如果任务ID已经存在,抛出异常 - * + * * @param id ID,为每一个Task定义一个ID * @param pattern {@link CronPattern}对应的String表达式 * @param task {@link Runnable} @@ -240,7 +240,7 @@ public class Scheduler implements Serializable { /** * 新增Task,如果任务ID已经存在,抛出异常 - * + * * @param id ID,为每一个Task定义一个ID * @param pattern {@link CronPattern}对应的String表达式 * @param task {@link Task} @@ -252,7 +252,7 @@ public class Scheduler implements Serializable { /** * 新增Task,如果任务ID已经存在,抛出异常 - * + * * @param id ID,为每一个Task定义一个ID * @param pattern {@link CronPattern} * @param task {@link Task} @@ -265,7 +265,7 @@ public class Scheduler implements Serializable { /** * 移除Task - * + * * @param id Task的ID * @return this */ @@ -276,7 +276,7 @@ public class Scheduler implements Serializable { /** * 更新Task执行的时间规则 - * + * * @param id Task的ID * @param pattern {@link CronPattern} * @return this @@ -299,7 +299,7 @@ public class Scheduler implements Serializable { /** * 获得指定id的{@link CronPattern} - * + * * @param id ID * @return {@link CronPattern} * @since 3.1.1 @@ -310,7 +310,7 @@ public class Scheduler implements Serializable { /** * 获得指定id的{@link Task} - * + * * @param id ID * @return {@link Task} * @since 3.1.1 @@ -321,7 +321,7 @@ public class Scheduler implements Serializable { /** * 是否无任务 - * + * * @return true表示无任务 * @since 4.0.2 */ @@ -331,14 +331,14 @@ public class Scheduler implements Serializable { /** * 当前任务数 - * + * * @return 当前任务数 * @since 4.0.2 */ public int size() { return this.taskTable.size(); } - + /** * 清空任务表 * @return this @@ -359,7 +359,7 @@ public class Scheduler implements Serializable { /** * 启动 - * + * * @param isDaemon 是否以守护线程方式启动,如果为true,则在调用{@link #stop()}方法后执行的定时任务立即结束,否则等待执行完毕才结束。 * @return this */ @@ -370,7 +370,7 @@ public class Scheduler implements Serializable { /** * 启动 - * + * * @return this */ public Scheduler start() { @@ -380,7 +380,7 @@ public class Scheduler implements Serializable { throw new CronException("Schedule is started!"); } - // 无界线程池,确保每一个需要执行的线程都可以及时运行,同时复用已有现成避免线程重复创建 + // 无界线程池,确保每一个需要执行的线程都可以及时运行,同时复用已有线程避免线程重复创建 this.threadExecutor = ExecutorBuilder.create().useSynchronousQueue().setThreadFactory(// ThreadFactoryBuilder.create().setNamePrefix("hutool-cron-").setDaemon(this.daemon).build()// ).build(); @@ -397,12 +397,12 @@ public class Scheduler implements Serializable { } return this; } - + /** * 停止定时任务
* 此方法调用后会将定时器进程立即结束,如果为守护线程模式,则正在执行的作业也会自动结束,否则作业线程将在执行完成后结束。
* 此方法并不会清除任务表中的任务,请调用{@link #clear()} 方法清空任务或者使用{@link #stop(boolean)}方法可选是否清空 - * + * * @return this */ public Scheduler stop() { @@ -427,11 +427,11 @@ public class Scheduler implements Serializable { // 停止CronTimer this.timer.stopTimer(); this.timer = null; - + //停止线程池 this.threadExecutor.shutdown(); this.threadExecutor = null; - + //可选是否清空任务表 if(clearTasks) { clear(); From ef3e3f55b52f364a45edd9f8807ab90e8931ca1d Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 20 Feb 2021 10:35:01 +0800 Subject: [PATCH 11/47] add formatSimple --- CHANGELOG.md | 1 + .../java/cn/hutool/core/convert/Convert.java | 209 +++++----- .../core/convert/NumberWordFormatter.java | 362 +++++++++--------- .../core/convert/NumberWordFormatTest.java | 59 +-- 4 files changed, 329 insertions(+), 302 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b332bdba5..24a1efd63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * 【core 】 StrUtil增加endWithAnyIgnoreCase(issue#I37I0B@Gitee) * 【crypto 】 Sm2增加getD和getQ方法(issue#I37Z4C@Gitee) * 【cache 】 AbstractCache增加keySet方法(issue#I37Z4C@Gitee) +* 【core 】 NumberWordFormatter增加formatSimple方法(pr#1436@Github) ### Bug修复 * 【json 】 JSONUtil.isJson方法改变trim策略,解决特殊空白符导致判断失败问题 diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java index dc1324284..2e2377f32 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java @@ -28,9 +28,9 @@ import java.util.concurrent.TimeUnit; /** * 类型转换器 - * + * * @author xiaoleilu - * + * */ public class Convert { @@ -38,7 +38,7 @@ public class Convert { * 转换为字符串
* 如果给定的值为null,或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -51,17 +51,17 @@ public class Convert { * 转换为字符串
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ public static String toStr(Object value) { return toStr(value, null); } - + /** * 转换为String数组 - * + * * @param value 被转换的值 * @return String数组 * @since 3.2.0 @@ -74,7 +74,7 @@ public class Convert { * 转换为字符
* 如果给定的值为null,或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -87,17 +87,17 @@ public class Convert { * 转换为字符
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ public static Character toChar(Object value) { return toChar(value, null); } - + /** * 转换为Character数组 - * + * * @param value 被转换的值 * @return Character数组 * @since 3.2.0 @@ -110,7 +110,7 @@ public class Convert { * 转换为byte
* 如果给定的值为{@code null},或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -123,17 +123,17 @@ public class Convert { * 转换为byte
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ public static Byte toByte(Object value) { return toByte(value, null); } - + /** * 转换为Byte数组 - * + * * @param value 被转换的值 * @return Byte数组 * @since 3.2.0 @@ -157,7 +157,7 @@ public class Convert { * 转换为Short
* 如果给定的值为{@code null},或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -170,17 +170,17 @@ public class Convert { * 转换为Short
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ public static Short toShort(Object value) { return toShort(value, null); } - + /** * 转换为Short数组 - * + * * @param value 被转换的值 * @return Short数组 * @since 3.2.0 @@ -193,7 +193,7 @@ public class Convert { * 转换为Number
* 如果给定的值为空,或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -206,17 +206,17 @@ public class Convert { * 转换为Number
* 如果给定的值为空,或者转换失败,返回默认值{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ public static Number toNumber(Object value) { return toNumber(value, null); } - + /** * 转换为Number数组 - * + * * @param value 被转换的值 * @return Number数组 * @since 3.2.0 @@ -229,7 +229,7 @@ public class Convert { * 转换为int
* 如果给定的值为空,或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -242,7 +242,7 @@ public class Convert { * 转换为int
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ @@ -264,7 +264,7 @@ public class Convert { * 转换为long
* 如果给定的值为空,或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -277,7 +277,7 @@ public class Convert { * 转换为long
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ @@ -287,7 +287,7 @@ public class Convert { /** * 转换为Long数组
- * + * * @param value 被转换的值 * @return 结果 */ @@ -299,7 +299,7 @@ public class Convert { * 转换为double
* 如果给定的值为空,或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -312,7 +312,7 @@ public class Convert { * 转换为double
* 如果给定的值为空,或者转换失败,返回默认值{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ @@ -322,7 +322,7 @@ public class Convert { /** * 转换为Double数组
- * + * * @param value 被转换的值 * @return 结果 */ @@ -334,7 +334,7 @@ public class Convert { * 转换为Float
* 如果给定的值为空,或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -347,7 +347,7 @@ public class Convert { * 转换为Float
* 如果给定的值为空,或者转换失败,返回默认值{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ @@ -357,7 +357,7 @@ public class Convert { /** * 转换为Float数组
- * + * * @param value 被转换的值 * @return 结果 */ @@ -369,7 +369,7 @@ public class Convert { * 转换为boolean
* String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -382,7 +382,7 @@ public class Convert { * 转换为boolean
* 如果给定的值为空,或者转换失败,返回默认值{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ @@ -392,7 +392,7 @@ public class Convert { /** * 转换为Boolean数组
- * + * * @param value 被转换的值 * @return 结果 */ @@ -404,7 +404,7 @@ public class Convert { * 转换为BigInteger
* 如果给定的值为空,或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -417,7 +417,7 @@ public class Convert { * 转换为BigInteger
* 如果给定的值为空,或者转换失败,返回默认值{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ @@ -429,7 +429,7 @@ public class Convert { * 转换为BigDecimal
* 如果给定的值为空,或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -442,19 +442,19 @@ public class Convert { * 转换为BigDecimal
* 如果给定的值为空,或者转换失败,返回null
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 */ public static BigDecimal toBigDecimal(Object value) { return toBigDecimal(value, null); } - + /** * 转换为Date
* 如果给定的值为空,或者转换失败,返回默认值
* 转换失败不会报错 - * + * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 @@ -489,7 +489,7 @@ public class Convert { public static LocalDateTime toLocalDateTime(Object value) { return toLocalDateTime(value, null); } - + /** * Instant
* 如果给定的值为空,或者转换失败,返回默认值
@@ -508,7 +508,7 @@ public class Convert { * 转换为Date
* 如果给定的值为空,或者转换失败,返回{@code null}
* 转换失败不会报错 - * + * * @param value 被转换的值 * @return 结果 * @since 4.1.6 @@ -516,11 +516,11 @@ public class Convert { public static Date toDate(Object value) { return toDate(value, null); } - + /** * 转换为Enum对象
* 如果给定的值为空,或者转换失败,返回默认值
- * + * * @param 枚举类型 * @param clazz Enum的Class * @param value 值 @@ -535,7 +535,7 @@ public class Convert { /** * 转换为Enum对象
* 如果给定的值为空,或者转换失败,返回默认值{@code null}
- * + * * @param 枚举类型 * @param clazz Enum的Class * @param value 值 @@ -547,7 +547,7 @@ public class Convert { /** * 转换为集合类 - * + * * @param collectionType 集合类型 * @param elementType 集合中元素类型 * @param value 被转换的值 @@ -557,10 +557,10 @@ public class Convert { public static Collection toCollection(Class collectionType, Class elementType, Object value) { return new CollectionConverter(collectionType, elementType).convert(value, null); } - + /** * 转换为ArrayList,元素类型默认Object - * + * * @param value 被转换的值 * @return {@link List} * @since 4.1.11 @@ -568,10 +568,10 @@ public class Convert { public static List toList(Object value) { return convert(List.class, value); } - + /** * 转换为ArrayList - * + * * @param 元素类型 * @param elementType 集合中元素类型 * @param value 被转换的值 @@ -598,10 +598,10 @@ public class Convert { public static Map toMap(Class keyType, Class valueType, Object value) { return (Map) new MapConverter(HashMap.class, keyType, valueType).convert(value, null); } - + /** * 转换值为指定类型,类型采用字符串表示 - * + * * @param 目标类型 * @param className 类的字符串表示 * @param value 值 @@ -612,10 +612,10 @@ public class Convert { public static T convertByClassName(String className, Object value) throws ConvertException{ return convert(ClassUtil.loadClass(className), value); } - + /** * 转换值为指定类型 - * + * * @param 目标类型 * @param type 类型 * @param value 值 @@ -626,10 +626,10 @@ public class Convert { public static T convert(Class type, Object value) throws ConvertException{ return convert((Type)type, value); } - + /** * 转换值为指定类型 - * + * * @param 目标类型 * @param reference 类型参考,用于持有转换后的泛型类型 * @param value 值 @@ -642,7 +642,7 @@ public class Convert { /** * 转换值为指定类型 - * + * * @param 目标类型 * @param type 类型 * @param value 值 @@ -652,10 +652,10 @@ public class Convert { public static T convert(Type type, Object value) throws ConvertException{ return convert(type, value, null); } - + /** * 转换值为指定类型 - * + * * @param 目标类型 * @param type 类型 * @param value 值 @@ -667,10 +667,10 @@ public class Convert { public static T convert(Class type, Object value, T defaultValue) throws ConvertException { return convert((Type)type, value, defaultValue); } - + /** * 转换值为指定类型 - * + * * @param 目标类型 * @param type 类型 * @param value 值 @@ -681,11 +681,11 @@ public class Convert { public static T convert(Type type, Object value, T defaultValue) throws ConvertException { return convertWithCheck(type, value, defaultValue, false); } - + /** * 转换值为指定类型,不抛异常转换
* 当转换失败时返回{@code null} - * + * * @param 目标类型 * @param type 目标类型 * @param value 值 @@ -695,11 +695,11 @@ public class Convert { public static T convertQuietly(Type type, Object value) { return convertQuietly(type, value, null); } - + /** * 转换值为指定类型,不抛异常转换
* 当转换失败时返回默认值 - * + * * @param 目标类型 * @param type 目标类型 * @param value 值 @@ -734,11 +734,11 @@ public class Convert { throw e; } } - + // ----------------------------------------------------------------------- 全角半角转换 /** * 半角转全角 - * + * * @param input String. * @return 全角字符串. */ @@ -748,7 +748,7 @@ public class Convert { /** * 半角转全角 - * + * * @param input String * @param notConvertSet 不替换的字符集合 * @return 全角字符串. @@ -773,7 +773,7 @@ public class Convert { /** * 全角转半角 - * + * * @param input String. * @return 半角字符串 */ @@ -783,7 +783,7 @@ public class Convert { /** * 替换全角为半角 - * + * * @param text 文本 * @param notConvertSet 不替换的字符集合 * @return 替换后的字符 @@ -813,7 +813,7 @@ public class Convert { // --------------------------------------------------------------------- hex /** * 字符串转换成十六进制字符串,结果为小写 - * + * * @param str 待转换的ASCII字符串 * @param charset 编码 * @return 16进制字符串 @@ -825,7 +825,7 @@ public class Convert { /** * byte数组转16进制串 - * + * * @param bytes 被转换的byte数组 * @return 转换后的值 * @see HexUtil#encodeHexStr(byte[]) @@ -836,7 +836,7 @@ public class Convert { /** * Hex字符串转换为Byte值 - * + * * @param src Byte字符串,每个Byte之间没有分隔符 * @return byte[] * @see HexUtil#decodeHex(char[]) @@ -847,7 +847,7 @@ public class Convert { /** * 十六进制转换字符串 - * + * * @param hexStr Byte字符串(Byte之间无分隔符 如:[616C6B]) * @param charset 编码 {@link Charset} * @return 对应的字符串 @@ -858,10 +858,10 @@ public class Convert { public static String hexStrToStr(String hexStr, Charset charset) { return hexToStr(hexStr, charset); } - + /** * 十六进制转换字符串 - * + * * @param hexStr Byte字符串(Byte之间无分隔符 如:[616C6B]) * @param charset 编码 {@link Charset} * @return 对应的字符串 @@ -874,7 +874,7 @@ public class Convert { /** * String的字符串转换成unicode的String - * + * * @param strText 全角字符串 * @return String 每个unicode之间无分隔符 * @see UnicodeUtil#toUnicode(String) @@ -885,7 +885,7 @@ public class Convert { /** * unicode的String转换成String的字符串 - * + * * @param unicode Unicode符 * @return String 字符串 * @see UnicodeUtil#toString(String) @@ -897,7 +897,7 @@ public class Convert { /** * 给定字符串转换字符编码
* 如果参数为空,则返回原字符串,不报错。 - * + * * @param str 被转码的字符串 * @param sourceCharset 原字符集 * @param destCharset 目标字符集 @@ -914,7 +914,7 @@ public class Convert { /** * 转换时间单位 - * + * * @param sourceDuration 时长 * @param sourceUnit 源单位 * @param destUnit 目标单位 @@ -929,7 +929,7 @@ public class Convert { // --------------------------------------------------------------- 原始包装类型转换 /** * 原始类转为包装类,非原始类返回原类 - * + * * @see BasicType#wrap(Class) * @param clazz 原始类 * @return 包装类 @@ -941,7 +941,7 @@ public class Convert { /** * 包装类转为原始类,非包装类返回原类 - * + * * @see BasicType#unWrap(Class) * @param clazz 包装类 * @return 原始类 @@ -954,7 +954,7 @@ public class Convert { // -------------------------------------------------------------------------- 数字和英文转换 /** * 将阿拉伯数字转为英文表达方式 - * + * * @param number {@link Number}对象 * @return 英文表达式 * @since 3.0.9 @@ -962,10 +962,25 @@ public class Convert { public static String numberToWord(Number number) { return NumberWordFormatter.format(number); } - + + /** + * 将阿拉伯数字转为精简表示形式,例如: + * + *
+	 *     1200 -> 1.2k
+	 * 
+ * + * @param number {@link Number}对象 + * @return 英文表达式 + * @since 5.5.9 + */ + public static String numberToSimple(Number number) { + return NumberWordFormatter.formatSimple(number.longValue()); + } + /** * 将阿拉伯数字转为中文表达方式 - * + * * @param number 数字 * @param isUseTraditonal 是否使用繁体字(金额形式) * @return 中文 @@ -974,10 +989,10 @@ public class Convert { public static String numberToChinese(double number, boolean isUseTraditonal) { return NumberChineseFormatter.format(number, isUseTraditonal); } - + /** * 金额转为中文形式 - * + * * @param n 数字 * @return 中文大写数字 * @since 3.2.3 @@ -988,11 +1003,11 @@ public class Convert { } return NumberChineseFormatter.format(n.doubleValue(), true, true); } - + // -------------------------------------------------------------------------- 数字转换 /** * int转byte - * + * * @param intValue int值 * @return byte值 * @since 3.2.0 @@ -1003,7 +1018,7 @@ public class Convert { /** * byte转无符号int - * + * * @param byteValue byte值 * @return 无符号int值 * @since 3.2.0 @@ -1015,7 +1030,7 @@ public class Convert { /** * byte数组转short - * + * * @param bytes byte数组 * @return short值 * @since 3.2.0 @@ -1039,7 +1054,7 @@ public class Convert { /** * byte[]转int值 - * + * * @param bytes byte数组 * @return int值 * @since 3.2.0 @@ -1053,7 +1068,7 @@ public class Convert { /** * int转byte数组 - * + * * @param intValue int值 * @return byte数组 * @since 3.2.0 @@ -1070,7 +1085,7 @@ public class Convert { /** * long转byte数组
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java - * + * * @param longValue long值 * @return byte数组 * @since 3.2.0 @@ -1088,7 +1103,7 @@ public class Convert { /** * byte数组转long
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java - * + * * @param bytes byte数组 * @return long值 * @since 3.2.0 diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java b/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java index 865bc3f93..3304a32ff 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java @@ -1,180 +1,182 @@ -package cn.hutool.core.convert; - -import cn.hutool.core.util.StrUtil; - -import java.text.DecimalFormat; - -/** - * 将浮点数类型的number转换成英语的表达方式
- * 参考博客:http://blog.csdn.net/eric_sunah/article/details/8713226 - * - * @author Looly - * @since 3.0.9 - */ -public class NumberWordFormatter { - - private static final String[] NUMBER = new String[]{"", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", - "EIGHT", "NINE"}; - private static final String[] NUMBER_TEEN = new String[]{"TEN", "ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN", - "FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"}; - private static final String[] NUMBER_TEN = new String[]{"TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", - "SEVENTY", "EIGHTY", "NINETY"}; - private static final String[] NUMBER_MORE = new String[]{"", "THOUSAND", "MILLION", "BILLION"}; - - private static final String[] NUMBER_SUFFIX = new String[]{"k", "w", "", "m", "", "", "b", "", "", "t", "", "", "p", "", "", "e"}; - - /** - * 将阿拉伯数字转为英文表达式 - * - * @param x 阿拉伯数字,可以为{@link Number}对象,也可以是普通对象,最后会使用字符串方式处理 - * @return 英文表达式 - */ - public static String format(Object x) { - if (x != null) { - return format(x.toString()); - } else { - return ""; - } - } - - /** - * 将阿拉伯数字转化为简介计数单位,例如 2100 => 2.1k - * 范围默认只到w - * @param value - * @return - */ - public static String formatValue(long value) { - return formatValue(value, true); - } - - /** - * 将阿拉伯数字转化为简介计数单位,例如 2100 => 2.1k - * @param value 对应数字的值 - * @param isTwo 控制是否为k、w - * @return - */ - public static String formatValue(long value, boolean isTwo) { - if (value < 1000) { - return String.valueOf(value); - } - int index = -1; - double res = value * 1.0d; - while (res > 10 && (!isTwo || index < 1)) { - if (res > 1000) { - res = res / 1000; - index++; - } - if (res > 10) { - res = res / 10; - index++; - } - } - DecimalFormat decimalFormat = new DecimalFormat("#.##"); - return String.format("%s%s", decimalFormat.format(res), NUMBER_SUFFIX[index]); - } - - /** - * 将阿拉伯数字转为英文表达式 - * - * @param x 阿拉伯数字字符串 - * @return 英文表达式 - */ - private static String format(String x) { - int z = x.indexOf("."); // 取小数点位置 - String lstr, rstr = ""; - if (z > -1) { // 看是否有小数,如果有,则分别取左边和右边 - lstr = x.substring(0, z); - rstr = x.substring(z + 1); - } else { - // 否则就是全部 - lstr = x; - } - - String lstrrev = StrUtil.reverse(lstr); // 对左边的字串取反 - String[] a = new String[5]; // 定义5个字串变量来存放解析出来的叁位一组的字串 - - switch (lstrrev.length() % 3) { - case 1: - lstrrev += "00"; - break; - case 2: - lstrrev += "0"; - break; - } - StringBuilder lm = new StringBuilder(); // 用来存放转换后的整数部分 - for (int i = 0; i < lstrrev.length() / 3; i++) { - a[i] = StrUtil.reverse(lstrrev.substring(3 * i, 3 * i + 3)); // 截取第一个三位 - if (false == "000".equals(a[i])) { // 用来避免这种情况:1000000 = one million - // thousand only - if (i != 0) { - lm.insert(0, transThree(a[i]) + " " + parseMore(i) + " "); // 加: - // thousand、million、billion - } else { - // 防止i=0时, 在多加两个空格. - lm = new StringBuilder(transThree(a[i])); - } - } else { - lm.append(transThree(a[i])); - } - } - - String xs = ""; // 用来存放转换后小数部分 - if (z > -1) { - xs = "AND CENTS " + transTwo(rstr) + " "; // 小数部分存在时转换小数 - } - - return lm.toString().trim() + " " + xs + "ONLY"; - } - - private static String parseFirst(String s) { - return NUMBER[Integer.parseInt(s.substring(s.length() - 1))]; - } - - private static String parseTeen(String s) { - return NUMBER_TEEN[Integer.parseInt(s) - 10]; - } - - private static String parseTen(String s) { - return NUMBER_TEN[Integer.parseInt(s.substring(0, 1)) - 1]; - } - - private static String parseMore(int i) { - return NUMBER_MORE[i]; - } - - // 两位 - private static String transTwo(String s) { - String value; - // 判断位数 - if (s.length() > 2) { - s = s.substring(0, 2); - } else if (s.length() < 2) { - s = "0" + s; - } - - if (s.startsWith("0")) {// 07 - seven 是否小於10 - value = parseFirst(s); - } else if (s.startsWith("1")) {// 17 seventeen 是否在10和20之间 - value = parseTeen(s); - } else if (s.endsWith("0")) {// 是否在10与100之间的能被10整除的数 - value = parseTen(s); - } else { - value = parseTen(s) + " " + parseFirst(s); - } - return value; - } - - // 制作叁位的数 - // s.length = 3 - private static String transThree(String s) { - String value; - if (s.startsWith("0")) {// 是否小於100 - value = transTwo(s.substring(1)); - } else if ("00".equals(s.substring(1))) {// 是否被100整除 - value = parseFirst(s.substring(0, 1)) + " HUNDRED"; - } else { - value = parseFirst(s.substring(0, 1)) + " HUNDRED AND " + transTwo(s.substring(1)); - } - return value; - } -} \ No newline at end of file +package cn.hutool.core.convert; + +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; + +/** + * 将浮点数类型的number转换成英语的表达方式
+ * 参考博客:http://blog.csdn.net/eric_sunah/article/details/8713226 + * + * @author Looly,totalo + * @since 3.0.9 + */ +public class NumberWordFormatter { + + private static final String[] NUMBER = new String[]{"", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", + "EIGHT", "NINE"}; + private static final String[] NUMBER_TEEN = new String[]{"TEN", "ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN", + "FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"}; + private static final String[] NUMBER_TEN = new String[]{"TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", + "SEVENTY", "EIGHTY", "NINETY"}; + private static final String[] NUMBER_MORE = new String[]{"", "THOUSAND", "MILLION", "BILLION"}; + + private static final String[] NUMBER_SUFFIX = new String[]{"k", "w", "", "m", "", "", "b", "", "", "t", "", "", "p", "", "", "e"}; + + /** + * 将阿拉伯数字转为英文表达式 + * + * @param x 阿拉伯数字,可以为{@link Number}对象,也可以是普通对象,最后会使用字符串方式处理 + * @return 英文表达式 + */ + public static String format(Object x) { + if (x != null) { + return format(x.toString()); + } else { + return StrUtil.EMPTY; + } + } + + /** + * 将阿拉伯数字转化为简洁计数单位,例如 2100 => 2.1k + * 范围默认只到w + * + * @param value 被格式化的数字 + * @return 格式化后的数字 + * @since 5.5.9 + */ + public static String formatSimple(long value) { + return formatSimple(value, true); + } + + /** + * 将阿拉伯数字转化为简介计数单位,例如 2100 => 2.1k + * + * @param value 对应数字的值 + * @param isTwo 控制是否为只为k、w,例如当为{@code false}时返回4.38m,{@code true}返回438.43w + * @return 格式化后的数字 + * @since 5.5.9 + */ + public static String formatSimple(long value, boolean isTwo) { + if (value < 1000) { + return String.valueOf(value); + } + int index = -1; + double res = value; + while (res > 10 && (false == isTwo || index < 1)) { + if (res > 1000) { + res = res / 1000; + index++; + } + if (res > 10) { + res = res / 10; + index++; + } + } + return String.format("%s%s", NumberUtil.decimalFormat("#.##", res), NUMBER_SUFFIX[index]); + } + + /** + * 将阿拉伯数字转为英文表达式 + * + * @param x 阿拉伯数字字符串 + * @return 英文表达式 + */ + private static String format(String x) { + int z = x.indexOf("."); // 取小数点位置 + String lstr, rstr = ""; + if (z > -1) { // 看是否有小数,如果有,则分别取左边和右边 + lstr = x.substring(0, z); + rstr = x.substring(z + 1); + } else { + // 否则就是全部 + lstr = x; + } + + String lstrrev = StrUtil.reverse(lstr); // 对左边的字串取反 + String[] a = new String[5]; // 定义5个字串变量来存放解析出来的叁位一组的字串 + + switch (lstrrev.length() % 3) { + case 1: + lstrrev += "00"; + break; + case 2: + lstrrev += "0"; + break; + } + StringBuilder lm = new StringBuilder(); // 用来存放转换后的整数部分 + for (int i = 0; i < lstrrev.length() / 3; i++) { + a[i] = StrUtil.reverse(lstrrev.substring(3 * i, 3 * i + 3)); // 截取第一个三位 + if (false == "000".equals(a[i])) { // 用来避免这种情况:1000000 = one million + // thousand only + if (i != 0) { + lm.insert(0, transThree(a[i]) + " " + parseMore(i) + " "); // 加: + // thousand、million、billion + } else { + // 防止i=0时, 在多加两个空格. + lm = new StringBuilder(transThree(a[i])); + } + } else { + lm.append(transThree(a[i])); + } + } + + String xs = ""; // 用来存放转换后小数部分 + if (z > -1) { + xs = "AND CENTS " + transTwo(rstr) + " "; // 小数部分存在时转换小数 + } + + return lm.toString().trim() + " " + xs + "ONLY"; + } + + private static String parseFirst(String s) { + return NUMBER[Integer.parseInt(s.substring(s.length() - 1))]; + } + + private static String parseTeen(String s) { + return NUMBER_TEEN[Integer.parseInt(s) - 10]; + } + + private static String parseTen(String s) { + return NUMBER_TEN[Integer.parseInt(s.substring(0, 1)) - 1]; + } + + private static String parseMore(int i) { + return NUMBER_MORE[i]; + } + + // 两位 + private static String transTwo(String s) { + String value; + // 判断位数 + if (s.length() > 2) { + s = s.substring(0, 2); + } else if (s.length() < 2) { + s = "0" + s; + } + + if (s.startsWith("0")) {// 07 - seven 是否小於10 + value = parseFirst(s); + } else if (s.startsWith("1")) {// 17 seventeen 是否在10和20之间 + value = parseTeen(s); + } else if (s.endsWith("0")) {// 是否在10与100之间的能被10整除的数 + value = parseTen(s); + } else { + value = parseTen(s) + " " + parseFirst(s); + } + return value; + } + + // 制作叁位的数 + // s.length = 3 + private static String transThree(String s) { + String value; + if (s.startsWith("0")) {// 是否小於100 + value = transTwo(s.substring(1)); + } else if ("00".equals(s.substring(1))) {// 是否被100整除 + value = parseFirst(s.substring(0, 1)) + " HUNDRED"; + } else { + value = parseFirst(s.substring(0, 1)) + " HUNDRED AND " + transTwo(s.substring(1)); + } + return value; + } +} diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/NumberWordFormatTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/NumberWordFormatTest.java index 835b06520..629205404 100644 --- a/hutool-core/src/test/java/cn/hutool/core/convert/NumberWordFormatTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/NumberWordFormatTest.java @@ -1,25 +1,34 @@ -package cn.hutool.core.convert; - -import org.junit.Assert; -import org.junit.Test; - -public class NumberWordFormatTest { - - @Test - public void formatTest() { - String format = NumberWordFormatter.format(100.23); - Assert.assertEquals("ONE HUNDRED AND CENTS TWENTY THREE ONLY", format); - - String format2 = NumberWordFormatter.format("2100.00"); - Assert.assertEquals("TWO THOUSAND ONE HUNDRED AND CENTS ONLY", format2); - - String format3 = NumberWordFormatter.formatValue(4384324, false); - Assert.assertEquals("4.38m", format3); - - String format4 = NumberWordFormatter.formatValue(4384324); - Assert.assertEquals("438.43w", format4); - - String format5 = NumberWordFormatter.formatValue(438); - Assert.assertEquals("438", format5); - } -} +package cn.hutool.core.convert; + +import org.junit.Assert; +import org.junit.Test; + +public class NumberWordFormatTest { + + @Test + public void formatTest() { + String format = NumberWordFormatter.format(100.23); + Assert.assertEquals("ONE HUNDRED AND CENTS TWENTY THREE ONLY", format); + + String format2 = NumberWordFormatter.format("2100.00"); + Assert.assertEquals("TWO THOUSAND ONE HUNDRED AND CENTS ONLY", format2); + } + + @Test + public void formatSimpleTest() { + String format1 = NumberWordFormatter.formatSimple(1200, false); + Assert.assertEquals("1.2k", format1); + + String format2 = NumberWordFormatter.formatSimple(4384324, false); + Assert.assertEquals("4.38m", format2); + + String format3 = NumberWordFormatter.formatSimple(4384324, true); + Assert.assertEquals("438.43w", format3); + + String format4 = NumberWordFormatter.formatSimple(4384324); + Assert.assertEquals("438.43w", format4); + + String format5 = NumberWordFormatter.formatSimple(438); + Assert.assertEquals("438", format5); + } +} From 66bdcac2b0480ebcd77f0e4a7aad215e22fddb24 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 20 Feb 2021 10:41:10 +0800 Subject: [PATCH 12/47] fix code --- .../main/java/cn/hutool/db/ds/DSFactory.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/DSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/DSFactory.java index 9d7b201c5..6d6df4269 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/DSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/DSFactory.java @@ -20,7 +20,7 @@ import java.io.Serializable; * 抽象数据源工厂类
* 通过实现{@link #getDataSource(String)} 方法实现数据源的获取
* 如果{@link DataSource} 的实现是数据库连接池库,应该在getDataSource调用时创建数据源并缓存 - * + * * @author Looly * */ @@ -46,7 +46,7 @@ public abstract class DSFactory implements Closeable, Serializable{ /** * 构造 - * + * * @param dataSourceName 数据源名称 */ public DSFactory(String dataSourceName) { @@ -55,7 +55,7 @@ public abstract class DSFactory implements Closeable, Serializable{ /** * 获得默认数据源 - * + * * @return 数据源 */ public DataSource getDataSource() { @@ -64,7 +64,7 @@ public abstract class DSFactory implements Closeable, Serializable{ /** * 获得分组对应数据源 - * + * * @param group 分组名 * @return 数据源 */ @@ -80,7 +80,7 @@ public abstract class DSFactory implements Closeable, Serializable{ /** * 关闭对应数据源 - * + * * @param group 分组 */ public abstract void close(String group); @@ -94,7 +94,7 @@ public abstract class DSFactory implements Closeable, Serializable{ /** * 获得数据源
* 使用默认配置文件的无分组配置 - * + * * @return 数据源 */ public static DataSource get() { @@ -103,7 +103,7 @@ public abstract class DSFactory implements Closeable, Serializable{ /** * 获得数据源 - * + * * @param group 配置文件中对应的分组 * @return 数据源 */ @@ -113,7 +113,7 @@ public abstract class DSFactory implements Closeable, Serializable{ /** * 根据Setting获取当前数据源工厂对象 - * + * * @param setting 数据源配置文件 * @return 当前使用的数据源工厂 * @deprecated 此方法容易引起歧义,应使用{@link #create(Setting)} 方法代替之 @@ -127,12 +127,12 @@ public abstract class DSFactory implements Closeable, Serializable{ * 设置全局的数据源工厂
* 在项目中存在多个连接池库的情况下,我们希望使用低优先级的库时使用此方法自定义之
* 重新定义全局的数据源工厂此方法可在以下两种情况下调用: - * + * *
 	 * 1. 在get方法调用前调用此方法来自定义全局的数据源工厂
 	 * 2. 替换已存在的全局数据源工厂,当已存在时会自动关闭
 	 * 
- * + * * @param dsFactory 数据源工厂 * @return 自定义的数据源工厂 */ From 76eb65249aa7125f70f329326b37be25bd032a61 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 22 Feb 2021 16:21:43 +0800 Subject: [PATCH 13/47] add method --- CHANGELOG.md | 2 ++ .../cn/hutool/core/collection/ListUtil.java | 13 ++++---- .../hutool/core/collection/ListUtilTest.java | 11 +++++++ .../java/cn/hutool/core/util/IdUtilTest.java | 24 +++++++------- .../main/java/cn/hutool/crypto/SmUtil.java | 31 +++++++++++++++++++ .../java/cn/hutool/crypto/asymmetric/SM2.java | 12 +++---- 6 files changed, 70 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24a1efd63..35d6c3b6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ * 【extra 】 修复Ftp中异常参数没有传入问题(issue#1397@Github) * 【crypto 】 修复Sm2使用D构造空指针问题(issue#I37Z4C@Gitee) * 【poi 】 修复ExcelPicUtil中图表报错问题(issue#I38857@Gitee) +* 【core 】 修复ListUtil.page方法返回空列表无法编辑问题(issue#1415@Github) +* 【core 】 修复ListUtil.sub中step不通结果不一致问题(issue#1409@Github) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java index f445e2927..088e19787 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java @@ -246,7 +246,7 @@ public class ListUtil { // 每页条目数大于总数直接返回所有 if (resultSize <= pageSize) { if (pageNo < (PageUtil.getFirstPageNo() + 1)) { - return Collections.unmodifiableList(list); + return unmodifiable(list); } else { // 越界直接返回空 return new ArrayList<>(0); @@ -262,11 +262,11 @@ public class ListUtil { if (startEnd[1] > resultSize) { startEnd[1] = resultSize; if (startEnd[0] > startEnd[1]) { - return empty(); + return new ArrayList<>(0); } } - return list.subList(startEnd[0], startEnd[1]); + return sub(list, startEnd[0], startEnd[1]); } /** @@ -366,7 +366,8 @@ public class ListUtil { } /** - * 截取集合的部分 + * 截取集合的部分
+ * 此方法与{@link List#subList(int, int)} 不同在于子列表是新的副本,操作子列表不会影响原列表。 * * @param 集合元素类型 * @param list 被截取的数组 @@ -407,8 +408,8 @@ public class ListUtil { end = size; } - if (step <= 1) { - return list.subList(start, end); + if (step < 1) { + step = 1; } final List result = new ArrayList<>(); diff --git a/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java index 86c9664dc..46c94cdd5 100644 --- a/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java @@ -101,4 +101,15 @@ public class ListUtilTest { int[] d1 = ListUtil.page(0,8,a).stream().mapToInt(Integer::valueOf).toArray(); Assert.assertArrayEquals(new int[]{1,2,3,4,5},d1); } + + @Test + public void subTest(){ + final List of = ListUtil.of(1, 2, 3, 4); + final List sub = ListUtil.sub(of, 2, 4); + sub.remove(0); + + // 对子列表操作不影响原列表 + Assert.assertEquals(4, of.size()); + Assert.assertEquals(1, sub.size()); + } } diff --git a/hutool-core/src/test/java/cn/hutool/core/util/IdUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/IdUtilTest.java index f9304b18d..ba4eba07b 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/IdUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/IdUtilTest.java @@ -17,7 +17,7 @@ import java.util.concurrent.CountDownLatch; /** * {@link IdUtil} 单元测试 - * + * * @author looly * */ @@ -31,12 +31,12 @@ public class IdUtilTest { String randomUUID = IdUtil.randomUUID(); Assert.assertEquals(36, randomUUID.length()); } - + @Test public void fastUUIDTest() { String simpleUUID = IdUtil.fastSimpleUUID(); Assert.assertEquals(32, simpleUUID.length()); - + String randomUUID = IdUtil.fastUUID(); Assert.assertEquals(36, randomUUID.length()); } @@ -60,25 +60,26 @@ public class IdUtilTest { } Console.log(timer.interval()); } - + @Test public void objectIdTest() { String id = IdUtil.objectId(); Assert.assertEquals(24, id.length()); } - + @Test public void createSnowflakeTest() { Snowflake snowflake = IdUtil.createSnowflake(1, 1); long id = snowflake.nextId(); Assert.assertTrue(id > 0); } - + @Test + @Ignore public void snowflakeBenchTest() { final Set set = new ConcurrentHashSet<>(); final Snowflake snowflake = IdUtil.createSnowflake(1, 1); - + //线程数 int threadCount = 100; //每个线程生成的ID数 @@ -94,7 +95,7 @@ public class IdUtilTest { latch.countDown(); }); } - + //等待全部线程结束 try { latch.await(); @@ -103,11 +104,12 @@ public class IdUtilTest { } Assert.assertEquals(threadCount * idCountPerThread, set.size()); } - + @Test + @Ignore public void snowflakeBenchTest2() { final Set set = new ConcurrentHashSet<>(); - + //线程数 int threadCount = 100; //每个线程生成的ID数 @@ -123,7 +125,7 @@ public class IdUtilTest { latch.countDown(); }); } - + //等待全部线程结束 try { latch.await(); diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java index 861768492..f3cb8083d 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java @@ -16,6 +16,8 @@ import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.gm.GMNamedCurves; import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.signers.DSAEncoding; +import org.bouncycastle.crypto.signers.StandardDSAEncoding; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; @@ -193,6 +195,35 @@ public class SmUtil { return result; } + /** + * 将sm2签名结果解码为R和S值 + * + * @param encoding {@link DSAEncoding} + * @param rsDer 签名结果的DER表示形式 + * @return R和S值,结果为64位,前32位为R,后32为为S + * @since 5.5.9 + */ + public static byte[] decode(DSAEncoding encoding, byte[] rsDer){ + if(null == encoding){ + encoding = StandardDSAEncoding.INSTANCE; + } + + final BigInteger[] decode; + try { + decode = encoding.decode(SM2_DOMAIN_PARAMS.getN(), rsDer); + } catch (IOException e) { + throw new IORuntimeException(e); + } + + byte[] r = bigIntToFixedLengthBytes(decode[0]); + byte[] s = bigIntToFixedLengthBytes(decode[1]); + byte[] result = new byte[RS_LEN * 2]; + System.arraycopy(r, 0, result, 0, r.length); + System.arraycopy(s, 0, result, RS_LEN, s.length); + + return result; + } + /** * BC的SM3withSM2签名得到的结果的rs是asn1格式的,这个方法转化成直接拼接r||s
* 来自:https://blog.csdn.net/pridas/article/details/86118774 diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java index e22c9402c..8a26f5d95 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java @@ -62,8 +62,8 @@ public class SM2 extends AbstractAsymmetricCrypto { * 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做加密或者解密 * - * @param privateKeyStr 私钥Hex或Base64表示 - * @param publicKeyStr 公钥Hex或Base64表示 + * @param privateKeyStr 私钥Hex或Base64表示,必须使用PKCS#8规范 + * @param publicKeyStr 公钥Hex或Base64表示,必须使用X509规范 */ public SM2(String privateKeyStr, String publicKeyStr) { this(SecureUtil.decode(privateKeyStr), SecureUtil.decode(publicKeyStr)); @@ -74,8 +74,8 @@ public class SM2 extends AbstractAsymmetricCrypto { * 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做加密或者解密 * - * @param privateKey 私钥 - * @param publicKey 公钥 + * @param privateKey 私钥,必须使用PKCS#8规范 + * @param publicKey 公钥,必须使用X509规范 */ public SM2(byte[] privateKey, byte[] publicKey) { this(// @@ -135,8 +135,8 @@ public class SM2 extends AbstractAsymmetricCrypto { * 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做加密或者解密 * - * @param privateKeyParams 私钥 - * @param publicKeyParams 公钥 + * @param privateKeyParams 私钥,可以为null + * @param publicKeyParams 公钥,可以为null */ public SM2(ECPrivateKeyParameters privateKeyParams, ECPublicKeyParameters publicKeyParams) { super(ALGORITHM_SM2, null, null); From cda3875d874b1b848c6bc5525417b6b728a529f3 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 22 Feb 2021 16:34:48 +0800 Subject: [PATCH 14/47] fix code --- .../main/java/cn/hutool/crypto/SmUtil.java | 57 ++++--------------- 1 file changed, 12 insertions(+), 45 deletions(-) diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java index f3cb8083d..49526f6ed 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java @@ -1,6 +1,7 @@ package cn.hutool.crypto; import cn.hutool.core.io.IORuntimeException; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.crypto.asymmetric.SM2; import cn.hutool.crypto.digest.HMac; import cn.hutool.crypto.digest.HmacAlgorithm; @@ -9,14 +10,9 @@ import cn.hutool.crypto.digest.mac.BCHMacEngine; import cn.hutool.crypto.digest.mac.MacEngine; import cn.hutool.crypto.symmetric.SM4; import cn.hutool.crypto.symmetric.SymmetricCrypto; -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.gm.GMNamedCurves; import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.crypto.params.ECDomainParameters; -import org.bouncycastle.crypto.signers.DSAEncoding; import org.bouncycastle.crypto.signers.StandardDSAEncoding; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; @@ -195,35 +191,6 @@ public class SmUtil { return result; } - /** - * 将sm2签名结果解码为R和S值 - * - * @param encoding {@link DSAEncoding} - * @param rsDer 签名结果的DER表示形式 - * @return R和S值,结果为64位,前32位为R,后32为为S - * @since 5.5.9 - */ - public static byte[] decode(DSAEncoding encoding, byte[] rsDer){ - if(null == encoding){ - encoding = StandardDSAEncoding.INSTANCE; - } - - final BigInteger[] decode; - try { - decode = encoding.decode(SM2_DOMAIN_PARAMS.getN(), rsDer); - } catch (IOException e) { - throw new IORuntimeException(e); - } - - byte[] r = bigIntToFixedLengthBytes(decode[0]); - byte[] s = bigIntToFixedLengthBytes(decode[1]); - byte[] result = new byte[RS_LEN * 2]; - System.arraycopy(r, 0, result, 0, r.length); - System.arraycopy(s, 0, result, RS_LEN, s.length); - - return result; - } - /** * BC的SM3withSM2签名得到的结果的rs是asn1格式的,这个方法转化成直接拼接r||s
* 来自:https://blog.csdn.net/pridas/article/details/86118774 @@ -233,14 +200,17 @@ public class SmUtil { * @since 4.5.0 */ public static byte[] rsAsn1ToPlain(byte[] rsDer) { - ASN1Sequence seq = ASN1Sequence.getInstance(rsDer); - byte[] r = bigIntToFixedLengthBytes(ASN1Integer.getInstance(seq.getObjectAt(0)).getValue()); - byte[] s = bigIntToFixedLengthBytes(ASN1Integer.getInstance(seq.getObjectAt(1)).getValue()); - byte[] result = new byte[RS_LEN * 2]; - System.arraycopy(r, 0, result, 0, r.length); - System.arraycopy(s, 0, result, RS_LEN, s.length); + final BigInteger[] decode; + try { + decode = StandardDSAEncoding.INSTANCE.decode(SM2_DOMAIN_PARAMS.getN(), rsDer); + } catch (IOException e) { + throw new IORuntimeException(e); + } - return result; + final byte[] r = bigIntToFixedLengthBytes(decode[0]); + final byte[] s = bigIntToFixedLengthBytes(decode[1]); + + return ArrayUtil.addAll(r, s); } /** @@ -257,11 +227,8 @@ public class SmUtil { } BigInteger r = new BigInteger(1, Arrays.copyOfRange(sign, 0, RS_LEN)); BigInteger s = new BigInteger(1, Arrays.copyOfRange(sign, RS_LEN, RS_LEN * 2)); - ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new ASN1Integer(r)); - v.add(new ASN1Integer(s)); try { - return new DERSequence(v).getEncoded("DER"); + return StandardDSAEncoding.INSTANCE.encode(SM2_DOMAIN_PARAMS.getN(), r, s); } catch (IOException e) { throw new IORuntimeException(e); } From bb645308ba3297873b565e188b6133dd3a096695 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 22 Feb 2021 16:54:28 +0800 Subject: [PATCH 15/47] fix doc --- hutool-core/src/main/java/cn/hutool/core/convert/Convert.java | 2 +- .../main/java/cn/hutool/core/convert/NumberWordFormatter.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java index 2e2377f32..d31e70478 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java @@ -967,7 +967,7 @@ public class Convert { * 将阿拉伯数字转为精简表示形式,例如: * *
-	 *     1200 -> 1.2k
+	 *     1200 -》 1.2k
 	 * 
* * @param number {@link Number}对象 diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java b/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java index 3304a32ff..22c0d057b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java @@ -37,7 +37,7 @@ public class NumberWordFormatter { } /** - * 将阿拉伯数字转化为简洁计数单位,例如 2100 => 2.1k + * 将阿拉伯数字转化为简洁计数单位,例如 2100 =》 2.1k * 范围默认只到w * * @param value 被格式化的数字 @@ -49,7 +49,7 @@ public class NumberWordFormatter { } /** - * 将阿拉伯数字转化为简介计数单位,例如 2100 => 2.1k + * 将阿拉伯数字转化为简介计数单位,例如 2100 =》 2.1k * * @param value 对应数字的值 * @param isTwo 控制是否为只为k、w,例如当为{@code false}时返回4.38m,{@code true}返回438.43w From 491e423e4b33ef59a71192ed91aa631d0b91eb6b Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 25 Feb 2021 21:24:50 +0800 Subject: [PATCH 16/47] fix code --- .../main/java/cn/hutool/http/server/HttpServerResponse.java | 2 ++ hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java | 4 ++-- .../src/main/java/cn/hutool/poi/excel/style/StyleUtil.java | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/hutool-http/src/main/java/cn/hutool/http/server/HttpServerResponse.java b/hutool-http/src/main/java/cn/hutool/http/server/HttpServerResponse.java index bad6c1ccb..f53d8d4aa 100644 --- a/hutool-http/src/main/java/cn/hutool/http/server/HttpServerResponse.java +++ b/hutool-http/src/main/java/cn/hutool/http/server/HttpServerResponse.java @@ -378,6 +378,7 @@ public class HttpServerResponse extends HttpServerBase { * 返回文件给客户端(文件下载) * * @param file 写出的文件对象 + * @param fileName 文件名 * @return this * @since 5.5.8 */ @@ -417,6 +418,7 @@ public class HttpServerResponse extends HttpServerBase { * 返回文件数据给客户端(文件下载) * * @param in 需要返回客户端的内容 + * @param length 长度 * @param contentType 返回的类型 * @param fileName 文件名 * @since 5.2.7 diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java index 9e88abc29..cffbe98d3 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java @@ -324,7 +324,7 @@ public class ExcelBase> implements Closeable { } /** - * 获取或创建某一行的样式,返回样式后可以设置样式内容
+ * 获取或创建某一列的样式,返回样式后可以设置样式内容
* 需要注意,此方法返回行样式,设置背景色在单元格设置值后会被覆盖,需要单独设置其单元格的样式。 * * @param x X坐标,从0计数,即列号 @@ -337,7 +337,7 @@ public class ExcelBase> implements Closeable { } /** - * 创建某一行的样式,返回样式后可以设置样式内容 + * 创建某一列的样式,返回样式后可以设置样式内容 * * @param x X坐标,从0计数,即列号 * @return {@link CellStyle} diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/style/StyleUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/style/StyleUtil.java index df60342d2..538f646af 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/style/StyleUtil.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/style/StyleUtil.java @@ -206,6 +206,7 @@ public class StyleUtil { /** * 创建数据格式并获取格式 * + * @param workbook {@link Workbook} * @param format 数据格式 * @return 数据格式 * @since 5.5.5 From 95e0292757bf84bed4d9fc2a62882a056f6a7a48 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 25 Feb 2021 21:34:34 +0800 Subject: [PATCH 17/47] fix test --- .../cn/hutool/crypto/test/PemUtilTest.java | 2 ++ .../crypto/test/asymmetric/SM2Test.java | 23 ++++++++++--------- .../java/cn/hutool/http/HttpUtilTest.java | 7 ------ 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java index 990c06d8c..86f8a578c 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java @@ -5,6 +5,7 @@ import cn.hutool.crypto.PemUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.RSA; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import java.security.PrivateKey; @@ -44,6 +45,7 @@ public class PemUtilTest { } @Test + @Ignore public void readECPrivateKeyTest() { PrivateKey privateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_ec_private_key.pem")); Assert.assertNotNull(privateKey); diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java index 0c4bfe152..d6d28b696 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java @@ -16,6 +16,7 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.junit.Assert; import org.junit.Test; +import java.nio.charset.StandardCharsets; import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; @@ -115,7 +116,7 @@ public class SM2Test { @Test public void sm2SignTest(){ //需要签名的明文,得到明文对应的字节数组 - byte[] dataBytes = "我是一段测试aaaa".getBytes(); + byte[] dataBytes = "我是一段测试aaaa".getBytes(StandardCharsets.UTF_8); //指定的私钥 String privateKeyHex = "1ebf8b341c695ee456fd1a41b82645724bc25d79935437d30e7e4b0a554baa5e"; @@ -131,7 +132,7 @@ public class SM2Test { //指定的公钥 String publicKeyHex = "04db9629dd33ba568e9507add5df6587a0998361a03d3321948b448c653c2c1b7056434884ab6f3d1c529501f166a336e86f045cea10dffe58aa82ea13d7253763"; //需要加密的明文,得到明文对应的字节数组 - byte[] dataBytes = "我是一段测试aaaa".getBytes(); + byte[] dataBytes = "我是一段测试aaaa".getBytes(StandardCharsets.UTF_8); //签名值 String signHex = "2881346e038d2ed706ccdd025f2b1dafa7377d5cf090134b98756fafe084dddbcdba0ab00b5348ed48025195af3f1dda29e819bb66aa9d4d088050ff148482a1"; @@ -148,8 +149,8 @@ public class SM2Test { final SM2 sm2 = SmUtil.sm2(); - byte[] sign = sm2.sign(content.getBytes()); - boolean verify = sm2.verify(content.getBytes(), sign); + byte[] sign = sm2.sign(StrUtil.utf8Bytes(content)); + boolean verify = sm2.verify(StrUtil.utf8Bytes(content), sign); Assert.assertTrue(verify); } @@ -172,8 +173,8 @@ public class SM2Test { final SM2 sm2 = new SM2(pair.getPrivate(), pair.getPublic()); - byte[] sign = sm2.sign(content.getBytes()); - boolean verify = sm2.verify(content.getBytes(), sign); + byte[] sign = sm2.sign(content.getBytes(StandardCharsets.UTF_8)); + boolean verify = sm2.verify(content.getBytes(StandardCharsets.UTF_8), sign); Assert.assertTrue(verify); } @@ -188,8 +189,8 @@ public class SM2Test { HexUtil.encodeHexStr(pair.getPublic().getEncoded())// ); - byte[] sign = sm2.sign(content.getBytes()); - boolean verify = sm2.verify(content.getBytes(), sign); + byte[] sign = sm2.sign(content.getBytes(StandardCharsets.UTF_8)); + boolean verify = sm2.verify(content.getBytes(StandardCharsets.UTF_8), sign); Assert.assertTrue(verify); } @@ -267,11 +268,11 @@ public class SM2Test { String src = "Sm2Test"; byte[] data = sm2.encrypt(src, KeyType.PublicKey); - byte[] sign = sm2.sign(src.getBytes()); + byte[] sign = sm2.sign(src.getBytes(StandardCharsets.UTF_8)); - Assert.assertTrue(sm2.verify( src.getBytes(), sign)); + Assert.assertTrue(sm2.verify( src.getBytes(StandardCharsets.UTF_8), sign)); byte[] dec = sm2.decrypt(data, KeyType.PrivateKey); - Assert.assertArrayEquals(dec, src.getBytes()); + Assert.assertArrayEquals(dec, src.getBytes(StandardCharsets.UTF_8)); } } diff --git a/hutool-http/src/test/java/cn/hutool/http/HttpUtilTest.java b/hutool-http/src/test/java/cn/hutool/http/HttpUtilTest.java index 43dfcd665..4a7aa3c1f 100644 --- a/hutool-http/src/test/java/cn/hutool/http/HttpUtilTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/HttpUtilTest.java @@ -318,11 +318,4 @@ public class HttpUtilTest { final String s = HttpUtil.get(url); Console.log(s); } - - @Test - public void tjhrTest(){ - String url = "https://www.51tjhr.com"; - final String s = HttpUtil.get(url); - Console.log(s); - } } From d615b5147b4a1f244323323eaea70508e94b3cc5 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 25 Feb 2021 21:59:39 +0800 Subject: [PATCH 18/47] fix db bug --- CHANGELOG.md | 3 +- .../main/java/cn/hutool/db/sql/Condition.java | 23 +++++++++++-- .../java/cn/hutool/db/sql/ConditionTest.java | 32 ++++++++++++------- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35d6c3b6d..e25e441b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.5.9 (2021-02-20) +# 5.5.9 (2021-02-25) ### 新特性 * 【crypto 】 PemUtil.readPemKey支持EC(pr#1366@Github) @@ -21,6 +21,7 @@ * 【poi 】 修复ExcelPicUtil中图表报错问题(issue#I38857@Gitee) * 【core 】 修复ListUtil.page方法返回空列表无法编辑问题(issue#1415@Github) * 【core 】 修复ListUtil.sub中step不通结果不一致问题(issue#1409@Github) +* 【db 】 修复Condition转换参数值时未转换数字异常(issue#I38LTM@Gitee) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-db/src/main/java/cn/hutool/db/sql/Condition.java b/hutool-db/src/main/java/cn/hutool/db/sql/Condition.java index 92fb8a55a..8cea8d6c9 100644 --- a/hutool-db/src/main/java/cn/hutool/db/sql/Condition.java +++ b/hutool-db/src/main/java/cn/hutool/db/sql/Condition.java @@ -5,6 +5,7 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.text.StrSpliter; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.CharUtil; +import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.StrUtil; import java.util.Arrays; @@ -444,7 +445,7 @@ public class Condition extends CloneSupport { return; } - valueStr = valueStr.trim(); + valueStr = StrUtil.trim(valueStr); // 处理null if (StrUtil.endWithIgnoreCase(valueStr, "null")) { @@ -463,7 +464,7 @@ public class Condition extends CloneSupport { } } - List strs = StrUtil.split(valueStr, StrUtil.C_SPACE, 2); + final List strs = StrUtil.split(valueStr, StrUtil.C_SPACE, 2); if (strs.size() < 2) { return; } @@ -472,7 +473,8 @@ public class Condition extends CloneSupport { final String firstPart = strs.get(0).trim().toUpperCase(); if (OPERATORS.contains(firstPart)) { this.operator = firstPart; - this.value = strs.get(1).trim(); + // 比较符号后跟大部分为数字,此处做转换 + this.value = tryToNumber(strs.get(1)); return; } @@ -526,5 +528,20 @@ public class Condition extends CloneSupport { } return value.substring(from, to); } + + /** + * 尝试转换为数字,转换失败返回字符串 + * + * @param value 被转换的字符串值 + * @return 转换后的值 + */ + private static Object tryToNumber(String value){ + value = StrUtil.trim(value); + try{ + return NumberUtil.parseNumber(value); + } catch (Exception ignore){ + return value; + } + } // ----------------------------------------------------------------------------------------------- Private method end } diff --git a/hutool-db/src/test/java/cn/hutool/db/sql/ConditionTest.java b/hutool-db/src/test/java/cn/hutool/db/sql/ConditionTest.java index e7823026d..c3078485d 100644 --- a/hutool-db/src/test/java/cn/hutool/db/sql/ConditionTest.java +++ b/hutool-db/src/test/java/cn/hutool/db/sql/ConditionTest.java @@ -4,52 +4,60 @@ import org.junit.Assert; import org.junit.Test; public class ConditionTest { - + @Test public void toStringTest() { Condition conditionNull = new Condition("user", null); Assert.assertEquals("user IS NULL", conditionNull.toString()); - + Condition conditionNotNull = new Condition("user", "!= null"); Assert.assertEquals("user IS NOT NULL", conditionNotNull.toString()); - + Condition condition2 = new Condition("user", "= zhangsan"); Assert.assertEquals("user = ?", condition2.toString()); - + Condition conditionLike = new Condition("user", "like %aaa"); Assert.assertEquals("user LIKE ?", conditionLike.toString()); - + Condition conditionIn = new Condition("user", "in 1,2,3"); Assert.assertEquals("user IN (?,?,?)", conditionIn.toString()); - + Condition conditionBetween = new Condition("user", "between 12 and 13"); Assert.assertEquals("user BETWEEN ? AND ?", conditionBetween.toString()); } - + @Test public void toStringNoPlaceHolderTest() { Condition conditionNull = new Condition("user", null); conditionNull.setPlaceHolder(false); Assert.assertEquals("user IS NULL", conditionNull.toString()); - + Condition conditionNotNull = new Condition("user", "!= null"); conditionNotNull.setPlaceHolder(false); Assert.assertEquals("user IS NOT NULL", conditionNotNull.toString()); - + Condition conditionEquals = new Condition("user", "= zhangsan"); conditionEquals.setPlaceHolder(false); Assert.assertEquals("user = zhangsan", conditionEquals.toString()); - + Condition conditionLike = new Condition("user", "like %aaa"); conditionLike.setPlaceHolder(false); Assert.assertEquals("user LIKE %aaa", conditionLike.toString()); - + Condition conditionIn = new Condition("user", "in 1,2,3"); conditionIn.setPlaceHolder(false); Assert.assertEquals("user IN (1,2,3)", conditionIn.toString()); - + Condition conditionBetween = new Condition("user", "between 12 and 13"); conditionBetween.setPlaceHolder(false); Assert.assertEquals("user BETWEEN 12 AND 13", conditionBetween.toString()); } + + @Test + public void parseTest(){ + final Condition age = Condition.parse("age", "< 10"); + Assert.assertEquals("age < ?", age.toString()); + // issue I38LTM + Assert.assertSame(Long.class, age.getValue().getClass()); + } } From fdd4e51fd1e5529d46cc6863f384b5d311e846ab Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 25 Feb 2021 22:16:46 +0800 Subject: [PATCH 19/47] fix test --- .../src/test/java/cn/hutool/core/lang/ClassScanerTest.java | 6 +++--- .../test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/ClassScanerTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/ClassScanerTest.java index 897557f82..9e9654f6b 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/ClassScanerTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/ClassScanerTest.java @@ -1,12 +1,12 @@ package cn.hutool.core.lang; -import java.util.Set; - import org.junit.Ignore; import org.junit.Test; +import java.util.Set; + public class ClassScanerTest { - + @Test @Ignore public void scanTest() { diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java index d6d28b696..5399629cb 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java @@ -275,4 +275,10 @@ public class SM2Test { byte[] dec = sm2.decrypt(data, KeyType.PrivateKey); Assert.assertArrayEquals(dec, src.getBytes(StandardCharsets.UTF_8)); } + + @Test + public void test(){ + String priKey = "MHcCAQEEIE29XqAFV/rkJbnJzCoQRJLTeAHG2TR0h9ZCWag0+ZMEoAoGCCqBHM9VAYItoUQDQgAESkOzNigIsH5ehFvr9yQNQ66genyOrm+Q4umCA4aWXPeRzmcTAWSlTineiReTFN2lqor2xaulT8u3a4w3AM/F6A=="; + String pubKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAESkOzNigIsH5ehFvr9yQNQ66genyOrm+Q4umCA4aWXPeRzmcTAWSlTineiReTFN2lqor2xaulT8u3a4w3AM/F6A=="; + } } From 4c772ead3535c0f24efdcd6b4fed05f1898623dc Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 25 Feb 2021 23:53:51 +0800 Subject: [PATCH 20/47] add method --- CHANGELOG.md | 1 + .../main/java/cn/hutool/crypto/ECKeyUtil.java | 22 +++++++++++++++++++ .../main/java/cn/hutool/crypto/PemUtil.java | 12 ++++++++++ .../main/java/cn/hutool/crypto/SmUtil.java | 14 ++++++------ .../cn/hutool/crypto/test/PemUtilTest.java | 16 ++++++++++---- 5 files changed, 54 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e25e441b7..0321de887 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * 【crypto 】 Sm2增加getD和getQ方法(issue#I37Z4C@Gitee) * 【cache 】 AbstractCache增加keySet方法(issue#I37Z4C@Gitee) * 【core 】 NumberWordFormatter增加formatSimple方法(pr#1436@Github) +* 【crypto 】 增加读取openSSL生成的sm2私钥 ### Bug修复 * 【json 】 JSONUtil.isJson方法改变trim策略,解决特殊空白符导致判断失败问题 diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java index 73b12a8c1..055d0bf57 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java @@ -1,5 +1,11 @@ package cn.hutool.crypto; +import cn.hutool.core.io.IORuntimeException; +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.sec.ECPrivateKey; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; @@ -8,6 +14,7 @@ import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.BigIntegers; +import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.Key; @@ -262,4 +269,19 @@ public class ECKeyUtil { throw new CryptoException(e); } } + + /** + * 将SM2算法的{@link ECPrivateKey} 转换为 {@link PrivateKey} + * @param privateKey {@link ECPrivateKey} + * @return {@link PrivateKey} + */ + public static PrivateKey toSm2PrivateKey(ECPrivateKey privateKey){ + try { + final PrivateKeyInfo info = new PrivateKeyInfo( + new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, SmUtil.ID_SM2_PUBLIC_KEY_PARAM), privateKey); + return KeyUtil.generatePrivateKey("SM2", info.getEncoded(ASN1Encoding.DER)); + } catch (IOException e) { + throw new IORuntimeException(e); + } + } } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java index e9271929b..5d9cb4b4f 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java @@ -3,6 +3,7 @@ package cn.hutool.crypto; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.StrUtil; +import org.bouncycastle.asn1.sec.ECPrivateKey; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemObjectGenerator; import org.bouncycastle.util.io.pem.PemReader; @@ -159,4 +160,15 @@ public class PemUtil { IoUtil.close(writer); } } + + /** + * 读取OpenSSL生成的ANS1格式的Pem私钥文件 + * + * @param keyStream 私钥pem流 + * @return {@link PrivateKey} + */ + public static PrivateKey readSm2PemPrivateKey(InputStream keyStream){ + final ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(readPem(keyStream)); + return ECKeyUtil.toSm2PrivateKey(ecPrivateKey); + } } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java index 49526f6ed..2f8d61b7f 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java @@ -10,6 +10,7 @@ import cn.hutool.crypto.digest.mac.BCHMacEngine; import cn.hutool.crypto.digest.mac.MacEngine; import cn.hutool.crypto.symmetric.SM4; import cn.hutool.crypto.symmetric.SymmetricCrypto; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.gm.GMNamedCurves; import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.crypto.params.ECDomainParameters; @@ -31,6 +32,7 @@ import java.math.BigInteger; */ public class SmUtil { + private final static int RS_LEN = 32; /** * SM2默认曲线 */ @@ -38,13 +40,11 @@ public class SmUtil { /** * SM2推荐曲线参数(来自https://github.com/ZZMarquis/gmhelper) */ - public static final ECDomainParameters SM2_DOMAIN_PARAMS; - - private final static int RS_LEN = 32; - - static { - SM2_DOMAIN_PARAMS = BCUtil.toDomainParams(GMNamedCurves.getByName(SM2_CURVE_NAME)); - } + public static final ECDomainParameters SM2_DOMAIN_PARAMS = BCUtil.toDomainParams(GMNamedCurves.getByName(SM2_CURVE_NAME)); + /** + * SM2国密算法公钥参数的Oid标识 + */ + public static final ASN1ObjectIdentifier ID_SM2_PUBLIC_KEY_PARAM = new ASN1ObjectIdentifier("1.2.156.10197.1.301"); /** * 创建SM2算法对象
diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java index 86f8a578c..637c09c6f 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java @@ -4,10 +4,11 @@ import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.crypto.PemUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.RSA; +import cn.hutool.crypto.asymmetric.SM2; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; +import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.PublicKey; @@ -45,9 +46,16 @@ public class PemUtilTest { } @Test - @Ignore public void readECPrivateKeyTest() { - PrivateKey privateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_ec_private_key.pem")); - Assert.assertNotNull(privateKey); + PrivateKey privateKey = PemUtil.readSm2PemPrivateKey(ResourceUtil.getStream("test_ec_private_key.pem")); + SM2 sm2 = new SM2(privateKey, null); + sm2.usePlainEncoding(); + + //需要签名的明文,得到明文对应的字节数组 + byte[] dataBytes = "我是一段测试aaaa".getBytes(StandardCharsets.UTF_8); + + byte[] sign = sm2.sign(dataBytes, null); + // 64位签名 + Assert.assertEquals(64, sign.length); } } From ba8b4ad760ba45eb82ff77ea4420531a816f2737 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 26 Feb 2021 09:11:45 +0800 Subject: [PATCH 21/47] add methods --- .../main/java/cn/hutool/crypto/BCUtil.java | 37 ++++++++++ .../main/java/cn/hutool/crypto/PemUtil.java | 72 ++++++++++++++----- .../java/cn/hutool/crypto/asymmetric/SM2.java | 6 +- 3 files changed, 96 insertions(+), 19 deletions(-) diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/BCUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/BCUtil.java index 918b1086b..1b603cc09 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/BCUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/BCUtil.java @@ -1,5 +1,8 @@ package cn.hutool.crypto; +import cn.hutool.core.io.IORuntimeException; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; @@ -13,6 +16,7 @@ import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.math.ec.ECCurve; +import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.security.Key; @@ -313,4 +317,37 @@ public class BCUtil { public static PublicKey readPemPublicKey(InputStream pemStream) { return PemUtil.readPemPublicKey(pemStream); } + + /** + * Java中的PKCS#8格式私钥转换为OpenSSL支持的PKCS#1格式 + * + * @param privateKey PKCS#8格式私钥 + * @return PKCS#1格式私钥 + * @since 5.5.9 + */ + public static byte[] toPkcs1(PrivateKey privateKey){ + final PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privateKey.getEncoded()); + try { + return pkInfo.parsePrivateKey().toASN1Primitive().getEncoded(); + } catch (IOException e) { + throw new IORuntimeException(e); + } + } + + /** + * Java中的X.509格式公钥转换为OpenSSL支持的PKCS#1格式 + * + * @param publicKey X.509格式公钥 + * @return PKCS#1格式公钥 + * @since 5.5.9 + */ + public static byte[] toPkcs1(PublicKey publicKey){ + final SubjectPublicKeyInfo spkInfo = SubjectPublicKeyInfo + .getInstance(publicKey.getEncoded()); + try { + return spkInfo.parsePublicKey().getEncoded(); + } catch (IOException e) { + throw new IORuntimeException(e); + } + } } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java index 5d9cb4b4f..5e3e29797 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java @@ -13,6 +13,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; +import java.io.StringWriter; +import java.io.Writer; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; @@ -67,7 +69,8 @@ public class PemUtil { //private if (type.endsWith("EC PRIVATE KEY")) { return KeyUtil.generatePrivateKey("EC", object.getContent()); - }if (type.endsWith("PRIVATE KEY")) { + } + if (type.endsWith("PRIVATE KEY")) { return KeyUtil.generateRSAPrivateKey(object.getContent()); } @@ -130,11 +133,35 @@ public class PemUtil { } } + /** + * 读取OpenSSL生成的ANS1格式的Pem私钥文件 + * + * @param keyStream 私钥pem流 + * @return {@link PrivateKey} + */ + public static PrivateKey readSm2PemPrivateKey(InputStream keyStream) { + final ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(readPem(keyStream)); + return ECKeyUtil.toSm2PrivateKey(ecPrivateKey); + } + + /** + * 将私钥或公钥转换为PEM格式的字符串 + * @param type 密钥类型(私钥、公钥、证书) + * @param content 密钥内容 + * @return PEM内容 + * @since 5.5.9 + */ + public static String toPem(String type, byte[] content) { + final StringWriter stringWriter = new StringWriter(); + writePemObject(type, content, stringWriter); + return stringWriter.toString(); + } + /** * 写出pem密钥(私钥、公钥、证书) * * @param type 密钥类型(私钥、公钥、证书) - * @param content 密钥内容 + * @param content 密钥内容,需为PKCS#1格式 * @param keyStream pem流 * @since 5.1.6 */ @@ -142,6 +169,18 @@ public class PemUtil { writePemObject(new PemObject(type, content), keyStream); } + /** + * 写出pem密钥(私钥、公钥、证书) + * + * @param type 密钥类型(私钥、公钥、证书) + * @param content 密钥内容,需为PKCS#1格式 + * @param writer pemWriter + * @since 5.5.9 + */ + public static void writePemObject(String type, byte[] content, Writer writer) { + writePemObject(new PemObject(type, content), writer); + } + /** * 写出pem密钥(私钥、公钥、证书) * @@ -150,25 +189,24 @@ public class PemUtil { * @since 5.1.6 */ public static void writePemObject(PemObjectGenerator pemObject, OutputStream keyStream) { - PemWriter writer = null; - try { - writer = new PemWriter(IoUtil.getUtf8Writer(keyStream)); - writer.writeObject(pemObject); - } catch (IOException e) { - throw new IORuntimeException(e); - } finally { - IoUtil.close(writer); - } + writePemObject(pemObject, IoUtil.getUtf8Writer(keyStream)); } /** - * 读取OpenSSL生成的ANS1格式的Pem私钥文件 + * 写出pem密钥(私钥、公钥、证书) * - * @param keyStream 私钥pem流 - * @return {@link PrivateKey} + * @param pemObject pem对象,包括密钥和密钥类型等信息 + * @param writer pemWriter + * @since 5.5.9 */ - public static PrivateKey readSm2PemPrivateKey(InputStream keyStream){ - final ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(readPem(keyStream)); - return ECKeyUtil.toSm2PrivateKey(ecPrivateKey); + public static void writePemObject(PemObjectGenerator pemObject, Writer writer) { + final PemWriter pemWriter = new PemWriter(writer); + try { + pemWriter.writeObject(pemObject); + } catch (IOException e) { + throw new IORuntimeException(e); + } finally { + IoUtil.close(pemWriter); + } } } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java index 8a26f5d95..ad4c3cf78 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java @@ -274,7 +274,8 @@ public class SM2 extends AbstractAsymmetricCrypto { } /** - * 用私钥对信息生成数字签名 + * 用私钥对信息生成数字签名,签名格式为ASN1
+ * * 在硬件签名中,返回结果为R+S,可以通过调用{@link cn.hutool.crypto.SmUtil#rsAsn1ToPlain(byte[])}方法转换之。 * * @param data 加密数据 * @return 签名 @@ -295,7 +296,8 @@ public class SM2 extends AbstractAsymmetricCrypto { } /** - * 用私钥对信息生成数字签名 + * 用私钥对信息生成数字签名,签名格式为ASN1
+ * 在硬件签名中,返回结果为R+S,可以通过调用{@link cn.hutool.crypto.SmUtil#rsAsn1ToPlain(byte[])}方法转换之。 * * @param data 被签名的数据数据 * @param id 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() From 32c4952d3188ce2b204b20f4d5874a5b3b6bef0a Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 26 Feb 2021 22:50:35 +0800 Subject: [PATCH 22/47] add method --- CHANGELOG.md | 3 +- .../hutool/core/collection/CollUtilTest.java | 11 ++ .../main/java/cn/hutool/crypto/ECKeyUtil.java | 119 +++++++++++++++++- .../main/java/cn/hutool/crypto/KeyUtil.java | 6 +- .../main/java/cn/hutool/crypto/PemUtil.java | 10 +- .../main/java/cn/hutool/crypto/SmUtil.java | 49 +++++++- .../java/cn/hutool/crypto/asymmetric/SM2.java | 12 +- .../java/cn/hutool/crypto/digest/SM3.java | 2 +- .../cn/hutool/crypto/test/PemUtilTest.java | 19 +++ .../crypto/test/asymmetric/SM2Test.java | 46 +++++-- 10 files changed, 243 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0321de887..a29c00be7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.5.9 (2021-02-25) +# 5.5.9 (2021-02-26) ### 新特性 * 【crypto 】 PemUtil.readPemKey支持EC(pr#1366@Github) @@ -13,6 +13,7 @@ * 【cache 】 AbstractCache增加keySet方法(issue#I37Z4C@Gitee) * 【core 】 NumberWordFormatter增加formatSimple方法(pr#1436@Github) * 【crypto 】 增加读取openSSL生成的sm2私钥 +* 【crypto 】 增加众多方法,SM2兼容各类密钥格式(issue#I37Z75@Gitee) ### Bug修复 * 【json 】 JSONUtil.isJson方法改变trim策略,解决特殊空白符导致判断失败问题 diff --git a/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java index aa16fcab4..076dd64fb 100644 --- a/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java @@ -11,6 +11,7 @@ import org.junit.Assert; import org.junit.Test; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -694,4 +695,14 @@ public class CollUtilTest { Assert.assertEquals(0, CollUtil.page(3, 5, objects).size()); } + + @Test + public void subtractToListTest(){ + List list1 = Arrays.asList(1L, 2L, 3L); + List list2 = Arrays.asList(2L, 3L); + + List result = CollUtil.subtractToList(list1, list2); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(1L, result.get(0), 1); + } } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java index 055d0bf57..283101da8 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java @@ -11,7 +11,11 @@ import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; +import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec; +import org.bouncycastle.jcajce.spec.OpenSSHPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.FixedPointCombMultiplier; import org.bouncycastle.util.BigIntegers; import java.io.IOException; @@ -20,6 +24,7 @@ import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; +import java.security.spec.KeySpec; /** * EC密钥参数相关工具类封装 @@ -45,7 +50,21 @@ public class ECKeyUtil { return null; } + /** + * 根据私钥参数获取公钥参数 + * + * @param privateKeyParameters 私钥参数 + * @return 公钥参数 + * @since 5.5.9 + */ + public static ECPublicKeyParameters getPublicParams(ECPrivateKeyParameters privateKeyParameters) { + final ECDomainParameters domainParameters = privateKeyParameters.getParameters(); + final ECPoint q = new FixedPointCombMultiplier().multiply(domainParameters.getG(), privateKeyParameters.getD()); + return new ECPublicKeyParameters(q, domainParameters); + } + //--------------------------------------------------------------------------- Public Key + /** * 转换为 ECPublicKeyParameters * @@ -91,8 +110,8 @@ public class ECKeyUtil { /** * 转换为ECPublicKeyParameters * - * @param x 公钥X - * @param y 公钥Y + * @param x 公钥X + * @param y 公钥Y * @param domainParameters ECDomainParameters * @return ECPublicKeyParameters,x或y为{@code null}则返回{@code null} */ @@ -109,7 +128,7 @@ public class ECKeyUtil { * @return ECPublicKeyParameters */ public static ECPublicKeyParameters toPublicParams(byte[] xBytes, byte[] yBytes, ECDomainParameters domainParameters) { - if(null == xBytes || null == yBytes){ + if (null == xBytes || null == yBytes) { return null; } return toPublicParams(BigIntegers.fromUnsignedByteArray(xBytes), BigIntegers.fromUnsignedByteArray(yBytes), domainParameters); @@ -187,6 +206,7 @@ public class ECKeyUtil { } //--------------------------------------------------------------------------- Private Key + /** * 转换为 ECPrivateKeyParameters * @@ -220,7 +240,7 @@ public class ECKeyUtil { /** * 转换为 ECPrivateKeyParameters * - * @param d 私钥d值16进制字符串 + * @param d 私钥d值16进制字符串 * @param domainParameters ECDomainParameters * @return ECPrivateKeyParameters */ @@ -272,10 +292,11 @@ public class ECKeyUtil { /** * 将SM2算法的{@link ECPrivateKey} 转换为 {@link PrivateKey} + * * @param privateKey {@link ECPrivateKey} * @return {@link PrivateKey} */ - public static PrivateKey toSm2PrivateKey(ECPrivateKey privateKey){ + public static PrivateKey toSm2PrivateKey(ECPrivateKey privateKey) { try { final PrivateKeyInfo info = new PrivateKeyInfo( new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, SmUtil.ID_SM2_PUBLIC_KEY_PARAM), privateKey); @@ -284,4 +305,92 @@ public class ECKeyUtil { throw new IORuntimeException(e); } } + + /** + * 创建{@link OpenSSHPrivateKeySpec} + * + * @param key 私钥,需为PKCS#1格式 + * @return {@link OpenSSHPrivateKeySpec} + * @since 5.5.9 + */ + public static KeySpec createOpenSSHPrivateKeySpec(byte[] key) { + return new OpenSSHPrivateKeySpec(key); + } + + /** + * 创建{@link OpenSSHPublicKeySpec} + * + * @param key 公钥,需为PKCS#1格式 + * @return {@link OpenSSHPublicKeySpec} + * @since 5.5.9 + */ + public static KeySpec createOpenSSHPublicKeySpec(byte[] key) { + return new OpenSSHPublicKeySpec(key); + } + + /** + * 尝试解析转换各种类型私钥为{@link ECPrivateKeyParameters},支持包括: + * + *
    + *
  • D值
  • + *
  • PKCS#8
  • + *
  • PKCS#1
  • + *
+ * + * @param privateKeyBytes 私钥 + * @return {@link ECPrivateKeyParameters} + * @since 5.5.9 + */ + public static ECPrivateKeyParameters decodePrivateKeyParams(byte[] privateKeyBytes) { + try { + // 尝试D值 + return toSm2PrivateParams(privateKeyBytes); + } catch (Exception ignore) { + // ignore + } + + PrivateKey privateKey; + //尝试PKCS#8 + try { + privateKey = KeyUtil.generatePrivateKey("sm2", privateKeyBytes); + } catch (Exception ignore) { + // 尝试PKCS#1 + privateKey = KeyUtil.generatePrivateKey("sm2", createOpenSSHPrivateKeySpec(privateKeyBytes)); + } + + return toPrivateParams(privateKey); + } + + /** + * 尝试解析转换各种类型公钥为{@link ECPublicKeyParameters},支持包括: + * + *
    + *
  • Q值
  • + *
  • X.509
  • + *
  • PKCS#1
  • + *
+ * + * @param publicKeyBytes 公钥 + * @return {@link ECPublicKeyParameters} + * @since 5.5.9 + */ + public static ECPublicKeyParameters decodePublicKeyParams(byte[] publicKeyBytes) { + try { + // 尝试Q值 + return toSm2PublicParams(publicKeyBytes); + } catch (Exception ignore) { + // ignore + } + + PublicKey publicKey; + //尝试X.509 + try { + publicKey = KeyUtil.generatePublicKey("sm2", publicKeyBytes); + } catch (Exception ignore) { + // 尝试PKCS#1 + publicKey = KeyUtil.generatePublicKey("sm2", createOpenSSHPublicKeySpec(publicKeyBytes)); + } + + return toPublicParams(publicKey); + } } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java index 21e2e7cab..3d97f1fc1 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java @@ -256,8 +256,8 @@ public class KeyUtil { * 采用PKCS#8规范,此规范定义了私钥信息语法和加密私钥语法
* 算法见:https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyFactory * - * @param algorithm 算法 - * @param key 密钥,必须为DER编码存储 + * @param algorithm 算法,如RSA、EC、SM2等 + * @param key 密钥,PKCS#8格式 * @return 私钥 {@link PrivateKey} */ public static PrivateKey generatePrivateKey(String algorithm, byte[] key) { @@ -271,7 +271,7 @@ public class KeyUtil { * 生成私钥,仅用于非对称加密
* 算法见:https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyFactory * - * @param algorithm 算法 + * @param algorithm 算法,如RSA、EC、SM2等 * @param keySpec {@link KeySpec} * @return 私钥 {@link PrivateKey} * @since 3.1.1 diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java index 5e3e29797..c7ca4205b 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java @@ -3,7 +3,6 @@ package cn.hutool.crypto; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.StrUtil; -import org.bouncycastle.asn1.sec.ECPrivateKey; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemObjectGenerator; import org.bouncycastle.util.io.pem.PemReader; @@ -134,14 +133,17 @@ public class PemUtil { } /** - * 读取OpenSSL生成的ANS1格式的Pem私钥文件 + * 读取OpenSSL生成的ANS1格式的Pem私钥文件,必须为PKCS#1格式 * * @param keyStream 私钥pem流 * @return {@link PrivateKey} */ public static PrivateKey readSm2PemPrivateKey(InputStream keyStream) { - final ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(readPem(keyStream)); - return ECKeyUtil.toSm2PrivateKey(ecPrivateKey); + try{ + return KeyUtil.generatePrivateKey("sm2", ECKeyUtil.createOpenSSHPrivateKeySpec(readPem(keyStream))); + } finally { + IoUtil.close(keyStream); + } } /** diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java index 2f8d61b7f..2bc3a2236 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/SmUtil.java @@ -14,6 +14,8 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.gm.GMNamedCurves; import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECPrivateKeyParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.signers.StandardDSAEncoding; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; @@ -22,11 +24,20 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; +import java.security.PrivateKey; +import java.security.PublicKey; /** * SM国密算法工具类
* 此工具类依赖org.bouncycastle:bcprov-jdk15to18 * + *

封装包括:

+ *
    + *
  • SM2 椭圆曲线非对称加密和签名
  • + *
  • SM3 杂凑算法
  • + *
  • SM4 对称加密
  • + *
+ * * @author looly * @since 4.3.2 */ @@ -74,14 +85,42 @@ public class SmUtil { * 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做加密或者解密 * - * @param privateKey 私钥 - * @param publicKey 公钥 + * @param privateKey 私钥,必须使用PKCS#8规范 + * @param publicKey 公钥,必须使用X509规范 * @return {@link SM2} */ public static SM2 sm2(byte[] privateKey, byte[] publicKey) { return new SM2(privateKey, publicKey); } + /** + * 创建SM2算法对象
+ * 私钥和公钥同时为空时生成一对新的私钥和公钥
+ * 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做加密或者解密 + * + * @param privateKey 私钥 + * @param publicKey 公钥 + * @return {@link SM2} + * @since 5.5.9 + */ + public static SM2 sm2(PrivateKey privateKey, PublicKey publicKey) { + return new SM2(privateKey, publicKey); + } + + /** + * 创建SM2算法对象
+ * 私钥和公钥同时为空时生成一对新的私钥和公钥
+ * 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做加密或者解密 + * + * @param privateKeyParams 私钥参数 + * @param publicKeyParams 公钥参数 + * @return {@link SM2} + * @since 5.5.9 + */ + public static SM2 sm2(ECPrivateKeyParameters privateKeyParams, ECPublicKeyParameters publicKeyParams) { + return new SM2(privateKeyParams, publicKeyParams); + } + /** * SM3加密
* 例:
@@ -192,8 +231,7 @@ public class SmUtil { } /** - * BC的SM3withSM2签名得到的结果的rs是asn1格式的,这个方法转化成直接拼接r||s
- * 来自:https://blog.csdn.net/pridas/article/details/86118774 + * BC的SM3withSM2签名得到的结果的rs是asn1格式的,这个方法转化成直接拼接r||s * * @param rsDer rs in asn1 format * @return sign result in plain byte array @@ -214,8 +252,7 @@ public class SmUtil { } /** - * BC的SM3withSM2验签需要的rs是asn1格式的,这个方法将直接拼接r||s的字节数组转化成asn1格式
- * 来自:https://blog.csdn.net/pridas/article/details/86118774 + * BC的SM3withSM2验签需要的rs是asn1格式的,这个方法将直接拼接r||s的字节数组转化成asn1格式 * * @param sign in plain byte array * @return rs result in asn1 format diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java index ad4c3cf78..48d05370f 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java @@ -4,7 +4,7 @@ import cn.hutool.core.lang.Assert; import cn.hutool.core.util.HexUtil; import cn.hutool.crypto.BCUtil; import cn.hutool.crypto.CryptoException; -import cn.hutool.crypto.KeyUtil; +import cn.hutool.crypto.ECKeyUtil; import cn.hutool.crypto.SecureUtil; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; @@ -74,13 +74,13 @@ public class SM2 extends AbstractAsymmetricCrypto { * 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做加密或者解密 * - * @param privateKey 私钥,必须使用PKCS#8规范 - * @param publicKey 公钥,必须使用X509规范 + * @param privateKey 私钥,可以使用PKCS#8、D值或PKCS#1规范 + * @param publicKey 公钥,可以使用X509、Q值或PKCS#1规范 */ public SM2(byte[] privateKey, byte[] publicKey) { - this(// - KeyUtil.generatePrivateKey(ALGORITHM_SM2, privateKey), // - KeyUtil.generatePublicKey(ALGORITHM_SM2, publicKey)// + this( + ECKeyUtil.decodePrivateKeyParams(privateKey), + ECKeyUtil.decodePublicKeyParams(publicKey) ); } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/digest/SM3.java b/hutool-crypto/src/main/java/cn/hutool/crypto/digest/SM3.java index 08f9c76a7..2b6b2afe5 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/digest/SM3.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/digest/SM3.java @@ -1,7 +1,7 @@ package cn.hutool.crypto.digest; /** - * SM3算法 + * SM3杂凑算法 * * @author looly * @since 4.6.8 diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java index 637c09c6f..f71d74f15 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/PemUtilTest.java @@ -1,11 +1,14 @@ package cn.hutool.crypto.test; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.resource.ResourceUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.PemUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.RSA; import cn.hutool.crypto.asymmetric.SM2; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import java.nio.charset.StandardCharsets; @@ -58,4 +61,20 @@ public class PemUtilTest { // 64位签名 Assert.assertEquals(64, sign.length); } + + @Test + @Ignore + public void readECPrivateKeyTest2() { + // https://gitee.com/loolly/hutool/issues/I37Z75 + byte[] d = PemUtil.readPem(FileUtil.getInputStream("d:/test/keys/priv.key")); + byte[] publicKey = PemUtil.readPem(FileUtil.getInputStream("d:/test/keys/pub.key")); + + SM2 sm2 = new SM2(d, publicKey); + sm2.usePlainEncoding(); + + String content = "我是Hanley."; + byte[] sign = sm2.sign(StrUtil.utf8Bytes(content)); + boolean verify = sm2.verify(StrUtil.utf8Bytes(content), sign); + Assert.assertTrue(verify); + } } diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java index 5399629cb..ffb5e1dbc 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java @@ -12,7 +12,7 @@ import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.SM2; import org.bouncycastle.crypto.engines.SM2Engine; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec; import org.junit.Assert; import org.junit.Test; @@ -136,7 +136,7 @@ public class SM2Test { //签名值 String signHex = "2881346e038d2ed706ccdd025f2b1dafa7377d5cf090134b98756fafe084dddbcdba0ab00b5348ed48025195af3f1dda29e819bb66aa9d4d088050ff148482a1"; - final SM2 sm2 = new SM2(null, ECKeyUtil.toSm2PublicParams(publicKeyHex)); + final SM2 sm2 = new SM2(null, publicKeyHex); sm2.usePlainEncoding(); boolean verify = sm2.verify(dataBytes, HexUtil.decodeHex(signHex)); @@ -251,10 +251,7 @@ public class SM2Test { String data = "123456"; - final ECPublicKeyParameters ecPublicKeyParameters = ECKeyUtil.toSm2PublicParams(q); - final ECPrivateKeyParameters ecPrivateKeyParameters = ECKeyUtil.toSm2PrivateParams(d); - - final SM2 sm2 = new SM2(ecPrivateKeyParameters, ecPublicKeyParameters); + final SM2 sm2 = new SM2(d, q); sm2.setMode(SM2Engine.Mode.C1C2C3); final String encryptHex = sm2.encryptHex(data, KeyType.PublicKey); final String decryptStr = sm2.decryptStr(encryptHex, KeyType.PrivateKey); @@ -277,8 +274,41 @@ public class SM2Test { } @Test - public void test(){ - String priKey = "MHcCAQEEIE29XqAFV/rkJbnJzCoQRJLTeAHG2TR0h9ZCWag0+ZMEoAoGCCqBHM9VAYItoUQDQgAESkOzNigIsH5ehFvr9yQNQ66genyOrm+Q4umCA4aWXPeRzmcTAWSlTineiReTFN2lqor2xaulT8u3a4w3AM/F6A=="; + public void getPublicKeyByPrivateKeyTest(){ + // issue#I38SDP,openSSL生成的PKCS#1格式私钥 + String priKey = "MHcCAQEEIE29XqAFV/rkJbnJzCoQRJLTeAHG2TR0h9ZCWag0+ZMEoAoGCCqBHM9VAYItoUQDQgAESkOzNigIsH5ehFvr9y" + + "QNQ66genyOrm+Q4umCA4aWXPeRzmcTAWSlTineiReTFN2lqor2xaulT8u3a4w3AM/F6A=="; + + PrivateKey privateKey = KeyUtil.generatePrivateKey("sm2", new OpenSSHPrivateKeySpec(SecureUtil.decode(priKey))); + final ECPrivateKeyParameters privateKeyParameters = ECKeyUtil.toPrivateParams(privateKey); + + final SM2 sm2 = new SM2(privateKeyParameters, ECKeyUtil.getPublicParams(privateKeyParameters)); + + String src = "Sm2Test"; + byte[] data = sm2.encrypt(src, KeyType.PublicKey); + byte[] sign = sm2.sign(src.getBytes(StandardCharsets.UTF_8)); + + Assert.assertTrue(sm2.verify( src.getBytes(StandardCharsets.UTF_8), sign)); + + byte[] dec = sm2.decrypt(data, KeyType.PrivateKey); + Assert.assertArrayEquals(dec, src.getBytes(StandardCharsets.UTF_8)); + } + + @Test + public void readPublicKeyTest(){ + String priKey = "MHcCAQEEIE29XqAFV/rkJbnJzCoQRJLTeAHG2TR0h9ZCWag0+ZMEoAoGCCqBHM9VAYItoUQDQgAESkOzNigIsH5ehFvr9y" + + "QNQ66genyOrm+Q4umCA4aWXPeRzmcTAWSlTineiReTFN2lqor2xaulT8u3a4w3AM/F6A=="; String pubKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAESkOzNigIsH5ehFvr9yQNQ66genyOrm+Q4umCA4aWXPeRzmcTAWSlTineiReTFN2lqor2xaulT8u3a4w3AM/F6A=="; + + SM2 sm2 = SmUtil.sm2(priKey, pubKey); + + String src = "Sm2Test中文"; + byte[] data = sm2.encrypt(src, KeyType.PublicKey); + byte[] sign = sm2.sign(src.getBytes(StandardCharsets.UTF_8)); + + Assert.assertTrue(sm2.verify( src.getBytes(StandardCharsets.UTF_8), sign)); + + byte[] dec = sm2.decrypt(data, KeyType.PrivateKey); + Assert.assertArrayEquals(dec, src.getBytes(StandardCharsets.UTF_8)); } } From e3c1852c4d2c83c52a40c8994da868a0981ae733 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 26 Feb 2021 23:18:05 +0800 Subject: [PATCH 23/47] fix code --- .../main/java/cn/hutool/db/sql/Condition.java | 8 +++- .../java/cn/hutool/db/sql/ConditionTest.java | 6 +++ .../main/java/cn/hutool/extra/ftp/Ftp.java | 44 ++++++++++--------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/hutool-db/src/main/java/cn/hutool/db/sql/Condition.java b/hutool-db/src/main/java/cn/hutool/db/sql/Condition.java index 8cea8d6c9..e5ecb0fc7 100644 --- a/hutool-db/src/main/java/cn/hutool/db/sql/Condition.java +++ b/hutool-db/src/main/java/cn/hutool/db/sql/Condition.java @@ -473,8 +473,9 @@ public class Condition extends CloneSupport { final String firstPart = strs.get(0).trim().toUpperCase(); if (OPERATORS.contains(firstPart)) { this.operator = firstPart; - // 比较符号后跟大部分为数字,此处做转换 - this.value = tryToNumber(strs.get(1)); + // 比较符号后跟大部分为数字,此处做转换(IN不做转换) + final String valuePart = strs.get(1); + this.value = isOperatorIn() ? valuePart : tryToNumber(valuePart); return; } @@ -537,6 +538,9 @@ public class Condition extends CloneSupport { */ private static Object tryToNumber(String value){ value = StrUtil.trim(value); + if(false == NumberUtil.isNumber(value)){ + return value; + } try{ return NumberUtil.parseNumber(value); } catch (Exception ignore){ diff --git a/hutool-db/src/test/java/cn/hutool/db/sql/ConditionTest.java b/hutool-db/src/test/java/cn/hutool/db/sql/ConditionTest.java index c3078485d..13bbc6b05 100644 --- a/hutool-db/src/test/java/cn/hutool/db/sql/ConditionTest.java +++ b/hutool-db/src/test/java/cn/hutool/db/sql/ConditionTest.java @@ -60,4 +60,10 @@ public class ConditionTest { // issue I38LTM Assert.assertSame(Long.class, age.getValue().getClass()); } + + @Test + public void parseInTest(){ + final Condition age = Condition.parse("age", "in 1,2,3"); + Assert.assertEquals("age IN (?,?,?)", age.toString()); + } } diff --git a/hutool-extra/src/main/java/cn/hutool/extra/ftp/Ftp.java b/hutool-extra/src/main/java/cn/hutool/extra/ftp/Ftp.java index 60f8e99b1..1f49f2ebd 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/ftp/Ftp.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/ftp/Ftp.java @@ -105,12 +105,14 @@ public class Ftp extends AbstractFtp { /** * 构造 * - * @param host 域名或IP - * @param port 端口 - * @param user 用户名 - * @param password 密码 - * @param charset 编码 - * @param mode 模式 + * @param host 域名或IP + * @param port 端口 + * @param user 用户名 + * @param password 密码 + * @param charset 编码 + * @param serverLanguageCode 服务器语言 + * @param systemKey 系统关键字 + * @param mode 模式 */ public Ftp(String host, int port, String user, String password, Charset charset, String serverLanguageCode, String systemKey, FtpMode mode) { this(new FtpConfig(host, port, user, password, charset, serverLanguageCode, systemKey), mode); @@ -338,14 +340,14 @@ public class Ftp extends AbstractFtp { * * @param path 目录,如果目录不存在,抛出异常 * @return 文件或目录列表 - * @throws FtpException 路径不存在 + * @throws FtpException 路径不存在 * @throws IORuntimeException IO异常 */ - public FTPFile[] lsFiles(String path) throws FtpException, IORuntimeException{ + public FTPFile[] lsFiles(String path) throws FtpException, IORuntimeException { String pwd = null; if (StrUtil.isNotBlank(path)) { pwd = pwd(); - if(false == cd(path)){ + if (false == cd(path)) { throw new FtpException("Change dir to [{}] error, maybe path not exist!", path); } } @@ -364,7 +366,7 @@ public class Ftp extends AbstractFtp { } @Override - public boolean mkdir(String dir) throws IORuntimeException{ + public boolean mkdir(String dir) throws IORuntimeException { try { return this.client.makeDirectory(dir); } catch (IOException e) { @@ -379,7 +381,7 @@ public class Ftp extends AbstractFtp { * @return 状态int,服务端不同,返回不同 * @since 5.4.3 */ - public int stat(String path) throws IORuntimeException{ + public int stat(String path) throws IORuntimeException { try { return this.client.stat(path); } catch (IOException e) { @@ -394,7 +396,7 @@ public class Ftp extends AbstractFtp { * @return 是否存在 * @throws IORuntimeException IO异常 */ - public boolean existFile(String path) throws IORuntimeException{ + public boolean existFile(String path) throws IORuntimeException { FTPFile[] ftpFileArr; try { ftpFileArr = client.listFiles(path); @@ -405,11 +407,11 @@ public class Ftp extends AbstractFtp { } @Override - public boolean delFile(String path) throws IORuntimeException{ + public boolean delFile(String path) throws IORuntimeException { final String pwd = pwd(); final String fileName = FileUtil.getName(path); final String dir = StrUtil.removeSuffix(path, fileName); - if(false == cd(dir)){ + if (false == cd(dir)) { throw new FtpException("Change dir to [{}] error, maybe dir not exist!", path); } @@ -426,7 +428,7 @@ public class Ftp extends AbstractFtp { } @Override - public boolean delDir(String dirPath) throws IORuntimeException{ + public boolean delDir(String dirPath) throws IORuntimeException { FTPFile[] dirs; try { dirs = client.listFiles(dirPath); @@ -490,7 +492,7 @@ public class Ftp extends AbstractFtp { * @return 是否上传成功 * @throws IORuntimeException IO异常 */ - public boolean upload(String path, String fileName, File file) throws IORuntimeException{ + public boolean upload(String path, String fileName, File file) throws IORuntimeException { try (InputStream in = FileUtil.getInputStream(file)) { return upload(path, fileName, in); } catch (IOException e) { @@ -513,7 +515,7 @@ public class Ftp extends AbstractFtp { * @return 是否上传成功 * @throws IORuntimeException IO异常 */ - public boolean upload(String path, String fileName, InputStream fileStream) throws IORuntimeException{ + public boolean upload(String path, String fileName, InputStream fileStream) throws IORuntimeException { try { client.setFileType(FTPClient.BINARY_FILE_TYPE); } catch (IOException e) { @@ -594,7 +596,7 @@ public class Ftp extends AbstractFtp { * @param outFile 输出文件或目录 * @throws IORuntimeException IO异常 */ - public void download(String path, String fileName, File outFile) throws IORuntimeException{ + public void download(String path, String fileName, File outFile) throws IORuntimeException { if (outFile.isDirectory()) { outFile = new File(outFile, fileName); } @@ -626,16 +628,16 @@ public class Ftp extends AbstractFtp { * @param fileName 文件名 * @param out 输出位置 * @param fileNameCharset 文件名编码 - * @since 5.5.7 * @throws IORuntimeException IO异常 + * @since 5.5.7 */ - public void download(String path, String fileName, OutputStream out, Charset fileNameCharset) throws IORuntimeException{ + public void download(String path, String fileName, OutputStream out, Charset fileNameCharset) throws IORuntimeException { String pwd = null; if (this.backToPwd) { pwd = pwd(); } - if(false == cd(path)){ + if (false == cd(path)) { throw new FtpException("Change dir to [{}] error, maybe dir not exist!", path); } From f8cd7a97c7e53fcf8844a244e1446fe7420b41c6 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 26 Feb 2021 23:20:34 +0800 Subject: [PATCH 24/47] release 5.5.9 --- hutool-all/pom.xml | 2 +- hutool-aop/pom.xml | 2 +- hutool-bloomFilter/pom.xml | 2 +- hutool-bom/pom.xml | 2 +- hutool-cache/pom.xml | 2 +- hutool-captcha/pom.xml | 2 +- hutool-core/pom.xml | 2 +- hutool-cron/pom.xml | 2 +- hutool-crypto/pom.xml | 2 +- hutool-db/pom.xml | 2 +- hutool-dfa/pom.xml | 2 +- hutool-extra/pom.xml | 2 +- hutool-http/pom.xml | 2 +- hutool-json/pom.xml | 2 +- hutool-log/pom.xml | 2 +- hutool-poi/pom.xml | 2 +- hutool-script/pom.xml | 2 +- hutool-setting/pom.xml | 2 +- hutool-socket/pom.xml | 2 +- hutool-system/pom.xml | 2 +- pom.xml | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/hutool-all/pom.xml b/hutool-all/pom.xml index 3ed397d87..b826ddc5b 100644 --- a/hutool-all/pom.xml +++ b/hutool-all/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-all diff --git a/hutool-aop/pom.xml b/hutool-aop/pom.xml index 37b59ae21..baf6303d5 100644 --- a/hutool-aop/pom.xml +++ b/hutool-aop/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-aop diff --git a/hutool-bloomFilter/pom.xml b/hutool-bloomFilter/pom.xml index 29336ff98..51c151480 100644 --- a/hutool-bloomFilter/pom.xml +++ b/hutool-bloomFilter/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-bloomFilter diff --git a/hutool-bom/pom.xml b/hutool-bom/pom.xml index 2a6cf622f..356e31a57 100644 --- a/hutool-bom/pom.xml +++ b/hutool-bom/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-bom diff --git a/hutool-cache/pom.xml b/hutool-cache/pom.xml index c8fff0f54..f07ded003 100644 --- a/hutool-cache/pom.xml +++ b/hutool-cache/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-cache diff --git a/hutool-captcha/pom.xml b/hutool-captcha/pom.xml index 0cd5e8990..ad77d4b0c 100644 --- a/hutool-captcha/pom.xml +++ b/hutool-captcha/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-captcha diff --git a/hutool-core/pom.xml b/hutool-core/pom.xml index c00ba74ab..1e5d500f7 100644 --- a/hutool-core/pom.xml +++ b/hutool-core/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-core diff --git a/hutool-cron/pom.xml b/hutool-cron/pom.xml index a25e3f0d0..e61a55671 100644 --- a/hutool-cron/pom.xml +++ b/hutool-cron/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-cron diff --git a/hutool-crypto/pom.xml b/hutool-crypto/pom.xml index 7a27c4acd..fbf01b771 100644 --- a/hutool-crypto/pom.xml +++ b/hutool-crypto/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-crypto diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index c3305e1d1..720cd231a 100644 --- a/hutool-db/pom.xml +++ b/hutool-db/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-db diff --git a/hutool-dfa/pom.xml b/hutool-dfa/pom.xml index 21db2a5cf..d152f0237 100644 --- a/hutool-dfa/pom.xml +++ b/hutool-dfa/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-dfa diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index 1a36f2aa3..883f9c15f 100644 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-extra diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml index e91849d20..f565cd05b 100644 --- a/hutool-http/pom.xml +++ b/hutool-http/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-http diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml index d75b09bc1..6c95d99cd 100644 --- a/hutool-json/pom.xml +++ b/hutool-json/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-json diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index 3489b3909..a545286bb 100644 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-log diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index 9afc07582..423f6c3f2 100644 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-poi diff --git a/hutool-script/pom.xml b/hutool-script/pom.xml index 685bc4c38..a4b954e17 100644 --- a/hutool-script/pom.xml +++ b/hutool-script/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-script diff --git a/hutool-setting/pom.xml b/hutool-setting/pom.xml index 6a8b96b38..0aebea98e 100644 --- a/hutool-setting/pom.xml +++ b/hutool-setting/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-setting diff --git a/hutool-socket/pom.xml b/hutool-socket/pom.xml index 0f02963e1..a7d841cc1 100644 --- a/hutool-socket/pom.xml +++ b/hutool-socket/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-socket diff --git a/hutool-system/pom.xml b/hutool-system/pom.xml index 50c578641..b504f6754 100644 --- a/hutool-system/pom.xml +++ b/hutool-system/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool-system diff --git a/pom.xml b/pom.xml index 63407a488..40967404e 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 5.5.9-SNAPSHOT + 5.5.9 hutool Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。 https://github.com/looly/hutool From 5975da73c21e1cab56d89de96096a6589327c221 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 26 Feb 2021 23:31:37 +0800 Subject: [PATCH 25/47] prepare 5.6.0 --- README-EN.md | 8 ++++---- README.md | 8 ++++---- bin/version.txt | 2 +- docs/js/version.js | 2 +- hutool-all/pom.xml | 2 +- hutool-aop/pom.xml | 2 +- hutool-bloomFilter/pom.xml | 2 +- hutool-bom/pom.xml | 2 +- hutool-cache/pom.xml | 2 +- hutool-captcha/pom.xml | 2 +- hutool-core/pom.xml | 2 +- hutool-cron/pom.xml | 2 +- hutool-crypto/pom.xml | 2 +- hutool-db/pom.xml | 2 +- hutool-dfa/pom.xml | 2 +- hutool-extra/pom.xml | 2 +- hutool-http/pom.xml | 2 +- hutool-json/pom.xml | 2 +- hutool-log/pom.xml | 2 +- hutool-poi/pom.xml | 2 +- hutool-script/pom.xml | 2 +- hutool-setting/pom.xml | 2 +- hutool-socket/pom.xml | 2 +- hutool-system/pom.xml | 2 +- pom.xml | 2 +- 25 files changed, 31 insertions(+), 31 deletions(-) diff --git a/README-EN.md b/README-EN.md index 275b8ae58..b5961c350 100644 --- a/README-EN.md +++ b/README-EN.md @@ -125,19 +125,19 @@ Each module can be introduced individually, or all modules can be introduced by cn.hutool hutool-all - 5.5.9 + 5.6.0 ``` ### Gradle ``` -compile 'cn.hutool:hutool-all:5.5.9' +compile 'cn.hutool:hutool-all:5.6.0' ``` ## Download -- [Maven1](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.5.9/) -- [Maven2](http://repo2.maven.org/maven2/cn/hutool/hutool-all/5.5.9/) +- [Maven1](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.6.0/) +- [Maven2](http://repo2.maven.org/maven2/cn/hutool/hutool-all/5.6.0/) > note: > Hutool 5.x supports JDK8+ and is not tested on Android platforms, and cannot guarantee that all tool classes or tool methods are available. diff --git a/README.md b/README.md index 7ee63ae09..340d51b97 100644 --- a/README.md +++ b/README.md @@ -123,21 +123,21 @@ Hutool的存在就是为了减少代码搜索成本,避免网络上参差不 cn.hutool hutool-all - 5.5.9 + 5.6.0 ``` ### Gradle ``` -compile 'cn.hutool:hutool-all:5.5.9' +compile 'cn.hutool:hutool-all:5.6.0' ``` ### 非Maven项目 点击以下任一链接,下载`hutool-all-X.X.X.jar`即可: -- [Maven中央库1](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.5.9/) -- [Maven中央库2](http://repo2.maven.org/maven2/cn/hutool/hutool-all/5.5.9/) +- [Maven中央库1](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.6.0/) +- [Maven中央库2](http://repo2.maven.org/maven2/cn/hutool/hutool-all/5.6.0/) > 注意 > Hutool 5.x支持JDK8+,对Android平台没有测试,不能保证所有工具类或工具方法可用。 diff --git a/bin/version.txt b/bin/version.txt index 6e03a7e79..1bc788d3b 100755 --- a/bin/version.txt +++ b/bin/version.txt @@ -1 +1 @@ -5.5.9 +5.6.0 diff --git a/docs/js/version.js b/docs/js/version.js index cc519cbf9..e2713f24d 100644 --- a/docs/js/version.js +++ b/docs/js/version.js @@ -1 +1 @@ -var version = '5.5.9' \ No newline at end of file +var version = '5.6.0' \ No newline at end of file diff --git a/hutool-all/pom.xml b/hutool-all/pom.xml index b826ddc5b..2a9f35ba7 100644 --- a/hutool-all/pom.xml +++ b/hutool-all/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-all diff --git a/hutool-aop/pom.xml b/hutool-aop/pom.xml index baf6303d5..c58830d53 100644 --- a/hutool-aop/pom.xml +++ b/hutool-aop/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-aop diff --git a/hutool-bloomFilter/pom.xml b/hutool-bloomFilter/pom.xml index 51c151480..7489bcdd9 100644 --- a/hutool-bloomFilter/pom.xml +++ b/hutool-bloomFilter/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-bloomFilter diff --git a/hutool-bom/pom.xml b/hutool-bom/pom.xml index 356e31a57..6b25aaef5 100644 --- a/hutool-bom/pom.xml +++ b/hutool-bom/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-bom diff --git a/hutool-cache/pom.xml b/hutool-cache/pom.xml index f07ded003..3283d79d5 100644 --- a/hutool-cache/pom.xml +++ b/hutool-cache/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-cache diff --git a/hutool-captcha/pom.xml b/hutool-captcha/pom.xml index ad77d4b0c..4137dd35e 100644 --- a/hutool-captcha/pom.xml +++ b/hutool-captcha/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-captcha diff --git a/hutool-core/pom.xml b/hutool-core/pom.xml index 1e5d500f7..d21790760 100644 --- a/hutool-core/pom.xml +++ b/hutool-core/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-core diff --git a/hutool-cron/pom.xml b/hutool-cron/pom.xml index e61a55671..2758f06b5 100644 --- a/hutool-cron/pom.xml +++ b/hutool-cron/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-cron diff --git a/hutool-crypto/pom.xml b/hutool-crypto/pom.xml index fbf01b771..b7b268248 100644 --- a/hutool-crypto/pom.xml +++ b/hutool-crypto/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-crypto diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index 720cd231a..f875846ce 100644 --- a/hutool-db/pom.xml +++ b/hutool-db/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-db diff --git a/hutool-dfa/pom.xml b/hutool-dfa/pom.xml index d152f0237..8ae0ee08a 100644 --- a/hutool-dfa/pom.xml +++ b/hutool-dfa/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-dfa diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index 883f9c15f..7b59cba47 100644 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-extra diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml index f565cd05b..cf454b4e7 100644 --- a/hutool-http/pom.xml +++ b/hutool-http/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-http diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml index 6c95d99cd..14f776a5e 100644 --- a/hutool-json/pom.xml +++ b/hutool-json/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-json diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index a545286bb..3d1a2bae4 100644 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-log diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index 423f6c3f2..d5dd22f65 100644 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-poi diff --git a/hutool-script/pom.xml b/hutool-script/pom.xml index a4b954e17..c78f82cef 100644 --- a/hutool-script/pom.xml +++ b/hutool-script/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-script diff --git a/hutool-setting/pom.xml b/hutool-setting/pom.xml index 0aebea98e..022741d8f 100644 --- a/hutool-setting/pom.xml +++ b/hutool-setting/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-setting diff --git a/hutool-socket/pom.xml b/hutool-socket/pom.xml index a7d841cc1..a48994d8e 100644 --- a/hutool-socket/pom.xml +++ b/hutool-socket/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-socket diff --git a/hutool-system/pom.xml b/hutool-system/pom.xml index b504f6754..114bbf31f 100644 --- a/hutool-system/pom.xml +++ b/hutool-system/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool-system diff --git a/pom.xml b/pom.xml index 40967404e..37e508adb 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 5.5.9 + 5.6.0-SNAPSHOT hutool Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。 https://github.com/looly/hutool From dfbbd7c6c114034be359142d42a1feb3a8298863 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 26 Feb 2021 23:32:04 +0800 Subject: [PATCH 26/47] prepare 5.6.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a29c00be7..44aa2aba8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ ------------------------------------------------------------------------------------------------------------- +# 5.6.0 (2021-02-27) + +### 新特性 + +### Bug修复 + +------------------------------------------------------------------------------------------------------------- + # 5.5.9 (2021-02-26) ### 新特性 From b285db71cd33aec297c4a18d1e60c339d84915c2 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 27 Feb 2021 12:51:08 +0800 Subject: [PATCH 27/47] compated to poi 5.x --- CHANGELOG.md | 1 + .../cn/hutool/poi/excel/cell/CellUtil.java | 18 ++++++++---------- .../cn/hutool/poi/excel/cell/NullCell.java | 2 -- .../cn/hutool/poi/excel/sax/ExcelSaxUtil.java | 3 +-- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44aa2aba8..05066f2e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ # 5.6.0 (2021-02-27) ### 新特性 +* 【poi 】 重要:不再兼容POI-3.x,增加兼容POI-5.x(issue#I35J6B@Gitee) ### Bug修复 diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/CellUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/CellUtil.java index ef46e87fc..0179caea3 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/CellUtil.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/CellUtil.java @@ -7,7 +7,6 @@ import cn.hutool.poi.excel.ExcelDateUtil; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.StyleSet; import cn.hutool.poi.excel.editors.TrimEditor; - import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellType; @@ -39,7 +38,6 @@ import java.util.Date; * @author looly * @since 4.0.7 */ -@SuppressWarnings("deprecation") public class CellUtil { /** @@ -64,7 +62,7 @@ public class CellUtil { if (null == cell) { return null; } - return getCellValue(cell, cell.getCellTypeEnum(), isTrimCellValue); + return getCellValue(cell, cell.getCellType(), isTrimCellValue); } /** @@ -107,14 +105,14 @@ public class CellUtil { return null == cellEditor ? null : cellEditor.edit(cell, null); } if (null == cellType) { - cellType = cell.getCellTypeEnum(); + cellType = cell.getCellType(); } // 尝试获取合并单元格,如果是合并单元格,则重新获取单元格类型 final Cell mergedCell = getMergedRegionCell(cell); if (mergedCell != cell) { cell = mergedCell; - cellType = cell.getCellTypeEnum(); + cellType = cell.getCellType(); } Object value; @@ -127,7 +125,7 @@ public class CellUtil { break; case FORMULA: // 遇到公式时查找公式结果类型 - value = getCellValue(cell, cell.getCachedFormulaResultTypeEnum(), cellEditor); + value = getCellValue(cell, cell.getCachedFormulaResultType(), cellEditor); break; case BLANK: value = StrUtil.EMPTY; @@ -332,10 +330,10 @@ public class CellUtil { ); if (null != cellStyle) { - RegionUtil.setBorderTop(cellStyle.getBorderTopEnum(), cellRangeAddress, sheet); - RegionUtil.setBorderRight(cellStyle.getBorderRightEnum(), cellRangeAddress, sheet); - RegionUtil.setBorderBottom(cellStyle.getBorderBottomEnum(), cellRangeAddress, sheet); - RegionUtil.setBorderLeft(cellStyle.getBorderLeftEnum(), cellRangeAddress, sheet); + RegionUtil.setBorderTop(cellStyle.getBorderTop(), cellRangeAddress, sheet); + RegionUtil.setBorderRight(cellStyle.getBorderRight(), cellRangeAddress, sheet); + RegionUtil.setBorderBottom(cellStyle.getBorderBottom(), cellRangeAddress, sheet); + RegionUtil.setBorderLeft(cellStyle.getBorderLeft(), cellRangeAddress, sheet); } return sheet.addMergedRegion(cellRangeAddress); } diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/NullCell.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/NullCell.java index 23ec37e19..87b867bec 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/NullCell.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/NullCell.java @@ -73,7 +73,6 @@ public class NullCell implements Cell { return null; } - @Override public CellType getCellTypeEnum() { return null; } @@ -83,7 +82,6 @@ public class NullCell implements Cell { return null; } - @Override public CellType getCachedFormulaResultTypeEnum() { return null; } diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java index bd2d25849..66b600883 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java @@ -85,8 +85,7 @@ public class ExcelSaxUtil { case SSTINDEX: try { final int index = Integer.parseInt(value); - //noinspection deprecation - result = new XSSFRichTextString(sharedStringsTable.getEntryAt(index)).getString(); + result = sharedStringsTable.getItemAt(index).getString(); } catch (NumberFormatException e) { result = value; } From 569e65f9dcb241df850925f8871e78df2c2d3ebf Mon Sep 17 00:00:00 2001 From: cal101 Date: Sat, 27 Feb 2021 09:43:12 +0000 Subject: [PATCH 28/47] [cleanup] erefactor/EclipseJdt - Remove redundant super() call in constructor EclipseJdt cleanup 'RemoveUnnecessarySuperCall' applied by erefactor. For EclipseJdt see https://www.eclipse.org/eclipse/news/4.18/jdt.php For erefactor see https://github.com/cal101/erefactor --- .../src/main/java/cn/hutool/core/builder/CompareToBuilder.java | 1 - .../java/cn/hutool/core/comparator/ComparableComparator.java | 1 - .../main/java/cn/hutool/core/date/format/FastDatePrinter.java | 3 --- .../src/main/java/cn/hutool/core/io/FastStringWriter.java | 1 - .../java/cn/hutool/core/io/resource/MultiFileResource.java | 2 -- hutool-core/src/main/java/cn/hutool/core/lang/Holder.java | 1 - .../src/main/java/cn/hutool/core/lang/mutable/MutableBool.java | 3 --- .../src/main/java/cn/hutool/core/lang/mutable/MutableByte.java | 3 --- .../main/java/cn/hutool/core/lang/mutable/MutableDouble.java | 3 --- .../main/java/cn/hutool/core/lang/mutable/MutableFloat.java | 3 --- .../src/main/java/cn/hutool/core/lang/mutable/MutableInt.java | 3 --- .../src/main/java/cn/hutool/core/lang/mutable/MutableLong.java | 3 --- .../src/main/java/cn/hutool/core/lang/mutable/MutableObj.java | 2 -- .../main/java/cn/hutool/core/lang/mutable/MutableShort.java | 3 --- hutool-core/src/main/java/cn/hutool/core/lang/tree/Tree.java | 1 - hutool-db/src/main/java/cn/hutool/db/Entity.java | 2 -- .../main/java/cn/hutool/extra/mail/UserPassAuthenticator.java | 1 - hutool-extra/src/main/java/cn/hutool/extra/ssh/Connector.java | 1 - .../src/test/java/cn/hutool/extra/expression/AviatorTest.java | 1 - .../java/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java | 1 - 20 files changed, 39 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/builder/CompareToBuilder.java b/hutool-core/src/main/java/cn/hutool/core/builder/CompareToBuilder.java index de0c6705b..cac51ed60 100644 --- a/hutool-core/src/main/java/cn/hutool/core/builder/CompareToBuilder.java +++ b/hutool-core/src/main/java/cn/hutool/core/builder/CompareToBuilder.java @@ -60,7 +60,6 @@ public class CompareToBuilder implements Builder { * 构造,构造后调用append方法增加比较项,然后调用{@link #toComparison()}获取结果 */ public CompareToBuilder() { - super(); comparison = 0; } diff --git a/hutool-core/src/main/java/cn/hutool/core/comparator/ComparableComparator.java b/hutool-core/src/main/java/cn/hutool/core/comparator/ComparableComparator.java index ba5a4c4fd..7b6b58754 100644 --- a/hutool-core/src/main/java/cn/hutool/core/comparator/ComparableComparator.java +++ b/hutool-core/src/main/java/cn/hutool/core/comparator/ComparableComparator.java @@ -21,7 +21,6 @@ public class ComparableComparator> implements Co * 构造 */ public ComparableComparator() { - super(); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/date/format/FastDatePrinter.java b/hutool-core/src/main/java/cn/hutool/core/date/format/FastDatePrinter.java index ccb4f009c..43108471b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/format/FastDatePrinter.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/format/FastDatePrinter.java @@ -694,7 +694,6 @@ public class FastDatePrinter extends AbstractDateBasic implements DatePrinter { * */ UnpaddedMonthField() { - super(); } /** @@ -833,7 +832,6 @@ public class FastDatePrinter extends AbstractDateBasic implements DatePrinter { * Constructs an instance of {@code TwoDigitYearField}. */ TwoDigitYearField() { - super(); } /** @@ -873,7 +871,6 @@ public class FastDatePrinter extends AbstractDateBasic implements DatePrinter { * Constructs an instance of {@code TwoDigitMonthField}. */ TwoDigitMonthField() { - super(); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/io/FastStringWriter.java b/hutool-core/src/main/java/cn/hutool/core/io/FastStringWriter.java index e9c751b06..aabdf84fa 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/FastStringWriter.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/FastStringWriter.java @@ -27,7 +27,6 @@ public final class FastStringWriter extends Writer { * @param initialSize 初始容量 */ public FastStringWriter(int initialSize) { - super(); if (initialSize < 0) { initialSize = StrBuilder.DEFAULT_CAPACITY; } diff --git a/hutool-core/src/main/java/cn/hutool/core/io/resource/MultiFileResource.java b/hutool-core/src/main/java/cn/hutool/core/io/resource/MultiFileResource.java index 90d721a2d..457de62e7 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/resource/MultiFileResource.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/resource/MultiFileResource.java @@ -19,7 +19,6 @@ public class MultiFileResource extends MultiResource{ * @param files 文件资源列表 */ public MultiFileResource(Collection files) { - super(); add(files); } @@ -29,7 +28,6 @@ public class MultiFileResource extends MultiResource{ * @param files 文件资源列表 */ public MultiFileResource(File... files) { - super(); add(files); } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Holder.java b/hutool-core/src/main/java/cn/hutool/core/lang/Holder.java index 2f8ff36f2..481882858 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Holder.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Holder.java @@ -30,7 +30,6 @@ public final class Holder extends MutableObj{ * 构造 */ public Holder() { - super(); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableBool.java b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableBool.java index 16556052b..86cdc52e4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableBool.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableBool.java @@ -17,7 +17,6 @@ public class MutableBool implements Comparable, Mutable, S * 构造,默认值0 */ public MutableBool() { - super(); } /** @@ -25,7 +24,6 @@ public class MutableBool implements Comparable, Mutable, S * @param value 值 */ public MutableBool(final boolean value) { - super(); this.value = value; } @@ -35,7 +33,6 @@ public class MutableBool implements Comparable, Mutable, S * @throws NumberFormatException 转为Boolean错误 */ public MutableBool(final String value) throws NumberFormatException { - super(); this.value = Boolean.parseBoolean(value); } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableByte.java b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableByte.java index f9dc2171f..c08381a9c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableByte.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableByte.java @@ -17,7 +17,6 @@ public class MutableByte extends Number implements Comparable, Muta * 构造,默认值0 */ public MutableByte() { - super(); } /** @@ -25,7 +24,6 @@ public class MutableByte extends Number implements Comparable, Muta * @param value 值 */ public MutableByte(final byte value) { - super(); this.value = value; } @@ -43,7 +41,6 @@ public class MutableByte extends Number implements Comparable, Muta * @throws NumberFormatException 转为Byte错误 */ public MutableByte(final String value) throws NumberFormatException { - super(); this.value = Byte.parseByte(value); } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableDouble.java b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableDouble.java index 061803e6e..67dd4ee0c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableDouble.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableDouble.java @@ -17,7 +17,6 @@ public class MutableDouble extends Number implements Comparable, * 构造,默认值0 */ public MutableDouble() { - super(); } /** @@ -25,7 +24,6 @@ public class MutableDouble extends Number implements Comparable, * @param value 值 */ public MutableDouble(final double value) { - super(); this.value = value; } @@ -43,7 +41,6 @@ public class MutableDouble extends Number implements Comparable, * @throws NumberFormatException 数字转换错误 */ public MutableDouble(final String value) throws NumberFormatException { - super(); this.value = Double.parseDouble(value); } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableFloat.java b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableFloat.java index 2253ea64f..40dacdeac 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableFloat.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableFloat.java @@ -17,7 +17,6 @@ public class MutableFloat extends Number implements Comparable, Mu * 构造,默认值0 */ public MutableFloat() { - super(); } /** @@ -25,7 +24,6 @@ public class MutableFloat extends Number implements Comparable, Mu * @param value 值 */ public MutableFloat(final float value) { - super(); this.value = value; } @@ -43,7 +41,6 @@ public class MutableFloat extends Number implements Comparable, Mu * @throws NumberFormatException 数字转换错误 */ public MutableFloat(final String value) throws NumberFormatException { - super(); this.value = Float.parseFloat(value); } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableInt.java b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableInt.java index bca3402fa..b661c00de 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableInt.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableInt.java @@ -17,7 +17,6 @@ public class MutableInt extends Number implements Comparable, Mutabl * 构造,默认值0 */ public MutableInt() { - super(); } /** @@ -25,7 +24,6 @@ public class MutableInt extends Number implements Comparable, Mutabl * @param value 值 */ public MutableInt(final int value) { - super(); this.value = value; } @@ -43,7 +41,6 @@ public class MutableInt extends Number implements Comparable, Mutabl * @throws NumberFormatException 数字转换错误 */ public MutableInt(final String value) throws NumberFormatException { - super(); this.value = Integer.parseInt(value); } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableLong.java b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableLong.java index 1276703b2..add2609f5 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableLong.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableLong.java @@ -17,7 +17,6 @@ public class MutableLong extends Number implements Comparable, Muta * 构造,默认值0 */ public MutableLong() { - super(); } /** @@ -25,7 +24,6 @@ public class MutableLong extends Number implements Comparable, Muta * @param value 值 */ public MutableLong(final long value) { - super(); this.value = value; } @@ -43,7 +41,6 @@ public class MutableLong extends Number implements Comparable, Muta * @throws NumberFormatException 数字转换错误 */ public MutableLong(final String value) throws NumberFormatException { - super(); this.value = Long.parseLong(value); } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableObj.java b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableObj.java index 0c1210291..433ed5dae 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableObj.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableObj.java @@ -17,7 +17,6 @@ public class MutableObj implements Mutable, Serializable { * 构造,空值 */ public MutableObj() { - super(); } /** @@ -26,7 +25,6 @@ public class MutableObj implements Mutable, Serializable { * @param value 值 */ public MutableObj(final T value) { - super(); this.value = value; } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableShort.java b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableShort.java index a5fb165dd..316804432 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableShort.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/mutable/MutableShort.java @@ -17,7 +17,6 @@ public class MutableShort extends Number implements Comparable, Mu * 构造,默认值0 */ public MutableShort() { - super(); } /** @@ -25,7 +24,6 @@ public class MutableShort extends Number implements Comparable, Mu * @param value 值 */ public MutableShort(final short value) { - super(); this.value = value; } @@ -43,7 +41,6 @@ public class MutableShort extends Number implements Comparable, Mu * @throws NumberFormatException 转为Short错误 */ public MutableShort(final String value) throws NumberFormatException { - super(); this.value = Short.parseShort(value); } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/tree/Tree.java b/hutool-core/src/main/java/cn/hutool/core/lang/tree/Tree.java index f5ab41fe4..c33e63873 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/tree/Tree.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/tree/Tree.java @@ -29,7 +29,6 @@ public class Tree extends LinkedHashMap implements Node { * @param treeNodeConfig TreeNode配置 */ public Tree(TreeNodeConfig treeNodeConfig) { - super(); this.treeNodeConfig = ObjectUtil.defaultIfNull( treeNodeConfig, TreeNodeConfig.DEFAULT_CONFIG); } diff --git a/hutool-db/src/main/java/cn/hutool/db/Entity.java b/hutool-db/src/main/java/cn/hutool/db/Entity.java index cf63a3c8e..4a85130e9 100644 --- a/hutool-db/src/main/java/cn/hutool/db/Entity.java +++ b/hutool-db/src/main/java/cn/hutool/db/Entity.java @@ -91,7 +91,6 @@ public class Entity extends Dict { // --------------------------------------------------------------- Constructor start public Entity() { - super(); } /** @@ -101,7 +100,6 @@ public class Entity extends Dict { */ public Entity(String tableName) { - super(); this.tableName = tableName; } diff --git a/hutool-extra/src/main/java/cn/hutool/extra/mail/UserPassAuthenticator.java b/hutool-extra/src/main/java/cn/hutool/extra/mail/UserPassAuthenticator.java index a05161941..4bdf58fc8 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/mail/UserPassAuthenticator.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/mail/UserPassAuthenticator.java @@ -21,7 +21,6 @@ public class UserPassAuthenticator extends Authenticator { * @param pass 密码 */ public UserPassAuthenticator(String user, String pass) { - super(); this.user = user; this.pass = pass; } diff --git a/hutool-extra/src/main/java/cn/hutool/extra/ssh/Connector.java b/hutool-extra/src/main/java/cn/hutool/extra/ssh/Connector.java index a4813db28..157bbd0df 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/ssh/Connector.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/ssh/Connector.java @@ -39,7 +39,6 @@ public class Connector { * @param password 密码 */ public Connector(String host, int port, String user, String password) { - super(); this.host = host; this.port = port; this.user = user; diff --git a/hutool-extra/src/test/java/cn/hutool/extra/expression/AviatorTest.java b/hutool-extra/src/test/java/cn/hutool/extra/expression/AviatorTest.java index 42d964a32..8896ab439 100644 --- a/hutool-extra/src/test/java/cn/hutool/extra/expression/AviatorTest.java +++ b/hutool-extra/src/test/java/cn/hutool/extra/expression/AviatorTest.java @@ -53,7 +53,6 @@ public class AviatorTest { Bar[] bars = new Bar[1]; public Foo(final int i, final float f, final Date date) { - super(); this.i = i; this.f = f; this.date = date; diff --git a/hutool-http/src/main/java/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java b/hutool-http/src/main/java/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java index e1630541b..1723a8011 100644 --- a/hutool-http/src/main/java/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java +++ b/hutool-http/src/main/java/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java @@ -28,7 +28,6 @@ public class CustomProtocolsSSLFactory extends SSLSocketFactory { * @throws NoSuchAlgorithmException NoSuchAlgorithmException */ public CustomProtocolsSSLFactory(String... protocols) throws KeyManagementException, NoSuchAlgorithmException { - super(); this.protocols = protocols; this.base = SSLSocketFactoryBuilder.create().build(); } From 83c30bcfb7d87120261962e8770d22646f4a2006 Mon Sep 17 00:00:00 2001 From: cal101 Date: Sat, 27 Feb 2021 09:54:17 +0000 Subject: [PATCH 29/47] [cleanup] erefactor/EclipseJdt - Remove trailing whitespace - All lines EclipseJdt cleanup 'RemoveAllTrailingWhitespace' applied by erefactor. For EclipseJdt see https://www.eclipse.org/eclipse/news/4.18/jdt.php For erefactor see https://github.com/cal101/erefactor --- .../cn/hutool/bloomfilter/package-info.java | 2 +- .../bloomfilter/BitMapBloomFilterTest.java | 4 +- .../main/java/cn/hutool/cache/CacheUtil.java | 38 +++++++++---------- .../hutool/cache/file/AbstractFileCache.java | 4 +- .../cn/hutool/cache/file/LFUFileCache.java | 2 +- .../cn/hutool/cache/file/LRUFileCache.java | 2 +- .../cn/hutool/cache/file/package-info.java | 2 +- .../java/cn/hutool/cache/impl/CacheObj.java | 22 +++++------ .../hutool/cache/impl/CacheObjIterator.java | 4 +- .../java/cn/hutool/cache/impl/NoCache.java | 6 +-- .../cn/hutool/cache/impl/package-info.java | 2 +- .../java/cn/hutool/cache/package-info.java | 2 +- .../java/cn/hutool/cache/test/CacheTest.java | 26 ++++++------- .../java/cn/hutool/captcha/CircleCaptcha.java | 12 +++--- .../main/java/cn/hutool/captcha/ICaptcha.java | 8 ++-- .../java/cn/hutool/captcha/LineCaptcha.java | 10 ++--- .../java/cn/hutool/captcha/ShearCaptcha.java | 18 ++++----- .../captcha/generator/AbstractGenerator.java | 12 +++--- .../captcha/generator/CodeGenerator.java | 6 +-- .../captcha/generator/MathGenerator.java | 6 +-- 20 files changed, 94 insertions(+), 94 deletions(-) diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/package-info.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/package-info.java index b43515889..1eec3a1a7 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/package-info.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/package-info.java @@ -1,6 +1,6 @@ /** * 布隆过滤,提供一些Hash算法的布隆过滤 - * + * * @author looly * */ diff --git a/hutool-bloomFilter/src/test/java/cn/hutool/bloomfilter/BitMapBloomFilterTest.java b/hutool-bloomFilter/src/test/java/cn/hutool/bloomfilter/BitMapBloomFilterTest.java index 277b424b8..ad104d632 100644 --- a/hutool-bloomFilter/src/test/java/cn/hutool/bloomfilter/BitMapBloomFilterTest.java +++ b/hutool-bloomFilter/src/test/java/cn/hutool/bloomfilter/BitMapBloomFilterTest.java @@ -8,14 +8,14 @@ import cn.hutool.bloomfilter.bitMap.IntMap; import cn.hutool.bloomfilter.bitMap.LongMap; public class BitMapBloomFilterTest { - + @Test public void filterTest() { BitMapBloomFilter filter = new BitMapBloomFilter(10); filter.add("123"); filter.add("abc"); filter.add("ddd"); - + Assert.assertTrue(filter.contains("abc")); Assert.assertTrue(filter.contains("ddd")); Assert.assertTrue(filter.contains("123")); diff --git a/hutool-cache/src/main/java/cn/hutool/cache/CacheUtil.java b/hutool-cache/src/main/java/cn/hutool/cache/CacheUtil.java index 69d76b79b..b9318d91b 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/CacheUtil.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/CacheUtil.java @@ -13,10 +13,10 @@ import cn.hutool.cache.impl.WeakCache; *@since 3.0.1 */ public class CacheUtil { - + /** * 创建FIFO(first in first out) 先进先出缓存. - * + * * @param Key类型 * @param Value类型 * @param capacity 容量 @@ -26,10 +26,10 @@ public class CacheUtil { public static FIFOCache newFIFOCache(int capacity, long timeout){ return new FIFOCache<>(capacity, timeout); } - + /** * 创建FIFO(first in first out) 先进先出缓存. - * + * * @param Key类型 * @param Value类型 * @param capacity 容量 @@ -38,10 +38,10 @@ public class CacheUtil { public static FIFOCache newFIFOCache(int capacity){ return new FIFOCache<>(capacity); } - + /** * 创建LFU(least frequently used) 最少使用率缓存. - * + * * @param Key类型 * @param Value类型 * @param capacity 容量 @@ -51,10 +51,10 @@ public class CacheUtil { public static LFUCache newLFUCache(int capacity, long timeout){ return new LFUCache<>(capacity, timeout); } - + /** * 创建LFU(least frequently used) 最少使用率缓存. - * + * * @param Key类型 * @param Value类型 * @param capacity 容量 @@ -63,11 +63,11 @@ public class CacheUtil { public static LFUCache newLFUCache(int capacity){ return new LFUCache<>(capacity); } - - + + /** * 创建LRU (least recently used)最近最久未使用缓存. - * + * * @param Key类型 * @param Value类型 * @param capacity 容量 @@ -77,10 +77,10 @@ public class CacheUtil { public static LRUCache newLRUCache(int capacity, long timeout){ return new LRUCache<>(capacity, timeout); } - + /** * 创建LRU (least recently used)最近最久未使用缓存. - * + * * @param Key类型 * @param Value类型 * @param capacity 容量 @@ -89,10 +89,10 @@ public class CacheUtil { public static LRUCache newLRUCache(int capacity){ return new LRUCache<>(capacity); } - + /** * 创建定时缓存. - * + * * @param Key类型 * @param Value类型 * @param timeout 过期时长,单位:毫秒 @@ -101,10 +101,10 @@ public class CacheUtil { public static TimedCache newTimedCache(long timeout){ return new TimedCache<>(timeout); } - + /** * 创建弱引用缓存. - * + * * @param Key类型 * @param Value类型 * @param timeout 过期时长,单位:毫秒 @@ -114,10 +114,10 @@ public class CacheUtil { public static WeakCache newWeakCache(long timeout){ return new WeakCache<>(timeout); } - + /** * 创建无缓存实现. - * + * * @param Key类型 * @param Value类型 * @return {@link NoCache} diff --git a/hutool-cache/src/main/java/cn/hutool/cache/file/AbstractFileCache.java b/hutool-cache/src/main/java/cn/hutool/cache/file/AbstractFileCache.java index 4154c51d7..5486d0593 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/file/AbstractFileCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/file/AbstractFileCache.java @@ -23,7 +23,7 @@ public abstract class AbstractFileCache implements Serializable{ protected final long timeout; /** 缓存实现 */ protected final Cache cache; - + /** 已使用缓存空间 */ protected int usedSize; @@ -122,7 +122,7 @@ public abstract class AbstractFileCache implements Serializable{ return bytes; } - + // ---------------------------------------------------------------- protected method start /** * 初始化实现文件缓存的缓存对象 diff --git a/hutool-cache/src/main/java/cn/hutool/cache/file/LFUFileCache.java b/hutool-cache/src/main/java/cn/hutool/cache/file/LFUFileCache.java index d0ea3ea1a..179b517d1 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/file/LFUFileCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/file/LFUFileCache.java @@ -12,7 +12,7 @@ import cn.hutool.cache.impl.LFUCache; */ public class LFUFileCache extends AbstractFileCache{ private static final long serialVersionUID = 1L; - + /** * 构造
* 最大文件大小为缓存容量的一半
diff --git a/hutool-cache/src/main/java/cn/hutool/cache/file/LRUFileCache.java b/hutool-cache/src/main/java/cn/hutool/cache/file/LRUFileCache.java index 042eb99c0..5d0d34f6d 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/file/LRUFileCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/file/LRUFileCache.java @@ -12,7 +12,7 @@ import cn.hutool.cache.impl.LRUCache; */ public class LRUFileCache extends AbstractFileCache{ private static final long serialVersionUID = 1L; - + /** * 构造
* 最大文件大小为缓存容量的一半
diff --git a/hutool-cache/src/main/java/cn/hutool/cache/file/package-info.java b/hutool-cache/src/main/java/cn/hutool/cache/file/package-info.java index 5b39709c4..b08242d69 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/file/package-info.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/file/package-info.java @@ -1,6 +1,6 @@ /** * 提供针对文件的缓存实现 - * + * * @author looly * */ diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/CacheObj.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/CacheObj.java index 97615e623..3f414add1 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/CacheObj.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/CacheObj.java @@ -12,20 +12,20 @@ import java.util.concurrent.atomic.AtomicLong; */ public class CacheObj implements Serializable{ private static final long serialVersionUID = 1L; - + protected final K key; protected final V obj; - + /** 上次访问时间 */ private volatile long lastAccess; /** 访问次数 */ protected AtomicLong accessCount = new AtomicLong(); /** 对象存活时长,0表示永久存活*/ private final long ttl; - + /** * 构造 - * + * * @param key 键 * @param obj 值 * @param ttl 超时时长 @@ -36,10 +36,10 @@ public class CacheObj implements Serializable{ this.ttl = ttl; this.lastAccess = System.currentTimeMillis(); } - + /** * 判断是否过期 - * + * * @return 是否过期 */ boolean isExpired() { @@ -49,10 +49,10 @@ public class CacheObj implements Serializable{ } return false; } - + /** * 获取值 - * + * * @param isUpdateLastAccess 是否更新最后访问时间 * @return 获得对象 * @since 4.0.10 @@ -64,7 +64,7 @@ public class CacheObj implements Serializable{ accessCount.getAndIncrement(); return this.obj; } - + /** * 获取键 * @return 键 @@ -73,7 +73,7 @@ public class CacheObj implements Serializable{ public K getKey() { return this.key; } - + /** * 获取值 * @return 值 @@ -82,7 +82,7 @@ public class CacheObj implements Serializable{ public V getValue() { return this.obj; } - + @Override public String toString() { return "CacheObj [key=" + key + ", obj=" + obj + ", lastAccess=" + lastAccess + ", accessCount=" + accessCount + ", ttl=" + ttl + "]"; diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/CacheObjIterator.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/CacheObjIterator.java index 63238246d..8541cf94c 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/CacheObjIterator.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/CacheObjIterator.java @@ -6,7 +6,7 @@ import java.util.NoSuchElementException; /** * {@link cn.hutool.cache.impl.AbstractCache} 的CacheObj迭代器. - * + * * @author looly * * @param 键类型 @@ -21,7 +21,7 @@ public class CacheObjIterator implements Iterator>, Seriali /** * 构造 - * + * * @param iterator 原{@link Iterator} */ CacheObjIterator(Iterator> iterator) { diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/NoCache.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/NoCache.java index 7814d9679..02b8173e4 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/NoCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/NoCache.java @@ -7,7 +7,7 @@ import java.util.Iterator; /** * 无缓存实现,用于快速关闭缓存 - * + * * @param 键类型 * @param 值类型 * @author Looly,jodd @@ -49,7 +49,7 @@ public class NoCache implements Cache { public V get(K key, boolean isUpdateLastAccess) { return null; } - + @Override public V get(K key, Func0 supplier) { return get(key, true, supplier); @@ -78,7 +78,7 @@ public class NoCache implements Cache { } }; } - + @Override public Iterator> cacheObjIterator() { return null; diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/package-info.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/package-info.java index 0aa247239..698b4d7a3 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/package-info.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/package-info.java @@ -1,6 +1,6 @@ /** * 提供各种缓存实现 - * + * * @author looly * */ diff --git a/hutool-cache/src/main/java/cn/hutool/cache/package-info.java b/hutool-cache/src/main/java/cn/hutool/cache/package-info.java index b8f80eb64..4a3d61aa6 100644 --- a/hutool-cache/src/main/java/cn/hutool/cache/package-info.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/package-info.java @@ -1,6 +1,6 @@ /** * 提供简易的缓存实现,此模块参考了jodd工具中的Cache模块 - * + * * @author looly * */ diff --git a/hutool-cache/src/test/java/cn/hutool/cache/test/CacheTest.java b/hutool-cache/src/test/java/cn/hutool/cache/test/CacheTest.java index d0d0f2e55..1014ca524 100644 --- a/hutool-cache/src/test/java/cn/hutool/cache/test/CacheTest.java +++ b/hutool-cache/src/test/java/cn/hutool/cache/test/CacheTest.java @@ -14,7 +14,7 @@ import org.junit.Test; * */ public class CacheTest { - + @Test public void fifoCacheTest(){ Cache fifoCache = CacheUtil.newFIFOCache(3); @@ -28,22 +28,22 @@ public class CacheTest { fifoCache.put("key2", "value2", DateUnit.SECOND.getMillis() * 3); fifoCache.put("key3", "value3", DateUnit.SECOND.getMillis() * 3); fifoCache.put("key4", "value4", DateUnit.SECOND.getMillis() * 3); - + //由于缓存容量只有3,当加入第四个元素的时候,根据FIFO规则,最先放入的对象将被移除 String value1 = fifoCache.get("key1"); Assert.assertNull(value1); } - + @Test public void lfuCacheTest(){ Cache lfuCache = CacheUtil.newLFUCache(3); lfuCache.put("key1", "value1", DateUnit.SECOND.getMillis() * 3); //使用次数+1 - lfuCache.get("key1"); + lfuCache.get("key1"); lfuCache.put("key2", "value2", DateUnit.SECOND.getMillis() * 3); lfuCache.put("key3", "value3", DateUnit.SECOND.getMillis() * 3); lfuCache.put("key4", "value4", DateUnit.SECOND.getMillis() * 3); - + //由于缓存容量只有3,当加入第四个元素的时候,根据LFU规则,最少使用的将被移除(2,3被移除) String value1 = lfuCache.get("key1"); String value2 = lfuCache.get("key2"); @@ -52,7 +52,7 @@ public class CacheTest { Assert.assertNull(value2); Assert.assertNull(value3); } - + @Test public void lruCacheTest(){ Cache lruCache = CacheUtil.newLRUCache(3); @@ -71,7 +71,7 @@ public class CacheTest { String value2 = lruCache.get("key2"); Assert.assertNull(value2); } - + @Test public void timedCacheTest(){ TimedCache timedCache = CacheUtil.newTimedCache(4); @@ -80,29 +80,29 @@ public class CacheTest { timedCache.put("key2", "value2", DateUnit.SECOND.getMillis() * 5);//5秒过期 timedCache.put("key3", "value3");//默认过期(4毫秒) timedCache.put("key4", "value4", Long.MAX_VALUE);//永不过期 - + //启动定时任务,每5毫秒秒检查一次过期 timedCache.schedulePrune(5); //等待5毫秒 ThreadUtil.sleep(5); - + //5毫秒后由于value2设置了5毫秒过期,因此只有value2被保留下来 String value1 = timedCache.get("key1"); Assert.assertNull(value1); String value2 = timedCache.get("key2"); Assert.assertEquals("value2", value2); - + //5毫秒后,由于设置了默认过期,key3只被保留4毫秒,因此为null String value3 = timedCache.get("key3"); Assert.assertNull(value3); - + String value3Supplier = timedCache.get("key3", () -> "Default supplier"); Assert.assertEquals("Default supplier", value3Supplier); - + // 永不过期 String value4 = timedCache.get("key4"); Assert.assertEquals("value4", value4); - + //取消定时清理 timedCache.cancelPruneSchedule(); } diff --git a/hutool-captcha/src/main/java/cn/hutool/captcha/CircleCaptcha.java b/hutool-captcha/src/main/java/cn/hutool/captcha/CircleCaptcha.java index 4183a14b2..9e16a90b5 100644 --- a/hutool-captcha/src/main/java/cn/hutool/captcha/CircleCaptcha.java +++ b/hutool-captcha/src/main/java/cn/hutool/captcha/CircleCaptcha.java @@ -13,7 +13,7 @@ import java.util.concurrent.ThreadLocalRandom; /** * 圆圈干扰验证码 - * + * * @author looly * @since 3.2.3 * @@ -23,7 +23,7 @@ public class CircleCaptcha extends AbstractCaptcha { /** * 构造 - * + * * @param width 图片宽 * @param height 图片高 */ @@ -33,7 +33,7 @@ public class CircleCaptcha extends AbstractCaptcha { /** * 构造 - * + * * @param width 图片宽 * @param height 图片高 * @param codeCount 字符个数 @@ -44,7 +44,7 @@ public class CircleCaptcha extends AbstractCaptcha { /** * 构造 - * + * * @param width 图片宽 * @param height 图片高 * @param codeCount 字符个数 @@ -71,7 +71,7 @@ public class CircleCaptcha extends AbstractCaptcha { // ----------------------------------------------------------------------------------------------------- Private method start /** * 绘制字符串 - * + * * @param g {@link Graphics2D}画笔 * @param code 验证码 */ @@ -85,7 +85,7 @@ public class CircleCaptcha extends AbstractCaptcha { /** * 画随机干扰 - * + * * @param g {@link Graphics2D} */ private void drawInterfere(Graphics2D g) { diff --git a/hutool-captcha/src/main/java/cn/hutool/captcha/ICaptcha.java b/hutool-captcha/src/main/java/cn/hutool/captcha/ICaptcha.java index 1ee9a3ae2..68c16c728 100644 --- a/hutool-captcha/src/main/java/cn/hutool/captcha/ICaptcha.java +++ b/hutool-captcha/src/main/java/cn/hutool/captcha/ICaptcha.java @@ -5,7 +5,7 @@ import java.io.Serializable; /** * 验证码接口,提供验证码对象接口定义 - * + * * @author looly * */ @@ -18,14 +18,14 @@ public interface ICaptcha extends Serializable{ /** * 获取验证码的文字内容 - * + * * @return 验证码文字内容 */ String getCode(); /** * 验证验证码是否正确,建议忽略大小写 - * + * * @param userInputCode 用户输入的验证码 * @return 是否与生成的一直 */ @@ -33,7 +33,7 @@ public interface ICaptcha extends Serializable{ /** * 将验证码写出到目标流中 - * + * * @param out 目标流 */ void write(OutputStream out); diff --git a/hutool-captcha/src/main/java/cn/hutool/captcha/LineCaptcha.java b/hutool-captcha/src/main/java/cn/hutool/captcha/LineCaptcha.java index 6ed632f0e..8bf337635 100644 --- a/hutool-captcha/src/main/java/cn/hutool/captcha/LineCaptcha.java +++ b/hutool-captcha/src/main/java/cn/hutool/captcha/LineCaptcha.java @@ -14,7 +14,7 @@ import cn.hutool.core.util.RandomUtil; /** * 使用干扰线方式生成的图形验证码 - * + * * @author looly * @since 3.1.2 */ @@ -24,7 +24,7 @@ public class LineCaptcha extends AbstractCaptcha { // -------------------------------------------------------------------- Constructor start /** * 构造,默认5位验证码,150条干扰线 - * + * * @param width 图片宽 * @param height 图片高 */ @@ -34,7 +34,7 @@ public class LineCaptcha extends AbstractCaptcha { /** * 构造 - * + * * @param width 图片宽 * @param height 图片高 * @param codeCount 字符个数 @@ -63,7 +63,7 @@ public class LineCaptcha extends AbstractCaptcha { // ----------------------------------------------------------------------------------------------------- Private method start /** * 绘制字符串 - * + * * @param g {@link Graphics}画笔 * @param code 验证码 */ @@ -77,7 +77,7 @@ public class LineCaptcha extends AbstractCaptcha { /** * 绘制干扰线 - * + * * @param g {@link Graphics2D}画笔 */ private void drawInterfere(Graphics2D g) { diff --git a/hutool-captcha/src/main/java/cn/hutool/captcha/ShearCaptcha.java b/hutool-captcha/src/main/java/cn/hutool/captcha/ShearCaptcha.java index 35cb4d626..0f43dcc1d 100644 --- a/hutool-captcha/src/main/java/cn/hutool/captcha/ShearCaptcha.java +++ b/hutool-captcha/src/main/java/cn/hutool/captcha/ShearCaptcha.java @@ -13,7 +13,7 @@ import java.awt.image.BufferedImage; /** * 扭曲干扰验证码 - * + * * @author looly * @since 3.2.3 * @@ -23,7 +23,7 @@ public class ShearCaptcha extends AbstractCaptcha { /** * 构造 - * + * * @param width 图片宽 * @param height 图片高 */ @@ -33,7 +33,7 @@ public class ShearCaptcha extends AbstractCaptcha { /** * 构造 - * + * * @param width 图片宽 * @param height 图片高 * @param codeCount 字符个数 @@ -44,7 +44,7 @@ public class ShearCaptcha extends AbstractCaptcha { /** * 构造 - * + * * @param width 图片宽 * @param height 图片高 * @param codeCount 字符个数 @@ -73,7 +73,7 @@ public class ShearCaptcha extends AbstractCaptcha { // ----------------------------------------------------------------------------------------------------- Private method start /** * 绘制字符串 - * + * * @param g {@link Graphics}画笔 * @param code 验证码 */ @@ -87,7 +87,7 @@ public class ShearCaptcha extends AbstractCaptcha { /** * 扭曲 - * + * * @param g {@link Graphics} * @param w1 w1 * @param h1 h1 @@ -100,7 +100,7 @@ public class ShearCaptcha extends AbstractCaptcha { /** * X坐标扭曲 - * + * * @param g {@link Graphics} * @param w1 宽 * @param h1 高 @@ -125,7 +125,7 @@ public class ShearCaptcha extends AbstractCaptcha { /** * Y坐标扭曲 - * + * * @param g {@link Graphics} * @param w1 宽 * @param h1 高 @@ -150,7 +150,7 @@ public class ShearCaptcha extends AbstractCaptcha { /** * 干扰线 - * + * * @param g {@link Graphics} * @param x1 x1 * @param y1 y1 diff --git a/hutool-captcha/src/main/java/cn/hutool/captcha/generator/AbstractGenerator.java b/hutool-captcha/src/main/java/cn/hutool/captcha/generator/AbstractGenerator.java index a77ecf03f..1470a7764 100644 --- a/hutool-captcha/src/main/java/cn/hutool/captcha/generator/AbstractGenerator.java +++ b/hutool-captcha/src/main/java/cn/hutool/captcha/generator/AbstractGenerator.java @@ -5,21 +5,21 @@ import cn.hutool.core.util.RandomUtil; /** * 随机字符验证码生成器
* 可以通过传入的基础集合和长度随机生成验证码字符 - * + * * @author looly * @since 4.1.2 */ public abstract class AbstractGenerator implements CodeGenerator { private static final long serialVersionUID = 8685744597154953479L; - + /** 基础字符集合,用于随机获取字符串的字符集合 */ protected final String baseStr; /** 验证码长度 */ protected final int length; - + /** * 构造,使用字母+数字做为基础 - * + * * @param count 生成验证码长度 */ public AbstractGenerator(int count) { @@ -28,7 +28,7 @@ public abstract class AbstractGenerator implements CodeGenerator { /** * 构造 - * + * * @param baseStr 基础字符集合,用于随机获取字符串的字符集合 * @param length 生成验证码长度 */ @@ -39,7 +39,7 @@ public abstract class AbstractGenerator implements CodeGenerator { /** * 获取长度验证码 - * + * * @return 验证码长度 */ public int getLength() { diff --git a/hutool-captcha/src/main/java/cn/hutool/captcha/generator/CodeGenerator.java b/hutool-captcha/src/main/java/cn/hutool/captcha/generator/CodeGenerator.java index d7391ecba..6fbc97563 100644 --- a/hutool-captcha/src/main/java/cn/hutool/captcha/generator/CodeGenerator.java +++ b/hutool-captcha/src/main/java/cn/hutool/captcha/generator/CodeGenerator.java @@ -4,7 +4,7 @@ import java.io.Serializable; /** * 验证码文字生成器 - * + * * @author looly * @since 4.1.2 */ @@ -12,7 +12,7 @@ public interface CodeGenerator extends Serializable{ /** * 生成验证码 - * + * * @return 验证码 */ String generate(); @@ -20,7 +20,7 @@ public interface CodeGenerator extends Serializable{ /** * 验证用户输入的字符串是否与生成的验证码匹配
* 用户通过实现此方法定义验证码匹配方式 - * + * * @param code 生成的随机验证码 * @param userInputCode 用户输入的验证码 * @return 是否验证通过 diff --git a/hutool-captcha/src/main/java/cn/hutool/captcha/generator/MathGenerator.java b/hutool-captcha/src/main/java/cn/hutool/captcha/generator/MathGenerator.java index e9f52be0e..7395b3ee5 100644 --- a/hutool-captcha/src/main/java/cn/hutool/captcha/generator/MathGenerator.java +++ b/hutool-captcha/src/main/java/cn/hutool/captcha/generator/MathGenerator.java @@ -7,7 +7,7 @@ import cn.hutool.core.util.StrUtil; /** * 数字计算验证码生成器 - * + * * @author looly * @since 4.1.2 */ @@ -28,7 +28,7 @@ public class MathGenerator implements CodeGenerator { /** * 构造 - * + * * @param numberLength 参与计算最大数字位数 */ public MathGenerator(int numberLength) { @@ -75,7 +75,7 @@ public class MathGenerator implements CodeGenerator { /** * 根据长度获取参与计算数字最大值 - * + * * @return 最大值 */ private int getLimit() { From e41c676ed59b6e10c57792409ceb374e758ec326 Mon Sep 17 00:00:00 2001 From: cal101 Date: Sat, 27 Feb 2021 09:54:18 +0000 Subject: [PATCH 30/47] [cleanup] erefactor/EclipseJdt - Remove trailing whitespace - All lines EclipseJdt cleanup 'RemoveAllTrailingWhitespace' applied by erefactor. For EclipseJdt see https://www.eclipse.org/eclipse/news/4.18/jdt.php For erefactor see https://github.com/cal101/erefactor --- .../captcha/generator/RandomGenerator.java | 8 ++-- .../captcha/generator/package-info.java | 2 +- .../java/cn/hutool/captcha/package-info.java | 2 +- .../cn/hutool/captcha/CaptchaUtilTest.java | 2 +- .../CombinationAnnotationElement.java | 10 ++--- .../hutool/core/annotation/package-info.java | 2 +- .../cn/hutool/core/bean/BeanDescCache.java | 4 +- .../cn/hutool/core/bean/BeanException.java | 8 ++-- .../java/cn/hutool/core/bean/BeanPath.java | 32 +++++++------- .../hutool/core/bean/copier/BeanCopier.java | 20 ++++----- .../core/bean/copier/ValueProvider.java | 8 ++-- .../hutool/core/bean/copier/package-info.java | 2 +- .../bean/copier/provider/package-info.java | 2 +- .../cn/hutool/core/bean/package-info.java | 2 +- .../java/cn/hutool/core/builder/Builder.java | 4 +- .../hutool/core/builder/CompareToBuilder.java | 42 +++++++++---------- .../hutool/core/builder/HashCodeBuilder.java | 10 ++--- .../java/cn/hutool/core/builder/IDKey.java | 8 ++-- .../cn/hutool/core/builder/package-info.java | 2 +- .../core/clone/CloneRuntimeException.java | 8 ++-- 20 files changed, 89 insertions(+), 89 deletions(-) diff --git a/hutool-captcha/src/main/java/cn/hutool/captcha/generator/RandomGenerator.java b/hutool-captcha/src/main/java/cn/hutool/captcha/generator/RandomGenerator.java index d7c7ab6a2..5aa0ca985 100644 --- a/hutool-captcha/src/main/java/cn/hutool/captcha/generator/RandomGenerator.java +++ b/hutool-captcha/src/main/java/cn/hutool/captcha/generator/RandomGenerator.java @@ -6,7 +6,7 @@ import cn.hutool.core.util.StrUtil; /** * 随机字符验证码生成器
* 可以通过传入的基础集合和长度随机生成验证码字符 - * + * * @author looly * @since 4.1.2 */ @@ -15,7 +15,7 @@ public class RandomGenerator extends AbstractGenerator { /** * 构造,使用字母+数字做为基础 - * + * * @param count 生成验证码长度 */ public RandomGenerator(int count) { @@ -24,7 +24,7 @@ public class RandomGenerator extends AbstractGenerator { /** * 构造 - * + * * @param baseStr 基础字符集合,用于随机获取字符串的字符集合 * @param length 生成验证码长度 */ @@ -36,7 +36,7 @@ public class RandomGenerator extends AbstractGenerator { public String generate() { return RandomUtil.randomString(this.baseStr, this.length); } - + @Override public boolean verify(String code, String userInputCode) { if (StrUtil.isNotBlank(userInputCode)) { diff --git a/hutool-captcha/src/main/java/cn/hutool/captcha/generator/package-info.java b/hutool-captcha/src/main/java/cn/hutool/captcha/generator/package-info.java index ea7eae90a..c3fbf77a1 100644 --- a/hutool-captcha/src/main/java/cn/hutool/captcha/generator/package-info.java +++ b/hutool-captcha/src/main/java/cn/hutool/captcha/generator/package-info.java @@ -1,6 +1,6 @@ /** * 验证码生成策略实现 - * + * * @author looly * @since 4.1.2 */ diff --git a/hutool-captcha/src/main/java/cn/hutool/captcha/package-info.java b/hutool-captcha/src/main/java/cn/hutool/captcha/package-info.java index 5215911ba..c23501f5d 100644 --- a/hutool-captcha/src/main/java/cn/hutool/captcha/package-info.java +++ b/hutool-captcha/src/main/java/cn/hutool/captcha/package-info.java @@ -1,6 +1,6 @@ /** * 图片验证码实现 - * + * * @author looly * */ diff --git a/hutool-captcha/src/test/java/cn/hutool/captcha/CaptchaUtilTest.java b/hutool-captcha/src/test/java/cn/hutool/captcha/CaptchaUtilTest.java index 4ec978557..d57cc393d 100644 --- a/hutool-captcha/src/test/java/cn/hutool/captcha/CaptchaUtilTest.java +++ b/hutool-captcha/src/test/java/cn/hutool/captcha/CaptchaUtilTest.java @@ -4,7 +4,7 @@ import org.junit.Ignore; import org.junit.Test; public class CaptchaUtilTest { - + @Test @Ignore public void createTest() { diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/CombinationAnnotationElement.java b/hutool-core/src/main/java/cn/hutool/core/annotation/CombinationAnnotationElement.java index f872e3577..90c892be0 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/CombinationAnnotationElement.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/CombinationAnnotationElement.java @@ -43,7 +43,7 @@ public class CombinationAnnotationElement implements AnnotatedElement, Serializa /** * 构造 - * + * * @param element 需要解析注解的元素:可以是Class、Method、Field、Constructor、ReflectPermission */ public CombinationAnnotationElement(AnnotatedElement element) { @@ -73,17 +73,17 @@ public class CombinationAnnotationElement implements AnnotatedElement, Serializa final Collection annotations = this.declaredAnnotationMap.values(); return annotations.toArray(new Annotation[0]); } - + /** * 初始化 - * + * * @param element 元素 */ private void init(AnnotatedElement element) { final Annotation[] declaredAnnotations = element.getDeclaredAnnotations(); this.declaredAnnotationMap = new HashMap<>(); parseDeclared(declaredAnnotations); - + final Annotation[] annotations = element.getAnnotations(); if(Arrays.equals(declaredAnnotations, annotations)) { this.annotationMap = this.declaredAnnotationMap; @@ -109,7 +109,7 @@ public class CombinationAnnotationElement implements AnnotatedElement, Serializa } } } - + /** * 进行递归解析注解,直到全部都是元注解为止 * diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/package-info.java b/hutool-core/src/main/java/cn/hutool/core/annotation/package-info.java index 2f6556f62..850654b46 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/package-info.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/package-info.java @@ -1,6 +1,6 @@ /** * 注解包,提供增强型注解和注解工具类 - * + * * @author looly * */ diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/BeanDescCache.java b/hutool-core/src/main/java/cn/hutool/core/bean/BeanDescCache.java index d2a3eeafc..d1eaa920a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/BeanDescCache.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/BeanDescCache.java @@ -11,9 +11,9 @@ import cn.hutool.core.lang.func.Func0; */ public enum BeanDescCache { INSTANCE; - + private final SimpleCache, BeanDesc> bdCache = new SimpleCache<>(); - + /** * 获得属性名和{@link BeanDesc}Map映射 * @param beanClass Bean的类 diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/BeanException.java b/hutool-core/src/main/java/cn/hutool/core/bean/BeanException.java index 6584dce36..227e28040 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/BeanException.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/BeanException.java @@ -13,19 +13,19 @@ public class BeanException extends RuntimeException{ public BeanException(Throwable e) { super(ExceptionUtil.getMessage(e), e); } - + public BeanException(String message) { super(message); } - + public BeanException(String messageTemplate, Object... params) { super(StrUtil.format(messageTemplate, params)); } - + public BeanException(String message, Throwable throwable) { super(message, throwable); } - + public BeanException(Throwable throwable, String messageTemplate, Object... params) { super(StrUtil.format(messageTemplate, params), throwable); } diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/BeanPath.java b/hutool-core/src/main/java/cn/hutool/core/bean/BeanPath.java index f07c65bb8..ce92e3951 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/BeanPath.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/BeanPath.java @@ -23,9 +23,9 @@ import java.util.Map; *
  • .表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值
  • *
  • []表达式,可以获取集合等对象中对应index的值
  • * - * + * * 表达式栗子: - * + * *
      * persion
      * persion.name
    @@ -33,7 +33,7 @@ import java.util.Map;
      * person.friends[5].name
      * ['person']['friends'][5]['name']
      * 
    - * + * * @author Looly * @since 4.0.6 */ @@ -54,9 +54,9 @@ public class BeanPath implements Serializable{ *
  • .表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值
  • *
  • []表达式,可以获取集合等对象中对应index的值
  • * - * + * * 表达式栗子: - * + * *
     	 * persion
     	 * persion.name
    @@ -64,7 +64,7 @@ public class BeanPath implements Serializable{
     	 * person.friends[5].name
     	 * ['person']['friends'][5]['name']
     	 * 
    - * + * * @param expression 表达式 * @return BeanPath */ @@ -74,7 +74,7 @@ public class BeanPath implements Serializable{ /** * 构造 - * + * * @param expression 表达式 */ public BeanPath(String expression) { @@ -83,7 +83,7 @@ public class BeanPath implements Serializable{ /** * 获取Bean中对应表达式的值 - * + * * @param bean Bean对象或Map或List等 * @return 值,如果对应值不存在,则返回null */ @@ -95,29 +95,29 @@ public class BeanPath implements Serializable{ * 设置表达式指定位置(或filed对应)的值
    * 若表达式指向一个List则设置其坐标对应位置的值,若指向Map则put对应key的值,Bean则设置字段的值
    * 注意: - * + * *
     	 * 1. 如果为List,如果下标不大于List长度,则替换原有值,否则追加值
     	 * 2. 如果为数组,如果下标不大于数组长度,则替换原有值,否则追加值
     	 * 
    - * + * * @param bean Bean、Map或List * @param value 值 */ public void set(Object bean, Object value) { set(bean, this.patternParts, value); } - + /** * 设置表达式指定位置(或filed对应)的值
    * 若表达式指向一个List则设置其坐标对应位置的值,若指向Map则put对应key的值,Bean则设置字段的值
    * 注意: - * + * *
     	 * 1. 如果为List,如果下标不大于List长度,则替换原有值,否则追加值
     	 * 2. 如果为数组,如果下标不大于数组长度,则替换原有值,否则追加值
     	 * 
    - * + * * @param bean Bean、Map或List * @param patternParts 表达式块列表 * @param value 值 @@ -135,7 +135,7 @@ public class BeanPath implements Serializable{ // ------------------------------------------------------------------------------------------------------------------------------------- Private method start /** * 获取Bean中对应表达式的值 - * + * * @param patternParts 表达式分段列表 * @param bean Bean对象或Map或List等 * @param ignoreLast 是否忽略最后一个值,忽略最后一个值则用于set,否则用于read @@ -215,7 +215,7 @@ public class BeanPath implements Serializable{ /** * 初始化 - * + * * @param expression 表达式 */ private void init(String expression) { @@ -277,7 +277,7 @@ public class BeanPath implements Serializable{ /** * 对于非表达式去除单引号 - * + * * @param expression 表达式 * @return 表达式 */ diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java index b2d375ba3..7d54e7a9c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java @@ -25,7 +25,7 @@ import java.util.Map; * 3. Map 转 Bean * 4. Map 转 Map * - * + * * @author looly * * @param 目标对象类型 @@ -33,7 +33,7 @@ import java.util.Map; */ public class BeanCopier implements Copier, Serializable { private static final long serialVersionUID = 1L; - + /** 源对象 */ private final Object source; /** 目标对象 */ @@ -45,7 +45,7 @@ public class BeanCopier implements Copier, Serializable { /** * 创建BeanCopier - * + * * @param 目标Bean类型 * @param source 来源对象,可以是Bean或者Map * @param dest 目标Bean对象 @@ -58,7 +58,7 @@ public class BeanCopier implements Copier, Serializable { /** * 创建BeanCopier - * + * * @param 目标Bean类型 * @param source 来源对象,可以是Bean或者Map * @param dest 目标Bean对象 @@ -72,7 +72,7 @@ public class BeanCopier implements Copier, Serializable { /** * 构造 - * + * * @param source 来源对象,可以是Bean或者Map * @param dest 目标Bean对象 * @param destType 目标的泛型类型,用于标注有泛型参数的Bean对象 @@ -115,7 +115,7 @@ public class BeanCopier implements Copier, Serializable { /** * Bean和Bean之间属性拷贝 - * + * * @param providerBean 来源Bean * @param destBean 目标Bean */ @@ -125,7 +125,7 @@ public class BeanCopier implements Copier, Serializable { /** * Map转Bean属性拷贝 - * + * * @param map Map * @param bean Bean */ @@ -138,7 +138,7 @@ public class BeanCopier implements Copier, Serializable { /** * Map转Map - * + * * @param source 源Map * @param dest 目标Map */ @@ -151,7 +151,7 @@ public class BeanCopier implements Copier, Serializable { /** * 对象转Map - * + * * @param bean bean对象 * @param targetMap 目标的Map * @since 4.1.22 @@ -201,7 +201,7 @@ public class BeanCopier implements Copier, Serializable { /** * 值提供器转Bean
    * 此方法通过遍历目标Bean的字段,从ValueProvider查找对应值 - * + * * @param valueProvider 值提供器 * @param bean Bean */ diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/ValueProvider.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/ValueProvider.java index 003154668..9f9611651 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/ValueProvider.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/ValueProvider.java @@ -6,17 +6,17 @@ import java.lang.reflect.Type; * 值提供者,用于提供Bean注入时参数对应值得抽象接口
    * 继承或匿名实例化此接口
    * 在Bean注入过程中,Bean获得字段名,通过外部方式根据这个字段名查找相应的字段值,然后注入Bean
    - * + * * @author Looly * @param KEY类型,一般情况下为 {@link String} * */ public interface ValueProvider{ - + /** * 获取值
    * 返回值一般需要匹配被注入类型,如果不匹配会调用默认转换 Convert#convert(Type, Object)实现转换 - * + * * @param key Bean对象中参数名 * @param valueType 被注入的值的类型 * @return 对应参数名的值 @@ -26,7 +26,7 @@ public interface ValueProvider{ /** * 是否包含指定KEY,如果不包含则忽略注入
    * 此接口方法单独需要实现的意义在于:有些值提供者(比如Map)key是存在的,但是value为null,此时如果需要注入这个null,需要根据此方法判断 - * + * * @param key Bean对象中参数名 * @return 是否包含指定KEY */ diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/package-info.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/package-info.java index 83ce74500..6220095d2 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/package-info.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/package-info.java @@ -1,6 +1,6 @@ /** * Bean拷贝实现,包括拷贝选项等 - * + * * @author looly * */ diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/package-info.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/package-info.java index 43b706d59..f52e7bc7e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/package-info.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/package-info.java @@ -1,6 +1,6 @@ /** * Bean值提供者方式封装 - * + * * @author looly * */ diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/package-info.java b/hutool-core/src/main/java/cn/hutool/core/bean/package-info.java index a7935ea32..dc27ffd67 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/package-info.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/package-info.java @@ -1,6 +1,6 @@ /** * Bean相关操作,包括Bean信息描述,Bean路径表达式、动态Bean、Bean工具等 - * + * * @author looly * */ diff --git a/hutool-core/src/main/java/cn/hutool/core/builder/Builder.java b/hutool-core/src/main/java/cn/hutool/core/builder/Builder.java index a7afb76cd..518ac8ddc 100644 --- a/hutool-core/src/main/java/cn/hutool/core/builder/Builder.java +++ b/hutool-core/src/main/java/cn/hutool/core/builder/Builder.java @@ -4,7 +4,7 @@ import java.io.Serializable; /** * 建造者模式接口定义 - * + * * @param 建造对象类型 * @author Looly * @since 4.2.2 @@ -12,7 +12,7 @@ import java.io.Serializable; public interface Builder extends Serializable{ /** * 构建 - * + * * @return 被构建的对象 */ T build(); diff --git a/hutool-core/src/main/java/cn/hutool/core/builder/CompareToBuilder.java b/hutool-core/src/main/java/cn/hutool/core/builder/CompareToBuilder.java index de0c6705b..66325853e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/builder/CompareToBuilder.java +++ b/hutool-core/src/main/java/cn/hutool/core/builder/CompareToBuilder.java @@ -8,7 +8,7 @@ import java.lang.reflect.Modifier; import java.util.Collection; import java.util.Comparator; -/** +/** * 用于构建 {@link java.lang.Comparable#compareTo(Object)} 方法的辅助工具 * *

    @@ -33,7 +33,7 @@ import java.util.Comparator; * } * } * - * + * * 字段值按照顺序比较,如果某个字段返回非0结果,比较终止,使用{@code toComparison()}返回结果,后续比较忽略。 * *

    @@ -52,7 +52,7 @@ import java.util.Comparator; */ public class CompareToBuilder implements Builder { private static final long serialVersionUID = 1L; - + /** 当前比较状态 */ private int comparison; @@ -65,7 +65,7 @@ public class CompareToBuilder implements Builder { } //----------------------------------------------------------------------- - /** + /** * 通过反射比较两个Bean对象,对象字段可以为private。比较规则如下: * *

      @@ -94,7 +94,7 @@ public class CompareToBuilder implements Builder { *

      Compares two Objects via reflection.

      * *

      Fields can be private, thus AccessibleObject.setAccessible - * is used to bypass normal access control checks. This will fail under a + * is used to bypass normal access control checks. This will fail under a * security manager unless the appropriate permissions are set.

      * *
        @@ -126,7 +126,7 @@ public class CompareToBuilder implements Builder { *

        Compares two Objects via reflection.

        * *

        Fields can be private, thus AccessibleObject.setAccessible - * is used to bypass normal access control checks. This will fail under a + * is used to bypass normal access control checks. This will fail under a * security manager unless the appropriate permissions are set.

        * *
          @@ -159,7 +159,7 @@ public class CompareToBuilder implements Builder { *

          Compares two Objects via reflection.

          * *

          Fields can be private, thus AccessibleObject.setAccessible - * is used to bypass normal access control checks. This will fail under a + * is used to bypass normal access control checks. This will fail under a * security manager unless the appropriate permissions are set.

          * *
            @@ -192,7 +192,7 @@ public class CompareToBuilder implements Builder { *

            Compares two Objects via reflection.

            * *

            Fields can be private, thus AccessibleObject.setAccessible - * is used to bypass normal access control checks. This will fail under a + * is used to bypass normal access control checks. This will fail under a * security manager unless the appropriate permissions are set.

            * *
              @@ -221,10 +221,10 @@ public class CompareToBuilder implements Builder { * @since 2.2 (2.0 as reflectionCompare(Object, Object, boolean, Class)) */ public static int reflectionCompare( - final Object lhs, - final Object rhs, - final boolean compareTransients, - final Class reflectUpToClass, + final Object lhs, + final Object rhs, + final boolean compareTransients, + final Class reflectUpToClass, final String... excludeFields) { if (lhs == rhs) { @@ -249,7 +249,7 @@ public class CompareToBuilder implements Builder { /** *

              Appends to builder the comparison of lhs * to rhs using the fields defined in clazz.

              - * + * * @param lhs left-hand object * @param rhs right-hand object * @param clazz Class that defines fields to be compared @@ -264,7 +264,7 @@ public class CompareToBuilder implements Builder { final CompareToBuilder builder, final boolean useTransients, final String[] excludeFields) { - + final Field[] fields = clazz.getDeclaredFields(); AccessibleObject.setAccessible(fields, true); for (int i = 0; i < fields.length && builder.comparison == 0; i++) { @@ -300,7 +300,7 @@ public class CompareToBuilder implements Builder { comparison = superCompareTo; return this; } - + //----------------------------------------------------------------------- /** *

              Appends to the builder the comparison of @@ -312,7 +312,7 @@ public class CompareToBuilder implements Builder { * a null object is less than a non-null object *

            • Check the object contents
            • * - * + * *

              lhs must either be an array or implement {@link Comparable}.

              * * @param lhs left-hand object @@ -441,7 +441,7 @@ public class CompareToBuilder implements Builder { /** * Appends to the builder the comparison of * two shorts. - * + * * @param lhs left-hand value * @param rhs right-hand value * @return this - used to chain append calls @@ -473,7 +473,7 @@ public class CompareToBuilder implements Builder { /** * Appends to the builder the comparison of * two bytes. - * + * * @param lhs left-hand value * @param rhs right-hand value * @return this - used to chain append calls @@ -575,7 +575,7 @@ public class CompareToBuilder implements Builder { public CompareToBuilder append(final Object[] lhs, final Object[] rhs) { return append(lhs, rhs, null); } - + /** *

              Appends to the builder the deep comparison of * two Object arrays.

              @@ -950,7 +950,7 @@ public class CompareToBuilder implements Builder { * the builder has judged the "left-hand" side * as less than, greater than, or equal to the "right-hand" * side. - * + * * @return final comparison result * @see #build() */ @@ -963,7 +963,7 @@ public class CompareToBuilder implements Builder { * the builder has judged the "left-hand" side * as less than, greater than, or equal to the "right-hand" * side. - * + * * @return final comparison result as an Integer * @see #toComparison() * @since 3.0 diff --git a/hutool-core/src/main/java/cn/hutool/core/builder/HashCodeBuilder.java b/hutool-core/src/main/java/cn/hutool/core/builder/HashCodeBuilder.java index 9991c7856..6ca13c243 100644 --- a/hutool-core/src/main/java/cn/hutool/core/builder/HashCodeBuilder.java +++ b/hutool-core/src/main/java/cn/hutool/core/builder/HashCodeBuilder.java @@ -85,17 +85,17 @@ import cn.hutool.core.util.ArrayUtil; */ public class HashCodeBuilder implements Builder { private static final long serialVersionUID = 1L; - + /** * The default initial value to use in reflection hash code building. */ private static final int DEFAULT_INITIAL_VALUE = 17; - + /** * The default multipler value to use in reflection hash code building. */ private static final int DEFAULT_MULTIPLIER_VALUE = 37; - + /** *

              * A registry of objects used by reflection methods to detect cyclical object references and avoid infinite loops. @@ -380,7 +380,7 @@ public class HashCodeBuilder implements Builder { * if the object is null */ public static int reflectionHashCode(final Object object, final boolean testTransients) { - return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object, + return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object, testTransients, null); } @@ -457,7 +457,7 @@ public class HashCodeBuilder implements Builder { * if the object is null */ public static int reflectionHashCode(final Object object, final String... excludeFields) { - return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object, false, + return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object, false, null, excludeFields); } diff --git a/hutool-core/src/main/java/cn/hutool/core/builder/IDKey.java b/hutool-core/src/main/java/cn/hutool/core/builder/IDKey.java index 40af0d8c4..e49ecd174 100644 --- a/hutool-core/src/main/java/cn/hutool/core/builder/IDKey.java +++ b/hutool-core/src/main/java/cn/hutool/core/builder/IDKey.java @@ -13,13 +13,13 @@ import java.io.Serializable; */ final class IDKey implements Serializable{ private static final long serialVersionUID = 1L; - + private final Object value; private final int id; /** * 构造 - * + * * @param obj 计算唯一ID的对象 */ public IDKey(final Object obj) { @@ -32,7 +32,7 @@ final class IDKey implements Serializable{ /** * returns hashcode - i.e. the system identity hashcode. - * + * * @return the hashcode */ @Override @@ -42,7 +42,7 @@ final class IDKey implements Serializable{ /** * checks if instances are equal - * + * * @param other The other object to compare to * @return if the instances are for the same object */ diff --git a/hutool-core/src/main/java/cn/hutool/core/builder/package-info.java b/hutool-core/src/main/java/cn/hutool/core/builder/package-info.java index db54a59b3..800a02855 100644 --- a/hutool-core/src/main/java/cn/hutool/core/builder/package-info.java +++ b/hutool-core/src/main/java/cn/hutool/core/builder/package-info.java @@ -1,7 +1,7 @@ /** * 建造者工具
              * 用于建造特定对象或结果 - * + * * @author looly * */ diff --git a/hutool-core/src/main/java/cn/hutool/core/clone/CloneRuntimeException.java b/hutool-core/src/main/java/cn/hutool/core/clone/CloneRuntimeException.java index 9f5744e21..7f70e2813 100644 --- a/hutool-core/src/main/java/cn/hutool/core/clone/CloneRuntimeException.java +++ b/hutool-core/src/main/java/cn/hutool/core/clone/CloneRuntimeException.java @@ -13,19 +13,19 @@ public class CloneRuntimeException extends RuntimeException{ public CloneRuntimeException(Throwable e) { super(ExceptionUtil.getMessage(e), e); } - + public CloneRuntimeException(String message) { super(message); } - + public CloneRuntimeException(String messageTemplate, Object... params) { super(StrUtil.format(messageTemplate, params)); } - + public CloneRuntimeException(String message, Throwable throwable) { super(message, throwable); } - + public CloneRuntimeException(Throwable throwable, String messageTemplate, Object... params) { super(StrUtil.format(messageTemplate, params), throwable); } From ece50fcacacc40ee5fde8709334ce9075773c52d Mon Sep 17 00:00:00 2001 From: cal101 Date: Sat, 27 Feb 2021 09:54:19 +0000 Subject: [PATCH 31/47] [cleanup] erefactor/EclipseJdt - Remove trailing whitespace - All lines EclipseJdt cleanup 'RemoveAllTrailingWhitespace' applied by erefactor. For EclipseJdt see https://www.eclipse.org/eclipse/news/4.18/jdt.php For erefactor see https://github.com/cal101/erefactor --- .../cn/hutool/core/clone/CloneSupport.java | 4 +-- .../java/cn/hutool/core/clone/Cloneable.java | 2 +- .../cn/hutool/core/clone/package-info.java | 2 +- .../main/java/cn/hutool/core/codec/BCD.java | 8 +++--- .../java/cn/hutool/core/codec/Base32.java | 20 +++++++------- .../java/cn/hutool/core/codec/Base62.java | 26 +++++++++---------- .../cn/hutool/core/codec/Base62Codec.java | 16 ++++++------ .../cn/hutool/core/codec/Base64Decoder.java | 16 ++++++------ .../cn/hutool/core/codec/Base64Encoder.java | 20 +++++++------- .../main/java/cn/hutool/core/codec/Morse.java | 12 ++++----- .../main/java/cn/hutool/core/codec/Rot.java | 18 ++++++------- .../cn/hutool/core/codec/package-info.java | 2 +- .../cn/hutool/core/collection/ArrayIter.java | 2 +- .../core/collection/BoundedPriorityQueue.java | 12 ++++----- .../core/collection/CollectionUtil.java | 2 +- .../core/collection/ConcurrentHashSet.java | 10 +++---- .../cn/hutool/core/collection/CopiedIter.java | 8 +++--- .../core/collection/EnumerationIter.java | 4 +-- .../core/collection/IteratorEnumeration.java | 4 +-- .../cn/hutool/core/collection/LineIter.java | 8 +++--- 20 files changed, 98 insertions(+), 98 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/clone/CloneSupport.java b/hutool-core/src/main/java/cn/hutool/core/clone/CloneSupport.java index 9a6a8ffec..3ea2fcec3 100644 --- a/hutool-core/src/main/java/cn/hutool/core/clone/CloneSupport.java +++ b/hutool-core/src/main/java/cn/hutool/core/clone/CloneSupport.java @@ -7,7 +7,7 @@ package cn.hutool.core.clone; * @param 继承类的类型 */ public class CloneSupport implements Cloneable{ - + @SuppressWarnings("unchecked") @Override public T clone() { @@ -17,5 +17,5 @@ public class CloneSupport implements Cloneable{ throw new CloneRuntimeException(e); } } - + } diff --git a/hutool-core/src/main/java/cn/hutool/core/clone/Cloneable.java b/hutool-core/src/main/java/cn/hutool/core/clone/Cloneable.java index 80f3c0167..5fdbb1b37 100644 --- a/hutool-core/src/main/java/cn/hutool/core/clone/Cloneable.java +++ b/hutool-core/src/main/java/cn/hutool/core/clone/Cloneable.java @@ -7,7 +7,7 @@ package cn.hutool.core.clone; * @param 实现克隆接口的类型 */ public interface Cloneable extends java.lang.Cloneable{ - + /** * 克隆当前对象,浅复制 * @return 克隆后的对象 diff --git a/hutool-core/src/main/java/cn/hutool/core/clone/package-info.java b/hutool-core/src/main/java/cn/hutool/core/clone/package-info.java index 24e938a34..a4530d996 100644 --- a/hutool-core/src/main/java/cn/hutool/core/clone/package-info.java +++ b/hutool-core/src/main/java/cn/hutool/core/clone/package-info.java @@ -1,6 +1,6 @@ /** * 克隆封装 - * + * * @author looly * */ diff --git a/hutool-core/src/main/java/cn/hutool/core/codec/BCD.java b/hutool-core/src/main/java/cn/hutool/core/codec/BCD.java index 936d6f529..5259405e1 100644 --- a/hutool-core/src/main/java/cn/hutool/core/codec/BCD.java +++ b/hutool-core/src/main/java/cn/hutool/core/codec/BCD.java @@ -10,7 +10,7 @@ import cn.hutool.core.lang.Assert; * */ public class BCD { - + /** * 字符串转BCD码 * @param asc ASCII字符串 @@ -53,7 +53,7 @@ public class BCD { } return bbt; } - + /** * ASCII转BCD * @param ascii ASCII byte数组 @@ -100,8 +100,8 @@ public class BCD { } return new String(temp); } - - + + //----------------------------------------------------------------- Private method start /** * 转换单个byte为BCD diff --git a/hutool-core/src/main/java/cn/hutool/core/codec/Base32.java b/hutool-core/src/main/java/cn/hutool/core/codec/Base32.java index d66c7ade0..030bf6e66 100644 --- a/hutool-core/src/main/java/cn/hutool/core/codec/Base32.java +++ b/hutool-core/src/main/java/cn/hutool/core/codec/Base32.java @@ -14,7 +14,7 @@ import cn.hutool.core.util.StrUtil; * */ public class Base32 { - + private Base32() {} private static final String BASE32_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; @@ -73,10 +73,10 @@ public class Base32 { return base32.toString(); } - + /** * base32编码 - * + * * @param source 被编码的base32字符串 * @return 被加密后的字符串 */ @@ -86,7 +86,7 @@ public class Base32 { /** * base32编码 - * + * * @param source 被编码的base32字符串 * @param charset 字符集 * @return 被加密后的字符串 @@ -97,7 +97,7 @@ public class Base32 { /** * base32编码 - * + * * @param source 被编码的base32字符串 * @param charset 字符集 * @return 被加密后的字符串 @@ -155,10 +155,10 @@ public class Base32 { } return bytes; } - + /** * base32解码 - * + * * @param source 被解码的base32字符串 * @return 被加密后的字符串 */ @@ -168,7 +168,7 @@ public class Base32 { /** * base32解码 - * + * * @param source 被解码的base32字符串 * @param charset 字符集 * @return 被加密后的字符串 @@ -176,10 +176,10 @@ public class Base32 { public static String decodeStr(String source, String charset) { return StrUtil.str(decode(source), charset); } - + /** * base32解码 - * + * * @param source 被解码的base32字符串 * @param charset 字符集 * @return 被加密后的字符串 diff --git a/hutool-core/src/main/java/cn/hutool/core/codec/Base62.java b/hutool-core/src/main/java/cn/hutool/core/codec/Base62.java index 5aefb324d..bb0454540 100644 --- a/hutool-core/src/main/java/cn/hutool/core/codec/Base62.java +++ b/hutool-core/src/main/java/cn/hutool/core/codec/Base62.java @@ -12,7 +12,7 @@ import cn.hutool.core.util.StrUtil; /** * Base62工具类,提供Base62的编码和解码方案
              - * + * * @author Looly * @since 4.5.9 */ @@ -24,7 +24,7 @@ public class Base62 { // -------------------------------------------------------------------- encode /** * Base62编码 - * + * * @param source 被编码的Base62字符串 * @return 被加密后的字符串 */ @@ -34,7 +34,7 @@ public class Base62 { /** * Base62编码 - * + * * @param source 被编码的Base62字符串 * @param charset 字符集 * @return 被加密后的字符串 @@ -45,7 +45,7 @@ public class Base62 { /** * Base62编码 - * + * * @param source 被编码的Base62字符串 * @return 被加密后的字符串 */ @@ -55,7 +55,7 @@ public class Base62 { /** * Base62编码 - * + * * @param in 被编码Base62的流(一般为图片流或者文件流) * @return 被加密后的字符串 */ @@ -65,7 +65,7 @@ public class Base62 { /** * Base62编码 - * + * * @param file 被编码Base62的文件 * @return 被加密后的字符串 */ @@ -76,7 +76,7 @@ public class Base62 { // -------------------------------------------------------------------- decode /** * Base62解码 - * + * * @param source 被解码的Base62字符串 * @return 被加密后的字符串 */ @@ -86,7 +86,7 @@ public class Base62 { /** * Base62解码 - * + * * @param source 被解码的Base62字符串 * @return 被加密后的字符串 */ @@ -96,7 +96,7 @@ public class Base62 { /** * Base62解码 - * + * * @param source 被解码的Base62字符串 * @param charset 字符集 * @return 被加密后的字符串 @@ -107,7 +107,7 @@ public class Base62 { /** * Base62解码 - * + * * @param Base62 被解码的Base62字符串 * @param destFile 目标文件 * @return 目标文件 @@ -118,7 +118,7 @@ public class Base62 { /** * Base62解码 - * + * * @param base62Str 被解码的Base62字符串 * @param out 写出到的流 * @param isCloseOut 是否关闭输出流 @@ -129,7 +129,7 @@ public class Base62 { /** * Base62解码 - * + * * @param base62Str 被解码的Base62字符串 * @return 被加密后的字符串 */ @@ -139,7 +139,7 @@ public class Base62 { /** * 解码Base62 - * + * * @param base62bytes Base62输入 * @return 解码后的bytes */ diff --git a/hutool-core/src/main/java/cn/hutool/core/codec/Base62Codec.java b/hutool-core/src/main/java/cn/hutool/core/codec/Base62Codec.java index 30390584d..0dbc1fadd 100644 --- a/hutool-core/src/main/java/cn/hutool/core/codec/Base62Codec.java +++ b/hutool-core/src/main/java/cn/hutool/core/codec/Base62Codec.java @@ -48,16 +48,16 @@ public class Base62Codec implements Serializable{ /** * 创建GMP风格的Base62编码解码器对象 - * + * * @return Base62Codec */ public static Base62Codec createGmp() { return new Base62Codec(GMP); } - + /** * 创建Inverted风格的Base62编码解码器对象 - * + * * @return Base62Codec */ public static Base62Codec createInverted() { @@ -69,7 +69,7 @@ public class Base62Codec implements Serializable{ /** * 构造 - * + * * @param alphabet 自定义字母表 */ public Base62Codec(byte[] alphabet) { @@ -93,7 +93,7 @@ public class Base62Codec implements Serializable{ /** * 解码Base62消息 - * + * * @param encoded Base62内容 * @return 消息 */ @@ -105,7 +105,7 @@ public class Base62Codec implements Serializable{ // --------------------------------------------------------------------------------------------------------------- Private method start /** * 按照字典转换bytes - * + * * @param indices 内容 * @param dictionary 字典 * @return 转换值 @@ -122,7 +122,7 @@ public class Base62Codec implements Serializable{ /** * 使用定义的字母表从源基准到目标基准 - * + * * @param message 消息bytes * @param sourceBase 源基准长度 * @param targetBase 目标基准长度 @@ -167,7 +167,7 @@ public class Base62Codec implements Serializable{ /** * 估算结果长度 - * + * * @param inputLength 输入长度 * @param sourceBase 源基准长度 * @param targetBase 目标基准长度 diff --git a/hutool-core/src/main/java/cn/hutool/core/codec/Base64Decoder.java b/hutool-core/src/main/java/cn/hutool/core/codec/Base64Decoder.java index bcade12dd..7f2346519 100644 --- a/hutool-core/src/main/java/cn/hutool/core/codec/Base64Decoder.java +++ b/hutool-core/src/main/java/cn/hutool/core/codec/Base64Decoder.java @@ -8,7 +8,7 @@ import cn.hutool.core.util.StrUtil; /** * Base64解码实现 - * + * * @author looly * */ @@ -41,7 +41,7 @@ public class Base64Decoder { /** * base64解码 - * + * * @param source 被解码的base64字符串 * @return 被加密后的字符串 */ @@ -51,7 +51,7 @@ public class Base64Decoder { /** * base64解码 - * + * * @param source 被解码的base64字符串 * @param charset 字符集 * @return 被加密后的字符串 @@ -62,7 +62,7 @@ public class Base64Decoder { /** * base64解码 - * + * * @param source 被解码的base64字符串 * @return 被加密后的字符串 */ @@ -72,7 +72,7 @@ public class Base64Decoder { /** * 解码Base64 - * + * * @param in 输入 * @return 解码后的bytes */ @@ -85,7 +85,7 @@ public class Base64Decoder { /** * 解码Base64 - * + * * @param in 输入 * @param pos 开始位置 * @param length 长度 @@ -133,7 +133,7 @@ public class Base64Decoder { // ----------------------------------------------------------------------------------------------- Private start /** * 获取下一个有效的byte字符 - * + * * @param in 输入 * @param pos 当前位置,调用此方法后此位置保持在有效字符的下一个位置 * @param maxPos 最大位置 @@ -157,7 +157,7 @@ public class Base64Decoder { /** * int包装,使之可变 - * + * * @author looly * */ diff --git a/hutool-core/src/main/java/cn/hutool/core/codec/Base64Encoder.java b/hutool-core/src/main/java/cn/hutool/core/codec/Base64Encoder.java index f5ba54699..a70ec5a7d 100644 --- a/hutool-core/src/main/java/cn/hutool/core/codec/Base64Encoder.java +++ b/hutool-core/src/main/java/cn/hutool/core/codec/Base64Encoder.java @@ -7,7 +7,7 @@ import java.nio.charset.Charset; /** * Base64编码 - * + * * @author looly * @since 3.2.0 */ @@ -40,7 +40,7 @@ public class Base64Encoder { // -------------------------------------------------------------------- encode /** * 编码为Base64,非URL安全的 - * + * * @param arr 被编码的数组 * @param lineSep 在76个char之后是CRLF还是EOF * @return 编码后的bytes @@ -51,7 +51,7 @@ public class Base64Encoder { /** * 编码为Base64,URL安全的 - * + * * @param arr 被编码的数组 * @param lineSep 在76个char之后是CRLF还是EOF * @return 编码后的bytes @@ -63,7 +63,7 @@ public class Base64Encoder { /** * base64编码 - * + * * @param source 被编码的base64字符串 * @return 被加密后的字符串 */ @@ -73,7 +73,7 @@ public class Base64Encoder { /** * base64编码,URL安全 - * + * * @param source 被编码的base64字符串 * @return 被加密后的字符串 * @since 3.0.6 @@ -84,7 +84,7 @@ public class Base64Encoder { /** * base64编码 - * + * * @param source 被编码的base64字符串 * @param charset 字符集 * @return 被加密后的字符串 @@ -95,7 +95,7 @@ public class Base64Encoder { /** * base64编码,URL安全的 - * + * * @param source 被编码的base64字符串 * @param charset 字符集 * @return 被加密后的字符串 @@ -107,7 +107,7 @@ public class Base64Encoder { /** * base64编码 - * + * * @param source 被编码的base64字符串 * @return 被加密后的字符串 */ @@ -117,7 +117,7 @@ public class Base64Encoder { /** * base64编码,URL安全的 - * + * * @param source 被编码的base64字符串 * @return 被加密后的字符串 * @since 3.0.6 @@ -129,7 +129,7 @@ public class Base64Encoder { /** * 编码为Base64
              * 如果isMultiLine为{@code true},则每76个字符一个换行符,否则在一行显示 - * + * * @param arr 被编码的数组 * @param isMultiLine 在76个char之后是CRLF还是EOF * @param isUrlSafe 是否使用URL安全字符,一般为{@code false} diff --git a/hutool-core/src/main/java/cn/hutool/core/codec/Morse.java b/hutool-core/src/main/java/cn/hutool/core/codec/Morse.java index e583ef2c8..16e0be430 100644 --- a/hutool-core/src/main/java/cn/hutool/core/codec/Morse.java +++ b/hutool-core/src/main/java/cn/hutool/core/codec/Morse.java @@ -11,7 +11,7 @@ import cn.hutool.core.util.StrUtil; /** * 莫尔斯电码的编码和解码实现
              * 参考:https://github.com/TakWolf/Java-MorseCoder - * + * * @author looly, TakWolf * @since 4.4.1 */ @@ -22,7 +22,7 @@ public class Morse { /** * 注册莫尔斯电码表 - * + * * @param abc 字母和字符 * @param dict 二进制 */ @@ -104,7 +104,7 @@ public class Morse { /** * 构造 - * + * * @param dit 点表示的字符 * @param dah 横线表示的字符 * @param split 分隔符 @@ -117,13 +117,13 @@ public class Morse { /** * 编码 - * + * * @param text 文本 * @return 密文 */ public String encode(String text) { Assert.notNull(text, "Text should not be null."); - + text = text.toUpperCase(); final StringBuilder morseBuilder = new StringBuilder(); final int len = text.codePointCount(0, text.length()); @@ -140,7 +140,7 @@ public class Morse { /** * 解码 - * + * * @param morse 莫尔斯电码 * @return 明文 */ diff --git a/hutool-core/src/main/java/cn/hutool/core/codec/Rot.java b/hutool-core/src/main/java/cn/hutool/core/codec/Rot.java index 48bb01c49..ff0cdd135 100644 --- a/hutool-core/src/main/java/cn/hutool/core/codec/Rot.java +++ b/hutool-core/src/main/java/cn/hutool/core/codec/Rot.java @@ -3,7 +3,7 @@ package cn.hutool.core.codec; /** * RotN(rotate by N places),回转N位密码,是一种简易的替换式密码,也是过去在古罗马开发的凯撒加密的一种变体。
              * 代码来自:https://github.com/orclight/jencrypt - * + * * @author looly,shuzhilong * @since 4.4.1 */ @@ -18,7 +18,7 @@ public class Rot { /** * Rot-13编码,同时编码数字 - * + * * @param message 被编码的消息 * @return 编码后的字符串 */ @@ -28,7 +28,7 @@ public class Rot { /** * Rot-13编码 - * + * * @param message 被编码的消息 * @param isEnocdeNumber 是否编码数字 * @return 编码后的字符串 @@ -39,7 +39,7 @@ public class Rot { /** * RotN编码 - * + * * @param message 被编码的消息 * @param offset 位移,常用位移13 * @param isEnocdeNumber 是否编码数字 @@ -57,7 +57,7 @@ public class Rot { /** * Rot-13解码,同时解码数字 - * + * * @param rot 被解码的消息密文 * @return 解码后的字符串 */ @@ -67,7 +67,7 @@ public class Rot { /** * Rot-13解码 - * + * * @param rot 被解码的消息密文 * @param isDecodeNumber 是否解码数字 * @return 解码后的字符串 @@ -78,7 +78,7 @@ public class Rot { /** * RotN解码 - * + * * @param rot 被解码的消息密文 * @param offset 位移,常用位移13 * @param isDecodeNumber 是否解码数字 @@ -97,7 +97,7 @@ public class Rot { // ------------------------------------------------------------------------------------------ Private method start /** * 解码字符 - * + * * @param c 字符 * @param offset 位移 * @param isDecodeNumber 是否解码数字 @@ -129,7 +129,7 @@ public class Rot { /** * 编码字符 - * + * * @param c 字符 * @param offset 位移 * @param isDecodeNumber 是否编码数字 diff --git a/hutool-core/src/main/java/cn/hutool/core/codec/package-info.java b/hutool-core/src/main/java/cn/hutool/core/codec/package-info.java index 921d1fca3..16774acaa 100644 --- a/hutool-core/src/main/java/cn/hutool/core/codec/package-info.java +++ b/hutool-core/src/main/java/cn/hutool/core/codec/package-info.java @@ -1,6 +1,6 @@ /** * BaseN以及BCD编码封装 - * + * * @author looly * */ diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/ArrayIter.java b/hutool-core/src/main/java/cn/hutool/core/collection/ArrayIter.java index 3a49b9c29..8463d6422 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/ArrayIter.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/ArrayIter.java @@ -58,7 +58,7 @@ public class ArrayIter implements Iterator, Iterable, Serializable{ if(endIndex > 0 && endIndex < this.endIndex){ this.endIndex = endIndex; } - + if(startIndex >=0 && startIndex < this.endIndex){ this.startIndex = startIndex; } diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/BoundedPriorityQueue.java b/hutool-core/src/main/java/cn/hutool/core/collection/BoundedPriorityQueue.java index 403ac62e0..7824ce727 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/BoundedPriorityQueue.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/BoundedPriorityQueue.java @@ -15,15 +15,15 @@ import java.util.PriorityQueue; */ public class BoundedPriorityQueue extends PriorityQueue{ private static final long serialVersionUID = 3794348988671694820L; - + //容量 private final int capacity; private final Comparator comparator; - + public BoundedPriorityQueue(int capacity) { this(capacity, null); } - + /** * 构造 * @param capacity 容量 @@ -63,7 +63,7 @@ public class BoundedPriorityQueue extends PriorityQueue{ } return super.offer(e); } - + /** * 添加多个元素
              * 参数为集合的情况请使用{@link PriorityQueue#addAll} @@ -73,7 +73,7 @@ public class BoundedPriorityQueue extends PriorityQueue{ public boolean addAll(E[] c) { return this.addAll(Arrays.asList(c)); } - + /** * @return 返回排序后的列表 */ @@ -82,7 +82,7 @@ public class BoundedPriorityQueue extends PriorityQueue{ list.sort(comparator); return list; } - + @Override public Iterator iterator() { return toList().iterator(); diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/CollectionUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/CollectionUtil.java index a1273374b..dde70af56 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/CollectionUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/CollectionUtil.java @@ -2,7 +2,7 @@ package cn.hutool.core.collection; /** * 集合相关工具类,包括数组,是{@link CollUtil} 的别名工具类类 - * + * * @author xiaoleilu * @see CollUtil */ diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java b/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java index 631875fbe..4760f8b39 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java @@ -7,7 +7,7 @@ import java.util.concurrent.ConcurrentHashMap; /** * 通过{@link ConcurrentHashMap}实现的线程安全HashSet - * + * * @author Looly * * @param 元素类型 @@ -32,7 +32,7 @@ public class ConcurrentHashSet extends AbstractSet implements java.io.Seri /** * 构造
              * 触发因子为默认的0.75 - * + * * @param initialCapacity 初始大小 */ public ConcurrentHashSet(int initialCapacity) { @@ -41,7 +41,7 @@ public class ConcurrentHashSet extends AbstractSet implements java.io.Seri /** * 构造 - * + * * @param initialCapacity 初始大小 * @param loadFactor 加载因子。此参数决定数据增长时触发的百分比 */ @@ -51,7 +51,7 @@ public class ConcurrentHashSet extends AbstractSet implements java.io.Seri /** * 构造 - * + * * @param initialCapacity 初始大小 * @param loadFactor 触发因子。此参数决定数据增长时触发的百分比 * @param concurrencyLevel 线程并发度 @@ -59,7 +59,7 @@ public class ConcurrentHashSet extends AbstractSet implements java.io.Seri public ConcurrentHashSet(int initialCapacity, float loadFactor, int concurrencyLevel) { map = new ConcurrentHashMap<>(initialCapacity, loadFactor, concurrencyLevel); } - + /** * 从已有集合中构造 * @param iter {@link Iterable} diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/CopiedIter.java b/hutool-core/src/main/java/cn/hutool/core/collection/CopiedIter.java index 9363202e8..d6ef1ed9e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/CopiedIter.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/CopiedIter.java @@ -8,14 +8,14 @@ import java.util.List; * 复制 {@link Iterator}
              * 为了解决并发情况下{@link Iterator}遍历导致的问题(当Iterator被修改会抛出ConcurrentModificationException) * ,故使用复制原Iterator的方式解决此问题。 - * + * *

              * 解决方法为:在构造方法中遍历Iterator中的元素,装入新的List中然后遍历之。 * 当然,修改这个复制后的Iterator是没有意义的,因此remove方法将会抛出异常。 - * + * *

              * 需要注意的是,在构造此对象时需要保证原子性(原对象不被修改),最好加锁构造此对象,构造完毕后解锁。 - * + * * * @param 元素类型 * @author Looly @@ -25,7 +25,7 @@ public class CopiedIter implements Iterator, Iterable, Serializable { private static final long serialVersionUID = 1L; private final Iterator listIterator; - + public static CopiedIter copyOf(Iterator iterator){ return new CopiedIter<>(iterator); } diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/EnumerationIter.java b/hutool-core/src/main/java/cn/hutool/core/collection/EnumerationIter.java index 06b2781b5..922f2d31a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/EnumerationIter.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/EnumerationIter.java @@ -13,9 +13,9 @@ import java.util.Iterator; */ public class EnumerationIter implements Iterator, Iterable, Serializable{ private static final long serialVersionUID = 1L; - + private final Enumeration e; - + /** * 构造 * @param enumeration {@link Enumeration}对象 diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/IteratorEnumeration.java b/hutool-core/src/main/java/cn/hutool/core/collection/IteratorEnumeration.java index 734a4602a..9beea2ca7 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/IteratorEnumeration.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/IteratorEnumeration.java @@ -13,9 +13,9 @@ import java.util.Iterator; */ public class IteratorEnumeration implements Enumeration, Serializable{ private static final long serialVersionUID = 1L; - + private final Iterator iterator; - + /** * 构造 * @param iterator {@link Iterator}对象 diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/LineIter.java b/hutool-core/src/main/java/cn/hutool/core/collection/LineIter.java index 1330440fe..eafbaa841 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/LineIter.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/LineIter.java @@ -17,7 +17,7 @@ import cn.hutool.core.lang.Assert; /** * 将Reader包装为一个按照行读取的Iterator
              * 此对象遍历结束后,应关闭之,推荐使用方式: - * + * *

                * LineIterator it = null;
                * try {
              @@ -30,7 +30,7 @@ import cn.hutool.core.lang.Assert;
                * 		it.close();
                * }
                * 
              - * + * * 此类来自于Apache Commons io * * @author looly @@ -45,7 +45,7 @@ public class LineIter implements Iterator, Iterable, Closeable, private String cachedLine; /** A flag indicating if the iterator has been fully read. */ private boolean finished = false; - + /** * 构造 * @@ -148,7 +148,7 @@ public class LineIter implements Iterator, Iterable, Closeable, /** * 重写此方法来判断是否每一行都被返回,默认全部为true - * + * * @param line 需要验证的行 * @return 是否通过验证 */ From 51d0d118ac7da7f3900c927178a9a987c73d8e02 Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 28 Feb 2021 12:14:05 +0800 Subject: [PATCH 32/47] fix code --- CHANGELOG.md | 3 ++- .../src/main/java/cn/hutool/json/XML.java | 4 +-- hutool-poi/pom.xml | 3 ++- .../main/java/cn/hutool/poi/word/DocUtil.java | 17 ++++++------ .../java/cn/hutool/poi/word/Word07Writer.java | 2 +- .../java/cn/hutool/socket/aio/AioClient.java | 26 ++++++++++--------- .../java/cn/hutool/socket/nio/NioClient.java | 1 + 7 files changed, 30 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05066f2e5..5e52baac8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,13 @@ ------------------------------------------------------------------------------------------------------------- -# 5.6.0 (2021-02-27) +# 5.6.0 (2021-02-28) ### 新特性 * 【poi 】 重要:不再兼容POI-3.x,增加兼容POI-5.x(issue#I35J6B@Gitee) ### Bug修复 +* 【socket 】 修复Client创建失败资源未释放问题。 ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-json/src/main/java/cn/hutool/json/XML.java b/hutool-json/src/main/java/cn/hutool/json/XML.java index 9687112dc..7dee8ef99 100644 --- a/hutool-json/src/main/java/cn/hutool/json/XML.java +++ b/hutool-json/src/main/java/cn/hutool/json/XML.java @@ -62,7 +62,7 @@ public class XML { /** * 转换XML为JSONObject * 转换过程中一些信息可能会丢失,JSON中无法区分节点和属性,相同的节点将被处理为JSONArray。 - * Content text may be placed in a "content" member. Comments, prologs, DTDs, and <[ [ ]]> are ignored. + * Content text may be placed in a "content" member. Comments, prologs, DTDs, and {@code <[ [ ]]>} are ignored. * * @param string The source string. * @return A JSONObject containing the structured data from the XML string. @@ -75,7 +75,7 @@ public class XML { /** * 转换XML为JSONObject * 转换过程中一些信息可能会丢失,JSON中无法区分节点和属性,相同的节点将被处理为JSONArray。 - * Content text may be placed in a "content" member. Comments, prologs, DTDs, and <[ [ ]]> are ignored. + * Content text may be placed in a "content" member. Comments, prologs, DTDs, and {@code <[ [ ]]>} are ignored. * All values are converted as strings, for 1, 01, 29.0 will not be coerced to numbers but will instead be the exact value as seen in the XML document. * * @param string The source string. diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index d5dd22f65..75757aa85 100644 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -40,10 +40,11 @@ compile true + org.ofdrw ofdrw-full - 1.7.2 + 1.7.3 compile true diff --git a/hutool-poi/src/main/java/cn/hutool/poi/word/DocUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/word/DocUtil.java index 1eb1c72f1..fb7e6fbbd 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/word/DocUtil.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/word/DocUtil.java @@ -1,19 +1,18 @@ package cn.hutool.poi.word; -import java.io.File; -import java.io.IOException; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xwpf.usermodel.XWPFDocument; - import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; import cn.hutool.poi.exceptions.POIException; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.xwpf.usermodel.XWPFDocument; + +import java.io.File; +import java.io.IOException; /** * Word Document工具 - * + * * @author looly * @since 4.4.1 */ @@ -21,7 +20,7 @@ public class DocUtil { /** * 创建{@link XWPFDocument},如果文件已存在则读取之,否则创建新的 - * + * * @param file docx文件 * @return {@link XWPFDocument} */ diff --git a/hutool-poi/src/main/java/cn/hutool/poi/word/Word07Writer.java b/hutool-poi/src/main/java/cn/hutool/poi/word/Word07Writer.java index 48bb446f6..837a57a7b 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/word/Word07Writer.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/word/Word07Writer.java @@ -21,7 +21,7 @@ import java.io.InputStream; import java.io.OutputStream; /** - * Word生成器 + * Word docx生成器 * * @author looly * @since 4.4.1 diff --git a/hutool-socket/src/main/java/cn/hutool/socket/aio/AioClient.java b/hutool-socket/src/main/java/cn/hutool/socket/aio/AioClient.java index 9c9505e75..2fb37713d 100644 --- a/hutool-socket/src/main/java/cn/hutool/socket/aio/AioClient.java +++ b/hutool-socket/src/main/java/cn/hutool/socket/aio/AioClient.java @@ -1,5 +1,11 @@ package cn.hutool.socket.aio; +import cn.hutool.core.io.IORuntimeException; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.thread.ThreadFactoryBuilder; +import cn.hutool.socket.SocketConfig; +import cn.hutool.socket.SocketRuntimeException; + import java.io.Closeable; import java.io.IOException; import java.net.InetSocketAddress; @@ -9,14 +15,9 @@ import java.nio.channels.AsynchronousChannelGroup; import java.nio.channels.AsynchronousSocketChannel; import java.util.concurrent.ExecutionException; -import cn.hutool.core.io.IORuntimeException; -import cn.hutool.core.thread.ThreadFactoryBuilder; -import cn.hutool.socket.SocketConfig; -import cn.hutool.socket.SocketRuntimeException; - /** * Aio Socket客户端 - * + * * @author looly * @since 4.5.0 */ @@ -26,7 +27,7 @@ public class AioClient implements Closeable{ /** * 构造 - * + * * @param address 地址 * @param ioAction IO处理类 */ @@ -36,7 +37,7 @@ public class AioClient implements Closeable{ /** * 构造 - * + * * @param address 地址 * @param ioAction IO处理类 * @param config 配置项 @@ -47,7 +48,7 @@ public class AioClient implements Closeable{ /** * 构造 - * + * * @param channel {@link AsynchronousSocketChannel} * @param ioAction IO处理类 * @param config 配置项 @@ -74,7 +75,7 @@ public class AioClient implements Closeable{ /** * 获取IO处理器 - * + * * @return {@link IoAction} */ public IoAction getIoAction() { @@ -83,7 +84,7 @@ public class AioClient implements Closeable{ /** * 从服务端读取数据 - * + * * @return this */ public AioClient read() { @@ -113,7 +114,7 @@ public class AioClient implements Closeable{ // ------------------------------------------------------------------------------------- Private method start /** * 初始化 - * + * * @param address 地址和端口 * @param poolSize 线程池大小 * @return this @@ -134,6 +135,7 @@ public class AioClient implements Closeable{ try { channel.connect(address).get(); } catch (InterruptedException | ExecutionException e) { + IoUtil.close(channel); throw new SocketRuntimeException(e); } return channel; diff --git a/hutool-socket/src/main/java/cn/hutool/socket/nio/NioClient.java b/hutool-socket/src/main/java/cn/hutool/socket/nio/NioClient.java index b235b1bdd..f56bd531d 100644 --- a/hutool-socket/src/main/java/cn/hutool/socket/nio/NioClient.java +++ b/hutool-socket/src/main/java/cn/hutool/socket/nio/NioClient.java @@ -66,6 +66,7 @@ public class NioClient implements Closeable { //noinspection StatementWithEmptyBody while (false == channel.finishConnect()){} } catch (IOException e) { + close(); throw new IORuntimeException(e); } return this; From 530151fbfd32114013e6ed25d20a772a5ac3548b Mon Sep 17 00:00:00 2001 From: weisz Date: Thu, 4 Mar 2021 11:13:34 +0800 Subject: [PATCH 33/47] fix FileTypeUtil --- .../java/cn/hutool/core/io/FileTypeUtil.java | 37 ++++++++++++------- .../cn/hutool/core/io/FileTypeUtilTest.java | 21 +++++++++-- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java index 0e6659a5f..e5955b817 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java @@ -5,7 +5,7 @@ import java.io.FileInputStream; import java.io.InputStream; import java.util.Map; import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListMap; import cn.hutool.core.util.StrUtil; @@ -23,7 +23,15 @@ public class FileTypeUtil { private static final Map FILE_TYPE_MAP; static { - FILE_TYPE_MAP = new ConcurrentHashMap<>(); + FILE_TYPE_MAP = new ConcurrentSkipListMap<>((s1, s2) -> { + int len1 = s1.length(); + int len2 = s2.length(); + if (len1 == len2) { + return s1.compareTo(s2); + } else { + return len2 - len1; + } + }); FILE_TYPE_MAP.put("ffd8ff", "jpg"); // JPEG (jpg) FILE_TYPE_MAP.put("89504e47", "png"); // PNG (png) @@ -50,22 +58,23 @@ public class FileTypeUtil { FILE_TYPE_MAP.put("52494646e27807005741", "wav"); // Wave (wav) FILE_TYPE_MAP.put("52494646d07d60074156", "avi"); FILE_TYPE_MAP.put("4d546864000000060001", "mid"); // MIDI (mid) - FILE_TYPE_MAP.put("526172211a0700cf9073", "rar");// WinRAR + FILE_TYPE_MAP.put("526172211a0700cf9073", "rar"); // WinRAR FILE_TYPE_MAP.put("235468697320636f6e66", "ini"); + FILE_TYPE_MAP.put("504B0304140000000800", "odf"); // ofd文件 国标版式文件 FILE_TYPE_MAP.put("504B03040a0000000000", "jar"); FILE_TYPE_MAP.put("504B0304140008000800", "jar"); // MS Excel 注意:word、msi 和 excel的文件头一样 FILE_TYPE_MAP.put("d0cf11e0a1b11ae10", "xls"); FILE_TYPE_MAP.put("504B0304", "zip"); - FILE_TYPE_MAP.put("4d5a9000030000000400", "exe");// 可执行文件 - FILE_TYPE_MAP.put("3c25402070616765206c", "jsp");// jsp文件 - FILE_TYPE_MAP.put("4d616e69666573742d56", "mf");// MF文件 - FILE_TYPE_MAP.put("7061636b616765207765", "java");// java文件 - FILE_TYPE_MAP.put("406563686f206f66660d", "bat");// bat文件 - FILE_TYPE_MAP.put("1f8b0800000000000000", "gz");// gz文件 - FILE_TYPE_MAP.put("cafebabe0000002e0041", "class");// bat文件 - FILE_TYPE_MAP.put("49545346030000006000", "chm");// bat文件 - FILE_TYPE_MAP.put("04000000010000001300", "mxp");// bat文件 + FILE_TYPE_MAP.put("4d5a9000030000000400", "exe"); // 可执行文件 + FILE_TYPE_MAP.put("3c25402070616765206c", "jsp"); // jsp文件 + FILE_TYPE_MAP.put("4d616e69666573742d56", "mf"); // MF文件 + FILE_TYPE_MAP.put("7061636b616765207765", "java"); // java文件 + FILE_TYPE_MAP.put("406563686f206f66660d", "bat"); // bat文件 + FILE_TYPE_MAP.put("1f8b0800000000000000", "gz"); // gz文件 + FILE_TYPE_MAP.put("cafebabe0000002e0041", "class"); // class文件 + FILE_TYPE_MAP.put("49545346030000006000", "chm"); // chm文件 + FILE_TYPE_MAP.put("04000000010000001300", "mxp"); // mxp文件 FILE_TYPE_MAP.put("6431303a637265617465", "torrent"); FILE_TYPE_MAP.put("6D6F6F76", "mov"); // Quicktime (mov) FILE_TYPE_MAP.put("FF575043", "wpd"); // WordPerfect (wpd) @@ -85,7 +94,7 @@ public class FileTypeUtil { * @return 之前已经存在的文件扩展名 */ public static String putFileType(String fileStreamHexHead, String extName) { - return FILE_TYPE_MAP.put(fileStreamHexHead.toLowerCase(), extName); + return FILE_TYPE_MAP.put(fileStreamHexHead, extName); } /** @@ -95,7 +104,7 @@ public class FileTypeUtil { * @return 移除的文件扩展名 */ public static String removeFileType(String fileStreamHexHead) { - return FILE_TYPE_MAP.remove(fileStreamHexHead.toLowerCase()); + return FILE_TYPE_MAP.remove(fileStreamHexHead); } /** diff --git a/hutool-core/src/test/java/cn/hutool/core/io/FileTypeUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/io/FileTypeUtilTest.java index 0eda487da..6d4775cba 100644 --- a/hutool-core/src/test/java/cn/hutool/core/io/FileTypeUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/io/FileTypeUtilTest.java @@ -6,6 +6,9 @@ import org.junit.Ignore; import org.junit.Test; import java.io.File; +import java.lang.reflect.Field; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * 文件类型判断单元测试 @@ -13,19 +16,19 @@ import java.io.File; * */ public class FileTypeUtilTest { - + @Test @Ignore public void fileTypeUtilTest() { File file = FileUtil.file("hutool.jpg"); String type = FileTypeUtil.getType(file); Assert.assertEquals("jpg", type); - + FileTypeUtil.putFileType("ffd8ffe000104a464946", "new_jpg"); String newType = FileTypeUtil.getType(file); Assert.assertEquals("new_jpg", newType); } - + @Test @Ignore public void emptyTest() { @@ -41,4 +44,16 @@ public class FileTypeUtilTest { String type = FileTypeUtil.getType(file); Console.log(type); } + + @Test + @Ignore + public void ofdTest() { + File file = FileUtil.file("e:/test.ofd"); + String hex = IoUtil.readHex28Upper(FileUtil.getInputStream(file)); + Console.log(hex); + String type = FileTypeUtil.getType(file); + Console.log(type); + Assert.assertEquals("odf", type); + } + } From 3a22d7e0daa26fbaee691c846a16d6ad46a98990 Mon Sep 17 00:00:00 2001 From: weisz Date: Thu, 4 Mar 2021 11:35:58 +0800 Subject: [PATCH 34/47] fix FileTypeUtil --- hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java | 2 +- .../src/test/java/cn/hutool/core/io/FileTypeUtilTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java index e5955b817..3da7555a4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java @@ -60,7 +60,7 @@ public class FileTypeUtil { FILE_TYPE_MAP.put("4d546864000000060001", "mid"); // MIDI (mid) FILE_TYPE_MAP.put("526172211a0700cf9073", "rar"); // WinRAR FILE_TYPE_MAP.put("235468697320636f6e66", "ini"); - FILE_TYPE_MAP.put("504B0304140000000800", "odf"); // ofd文件 国标版式文件 + FILE_TYPE_MAP.put("504B0304140000000800", "ofd"); // ofd文件 国标版式文件 FILE_TYPE_MAP.put("504B03040a0000000000", "jar"); FILE_TYPE_MAP.put("504B0304140008000800", "jar"); // MS Excel 注意:word、msi 和 excel的文件头一样 diff --git a/hutool-core/src/test/java/cn/hutool/core/io/FileTypeUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/io/FileTypeUtilTest.java index 6d4775cba..16b8d2bea 100644 --- a/hutool-core/src/test/java/cn/hutool/core/io/FileTypeUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/io/FileTypeUtilTest.java @@ -53,7 +53,7 @@ public class FileTypeUtilTest { Console.log(hex); String type = FileTypeUtil.getType(file); Console.log(type); - Assert.assertEquals("odf", type); + Assert.assertEquals("ofd", type); } } From 8097cc710e2905ba056ac0cd215d0203fe7e0b87 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 5 Mar 2021 15:50:19 +0800 Subject: [PATCH 35/47] fix comment --- .../src/main/java/cn/hutool/json/JSONNull.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONNull.java b/hutool-json/src/main/java/cn/hutool/json/JSONNull.java index 6ae2b03cf..93599a3cf 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONNull.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONNull.java @@ -5,8 +5,8 @@ import cn.hutool.core.util.StrUtil; import java.io.Serializable; /** - * 用于定义null,与Javascript中null相对应
              - * Java中的null值在js中表示为undefined。 + * 用于定义{@code null},与Javascript中null相对应
              + * Java中的{@code null}值在js中表示为undefined。 * @author Looly * */ @@ -14,15 +14,15 @@ public class JSONNull implements Serializable{ private static final long serialVersionUID = 2633815155870764938L; /** - * NULL 对象用于减少歧义来表示Java 中的null
              - * NULL.equals(null) 返回 true.
              - * NULL.toString() 返回 "null". + * {@code NULL} 对象用于减少歧义来表示Java 中的{@code null}
              + * {@code NULL.equals(null)} 返回 {@code true}.
              + * {@code NULL.toString()} 返回 {@code "null"}. */ public static final JSONNull NULL = new JSONNull(); /** * A Null object is equal to the null value and to itself. - * 对象与其本身和null值相等 + * 对象与其本身和{@code null}值相等 * * @param object An object to test for nullness. * @return true if the object parameter is the JSONObject.NULL object or null. @@ -32,7 +32,7 @@ public class JSONNull implements Serializable{ public boolean equals(Object object) { return object == null || (object == this); } - + /** * Get the "null" string value. *获得“null”字符串 @@ -43,4 +43,4 @@ public class JSONNull implements Serializable{ public String toString() { return StrUtil.NULL; } -} \ No newline at end of file +} From b654e89e22cdead9c774d24902633664598bec5e Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 5 Mar 2021 16:38:59 +0800 Subject: [PATCH 36/47] fix FileTypeUtil --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e52baac8..9decc9000 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,11 @@ ------------------------------------------------------------------------------------------------------------- -# 5.6.0 (2021-02-28) +# 5.6.0 (2021-03-05) ### 新特性 * 【poi 】 重要:不再兼容POI-3.x,增加兼容POI-5.x(issue#I35J6B@Gitee) +* 【core 】 FileTypeUtil使用长匹配优先(pr#1457@Github) ### Bug修复 * 【socket 】 修复Client创建失败资源未释放问题。 From 626691adecbb8d86391d1f32c6bf5f56b52d8c93 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 5 Mar 2021 19:13:20 +0800 Subject: [PATCH 37/47] =?UTF-8?q?add=20isEqualList=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../cn/hutool/core/collection/CollUtil.java | 21 ++++++++++ .../cn/hutool/core/collection/IterUtil.java | 38 ++++++++++++++++++- 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9decc9000..4c888ca19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### 新特性 * 【poi 】 重要:不再兼容POI-3.x,增加兼容POI-5.x(issue#I35J6B@Gitee) * 【core 】 FileTypeUtil使用长匹配优先(pr#1457@Github) +* 【core 】 IterUtil和CollUtil增加isEqualList方法(issue#I3A3PY@Gitee) ### Bug修复 * 【socket 】 修复Client创建失败资源未释放问题。 diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java index 9c8819f22..927ecb69e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java @@ -2988,4 +2988,25 @@ public class CollUtil { } return total; } + + /** + * 判断两个{@link Collection} 是否元素和顺序相同,返回{@code true}的条件是: + *
                + *
              • 两个{@link Collection}必须长度相同
              • + *
              • 两个{@link Collection}元素相同index的对象必须equals,满足{@link Objects#equals(Object, Object)}
              • + *
              + * 此方法来自Apache-Commons-Collections4。 + * + * @param list1 列表1 + * @param list2 列表2 + * @return 是否相同 + * @since 5.6.0 + */ + public static boolean isEqualList(final Collection list1, final Collection list2) { + if (list1 == null || list2 == null || list1.size() != list2.size()) { + return false; + } + + return IterUtil.isEqualList(list1, list2); + } } diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java index 931af5f44..ad41f8699 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java @@ -18,6 +18,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.function.Function; /** @@ -612,7 +613,7 @@ public class IterUtil { /** * Enumeration转换为Iterator *

              - * Adapt the specified Enumeration to the Iterator interface + * Adapt the specified {@code Enumeration} to the {@code Iterator} interface * * @param 集合元素类型 * @param e {@link Enumeration} @@ -859,4 +860,39 @@ public class IterUtil { } return size; } + + /** + * 判断两个{@link Iterable} 是否元素和顺序相同,返回{@code true}的条件是: + *

                + *
              • 两个{@link Iterable}必须长度相同
              • + *
              • 两个{@link Iterable}元素相同index的对象必须equals,满足{@link Objects#equals(Object, Object)}
              • + *
              + * 此方法来自Apache-Commons-Collections4。 + * + * @param list1 列表1 + * @param list2 列表2 + * @return 是否相同 + * @since 5.6.0 + */ + public static boolean isEqualList(final Iterable list1, final Iterable list2) { + if (list1 == list2) { + return true; + } + + final Iterator it1 = list1.iterator(); + final Iterator it2 = list2.iterator(); + Object obj1; + Object obj2; + while (it1.hasNext() && it2.hasNext()) { + obj1 = it1.next(); + obj2 = it2.next(); + + if (false == Objects.equals(obj1, obj2)) { + return false; + } + } + + // 当两个Iterable长度不一致时返回false + return false == (it1.hasNext() || it2.hasNext()); + } } From d0f37fe46046d4b41995445d80b6596dd87d8098 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 5 Mar 2021 20:25:21 +0800 Subject: [PATCH 38/47] fix dta size bug --- CHANGELOG.md | 1 + .../src/main/java/cn/hutool/core/io/unit/DataUnit.java | 4 ++-- .../java/cn/hutool/core/io/unit/DataSizeUtilTest.java | 10 ++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c888ca19..15a28fb9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Bug修复 * 【socket 】 修复Client创建失败资源未释放问题。 +* 【core 】 修复DataSizeUtil中EB单位错误问题(issue#I39O7I@Gitee) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/io/unit/DataUnit.java b/hutool-core/src/main/java/cn/hutool/core/io/unit/DataUnit.java index 3133fdbf8..6a95b8dc0 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/unit/DataUnit.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/unit/DataUnit.java @@ -44,7 +44,7 @@ public enum DataUnit { */ TERABYTES("TB", DataSize.ofTerabytes(1)); - public static final String[] UNIT_NAMES = new String[]{"B", "kB", "MB", "GB", "TB", "EB"}; + public static final String[] UNIT_NAMES = new String[]{"B", "kB", "MB", "GB", "TB", "PB", "EB"}; private final String suffix; @@ -77,4 +77,4 @@ public enum DataUnit { throw new IllegalArgumentException("Unknown data unit suffix '" + suffix + "'"); } -} \ No newline at end of file +} diff --git a/hutool-core/src/test/java/cn/hutool/core/io/unit/DataSizeUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/io/unit/DataSizeUtilTest.java index 2baeaf34c..dcdc60057 100644 --- a/hutool-core/src/test/java/cn/hutool/core/io/unit/DataSizeUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/io/unit/DataSizeUtilTest.java @@ -51,7 +51,13 @@ public class DataSizeUtilTest { @Test public void formatTest(){ - final String format = DataSizeUtil.format(Long.MAX_VALUE); - Assert.assertEquals("8,192 EB", format); + String format = DataSizeUtil.format(Long.MAX_VALUE); + Assert.assertEquals("8 EB", format); + + format = DataSizeUtil.format(1024L * 1024 * 1024 * 1024 * 1024); + Assert.assertEquals("1 PB", format); + + format = DataSizeUtil.format(1024L * 1024 * 1024 * 1024); + Assert.assertEquals("1 TB", format); } } From 71a82e053463394af1be80059345d4a29bc2d674 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 5 Mar 2021 21:07:36 +0800 Subject: [PATCH 39/47] add PBKDF2 --- CHANGELOG.md | 1 + .../java/cn/hutool/crypto/SecureUtil.java | 13 ++++ .../cn/hutool/crypto/symmetric/PBKDF2.java | 66 +++++++++++++++++++ .../crypto/test/symmetric/PBKDF2Test.java | 15 +++++ 4 files changed, 95 insertions(+) create mode 100644 hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/PBKDF2.java create mode 100644 hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/PBKDF2Test.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 15a28fb9c..a8c6f0685 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * 【poi 】 重要:不再兼容POI-3.x,增加兼容POI-5.x(issue#I35J6B@Gitee) * 【core 】 FileTypeUtil使用长匹配优先(pr#1457@Github) * 【core 】 IterUtil和CollUtil增加isEqualList方法(issue#I3A3PY@Gitee) +* 【crypto 】 增加PBKDF2(issue#1416@Github) ### Bug修复 * 【socket 】 修复Client创建失败资源未释放问题。 diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/SecureUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/SecureUtil.java index ddb39e1ee..17c0da0f2 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/SecureUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/SecureUtil.java @@ -19,6 +19,7 @@ import cn.hutool.crypto.digest.MD5; import cn.hutool.crypto.symmetric.AES; import cn.hutool.crypto.symmetric.DES; import cn.hutool.crypto.symmetric.DESede; +import cn.hutool.crypto.symmetric.PBKDF2; import cn.hutool.crypto.symmetric.RC4; import cn.hutool.crypto.symmetric.SymmetricCrypto; @@ -1048,4 +1049,16 @@ public final class SecureUtil { public static void disableBouncyCastle() { GlobalBouncyCastleProvider.setUseBouncyCastle(false); } + + /** + * PBKDF2加密密码 + * + * @param password 密码 + * @param salt 盐 + * @return 盐,一般为16位 + * @since 5.6.0 + */ + public static String pbkdf2(char[] password, byte[] salt){ + return new PBKDF2().encryptHex(password, salt); + } } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/PBKDF2.java b/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/PBKDF2.java new file mode 100644 index 000000000..059660afe --- /dev/null +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/PBKDF2.java @@ -0,0 +1,66 @@ +package cn.hutool.crypto.symmetric; + +import cn.hutool.core.util.HexUtil; +import cn.hutool.crypto.KeyUtil; + +import javax.crypto.SecretKey; +import javax.crypto.spec.PBEKeySpec; + +/** + * PBKDF2应用一个伪随机函数以导出密钥,PBKDF2简单而言就是将salted hash进行多次重复计算。 + * 参考:https://blog.csdn.net/huoji555/article/details/83659687 + * + * @author looly + */ +public class PBKDF2 { + + private String algorithm = "PBKDF2WithHmacSHA1"; + //生成密文的长度 + private int keyLength = 512; + + //迭代次数 + private int iterationCount = 1000; + + /** + * 构造,算法PBKDF2WithHmacSHA1,盐长度16,密文长度512,迭代次数1000 + */ + public PBKDF2() { + } + + /** + * 构造 + * + * @param algorithm 算法,一般为PBKDF2WithXXX + * @param keyLength 生成密钥长度,默认512 + * @param iterationCount 迭代次数,默认1000 + */ + public PBKDF2(String algorithm, int keyLength, int iterationCount) { + this.algorithm = algorithm; + this.keyLength = keyLength; + this.iterationCount = iterationCount; + } + + /** + * 加密 + * + * @param password 密码 + * @param salt 盐 + * @return 加密后的密码 + */ + public byte[] encrypt(char[] password, byte[] salt) { + final PBEKeySpec pbeKeySpec = new PBEKeySpec(password, salt, iterationCount, keyLength); + final SecretKey secretKey = KeyUtil.generateKey(algorithm, pbeKeySpec); + return secretKey.getEncoded(); + } + + /** + * 加密 + * + * @param password 密码 + * @param salt 盐 + * @return 加密后的密码 + */ + public String encryptHex(char[] password, byte[] salt) { + return HexUtil.encodeHexStr(encrypt(password, salt)); + } +} diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/PBKDF2Test.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/PBKDF2Test.java new file mode 100644 index 000000000..780781ee2 --- /dev/null +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/PBKDF2Test.java @@ -0,0 +1,15 @@ +package cn.hutool.crypto.test.symmetric; + +import cn.hutool.core.util.RandomUtil; +import cn.hutool.crypto.SecureUtil; +import org.junit.Assert; +import org.junit.Test; + +public class PBKDF2Test { + + @Test + public void encryptTest(){ + final String s = SecureUtil.pbkdf2("123456".toCharArray(), RandomUtil.randomBytes(16)); + Assert.assertEquals(128, s.length()); + } +} From 047be5a1f86177df13ccad7382cc7877d0fa820d Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 5 Mar 2021 21:22:31 +0800 Subject: [PATCH 40/47] add FuncKeyMap --- CHANGELOG.md | 1 + .../java/cn/hutool/core/map/FuncKeyMap.java | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 hutool-core/src/main/java/cn/hutool/core/map/FuncKeyMap.java diff --git a/CHANGELOG.md b/CHANGELOG.md index a8c6f0685..c9cee9314 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * 【core 】 FileTypeUtil使用长匹配优先(pr#1457@Github) * 【core 】 IterUtil和CollUtil增加isEqualList方法(issue#I3A3PY@Gitee) * 【crypto 】 增加PBKDF2(issue#1416@Github) +* 【core 】 增加FuncKeyMap(issue#1402@Github) ### Bug修复 * 【socket 】 修复Client创建失败资源未释放问题。 diff --git a/hutool-core/src/main/java/cn/hutool/core/map/FuncKeyMap.java b/hutool-core/src/main/java/cn/hutool/core/map/FuncKeyMap.java new file mode 100644 index 000000000..e9589c9d8 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/map/FuncKeyMap.java @@ -0,0 +1,45 @@ +package cn.hutool.core.map; + +import java.util.Map; +import java.util.function.Function; + +/** + * 自定义函数Key风格的Map + * + * @param 键类型 + * @param 值类型 + * @author Looly + * @since 5.6.0 + */ +public class FuncKeyMap extends CustomKeyMap { + private static final long serialVersionUID = 1L; + + private Function keyFunc; + + // ------------------------------------------------------------------------- Constructor start + + /** + * 构造 + * + * @param m Map + * @param keyFunc 自定义KEY的函数 + */ + public FuncKeyMap(Map m, Function keyFunc) { + super(m); + } + // ------------------------------------------------------------------------- Constructor end + + /** + * 将Key转为驼峰风格,如果key为字符串的话 + * + * @param key KEY + * @return 驼峰Key + */ + @Override + protected Object customKey(Object key) { + if (null != this.keyFunc) { + return keyFunc.apply(key); + } + return key; + } +} From 5646a1c3c0589a756372c433cfa5c8293961f90e Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 5 Mar 2021 22:37:41 +0800 Subject: [PATCH 41/47] add StrMatcher --- CHANGELOG.md | 1 + .../java/cn/hutool/core/text/StrMatcher.java | 103 ++++++++++++++++++ .../cn/hutool/core/text/StrMatcherTest.java | 16 +++ 3 files changed, 120 insertions(+) create mode 100644 hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java create mode 100644 hutool-core/src/test/java/cn/hutool/core/text/StrMatcherTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index c9cee9314..67ed84e2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * 【core 】 IterUtil和CollUtil增加isEqualList方法(issue#I3A3PY@Gitee) * 【crypto 】 增加PBKDF2(issue#1416@Github) * 【core 】 增加FuncKeyMap(issue#1402@Github) +* 【core 】 增加StrMatcher(issue#1379@Github) ### Bug修复 * 【socket 】 修复Client创建失败资源未释放问题。 diff --git a/hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java b/hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java new file mode 100644 index 000000000..f6ef39c98 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java @@ -0,0 +1,103 @@ +package cn.hutool.core.text; + +import cn.hutool.core.lang.Console; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 字符串模式匹配,使用${XXXXX}作为变量,例如: + * + *
              + *     pattern: ${name}-${age}-${gender}-${country}-${province}-${city}-${status}
              + *     text:    "小明-19-男-中国-河南-郑州-已婚"
              + *     result:  {name=小明, age=19, gender=男, country=中国, province=河南, city=郑州, status=已婚}
              + * 
              + * + * @author looly + * @since 5.6.0 + */ +public class StrMatcher { + + List patterns; + + public StrMatcher(String pattern) { + this.patterns = parse(pattern); + Console.log(this.patterns); + } + + public Map match(String text) { + final HashMap result = MapUtil.newHashMap(true); + int from = 0; + String key = null; + int to; + for (String part : patterns) { + if (StrUtil.isWrap(part, "${", "}")) { + // 变量 + key = StrUtil.sub(part, 2, part.length() - 1); + } else { + to = text.indexOf(part, from); + if (null != key && to > from) { + // 变量对应部分有内容 + result.put(key, text.substring(from, to)); + } + from = to + 1; + key = null; + } + } + + if (null != key && from < text.length()) { + // 变量对应部分有内容 + result.put(key, text.substring(from)); + } + + return result; + } + + /** + * 解析表达式 + * @param pattern 表达式,使用${XXXX}作为变量占位符 + * @return 表达式 + */ + private static List parse(String pattern) { + List patterns = new ArrayList<>(); + final int length = pattern.length(); + char c = 0; + char pre; + boolean inVar = false; + StrBuilder part = StrUtil.strBuilder(); + for (int i = 0; i < length; i++) { + pre = c; + c = pattern.charAt(i); + if (inVar) { + part.append(c); + if ('}' == c) { + // 变量结束 + inVar = false; + patterns.add(part.toString()); + part.clear(); + } + } else if ('{' == c && '$' == pre) { + // 变量开始 + inVar = true; + final String preText = part.subString(0, part.length() - 1); + if (StrUtil.isNotEmpty(preText)) { + patterns.add(preText); + } + part.reset().append(pre).append(c); + } else { + // 普通字符 + part.append(c); + } + } + + if (part.length() > 0) { + patterns.add(part.toString()); + } + return patterns; + } +} diff --git a/hutool-core/src/test/java/cn/hutool/core/text/StrMatcherTest.java b/hutool-core/src/test/java/cn/hutool/core/text/StrMatcherTest.java new file mode 100644 index 000000000..12c59c840 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/text/StrMatcherTest.java @@ -0,0 +1,16 @@ +package cn.hutool.core.text; + +import cn.hutool.core.lang.Console; +import org.junit.Test; + +import java.util.Map; + +public class StrMatcherTest { + + @Test + public void matcherTest(){ + final StrMatcher strMatcher = new StrMatcher("${name}-${age}-${gender}-${country}-${province}-${city}-${status}"); + final Map match = strMatcher.match("小明-19-男-中国-河南-郑州-已婚"); + Console.log(match); + } +} From f5172ef42b36c4a7b4e7afffc00e6c07390e2c12 Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 7 Mar 2021 10:41:21 +0800 Subject: [PATCH 42/47] fix code --- .../java/cn/hutool/core/text/StrMatcher.java | 19 ++++++++++++++++--- .../cn/hutool/core/text/StrMatcherTest.java | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java b/hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java index f6ef39c98..e5bbc60ab 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java @@ -1,6 +1,5 @@ package cn.hutool.core.text; -import cn.hutool.core.lang.Console; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; @@ -25,11 +24,20 @@ public class StrMatcher { List patterns; + /** + * 构造 + * + * @param pattern 模式,变量用${XXX}占位 + */ public StrMatcher(String pattern) { this.patterns = parse(pattern); - Console.log(this.patterns); } + /** + * 匹配并提取匹配到的内容 + * @param text 被匹配的文本 + * @return 匹配的map,key为变量名,value为匹配到的值 + */ public Map match(String text) { final HashMap result = MapUtil.newHashMap(true); int from = 0; @@ -41,11 +49,16 @@ public class StrMatcher { key = StrUtil.sub(part, 2, part.length() - 1); } else { to = text.indexOf(part, from); + if(to < 0){ + //普通字符串未匹配到,说明整个模式不能匹配,返回空 + return MapUtil.empty(); + } if (null != key && to > from) { // 变量对应部分有内容 result.put(key, text.substring(from, to)); } - from = to + 1; + // 下一个起始点是普通字符串的末尾 + from = to + part.length(); key = null; } } diff --git a/hutool-core/src/test/java/cn/hutool/core/text/StrMatcherTest.java b/hutool-core/src/test/java/cn/hutool/core/text/StrMatcherTest.java index 12c59c840..4ebf4ff9a 100644 --- a/hutool-core/src/test/java/cn/hutool/core/text/StrMatcherTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/text/StrMatcherTest.java @@ -1,6 +1,7 @@ package cn.hutool.core.text; import cn.hutool.core.lang.Console; +import org.junit.Assert; import org.junit.Test; import java.util.Map; @@ -13,4 +14,22 @@ public class StrMatcherTest { final Map match = strMatcher.match("小明-19-男-中国-河南-郑州-已婚"); Console.log(match); } + + @Test + public void matcherTest2(){ + // 当有无匹配项的时候,按照全不匹配对待 + final StrMatcher strMatcher = new StrMatcher("${name}-${age}-${gender}-${country}-${province}-${city}-${status}"); + final Map match = strMatcher.match("小明-19-男-中国-河南-郑州"); + Assert.assertEquals(0, match.size()); + } + + @Test + public void matcherTest3(){ + // 当有无匹配项的时候,按照全不匹配对待 + final StrMatcher strMatcher = new StrMatcher("${name}经过${year}年"); + final Map match = strMatcher.match("小明经过20年,成长为一个大人。"); + Console.log(match); + Assert.assertEquals("小明", match.get("name")); + Assert.assertEquals("20", match.get("year")); + } } From 87813ae8987016f7fed9907c6fe007bd700a58d4 Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 7 Mar 2021 11:39:03 +0800 Subject: [PATCH 43/47] add method --- CHANGELOG.md | 3 +- .../java/cn/hutool/core/util/NumberUtil.java | 54 ++++++++++++++- .../cn/hutool/core/util/NumberUtilTest.java | 67 ++++++++++++------- 3 files changed, 98 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67ed84e2b..36780cfc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.6.0 (2021-03-05) +# 5.6.0 (2021-03-07) ### 新特性 * 【poi 】 重要:不再兼容POI-3.x,增加兼容POI-5.x(issue#I35J6B@Gitee) @@ -12,6 +12,7 @@ * 【crypto 】 增加PBKDF2(issue#1416@Github) * 【core 】 增加FuncKeyMap(issue#1402@Github) * 【core 】 增加StrMatcher(issue#1379@Github) +* 【core 】 NumberUtil增加factorial针对BigInterger方法(issue#1379@Github) ### Bug修复 * 【socket 】 修复Client创建失败资源未释放问题。 diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java index 6d4698c6c..de890ec7e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java @@ -1428,10 +1428,62 @@ public class NumberUtil { // ------------------------------------------------------------------------------------------- others + /** + * 计算阶乘 + *

              + * n! = n * (n-1) * ... * 2 * 1 + *

              + * + * @param n 阶乘起始 + * @return 结果 + * @since 5.6.0 + */ + public static BigInteger factorial(BigInteger n) { + if(n.equals(BigInteger.ZERO)){ + return BigInteger.ONE; + } + return factorial(n, BigInteger.ZERO); + } + /** * 计算范围阶乘 *

              - * factorial(start, end) = start * (start - 1) * ... * (end - 1) + * factorial(start, end) = start * (start - 1) * ... * (end + 1) + *

              + * + * @param start 阶乘起始(包含) + * @param end 阶乘结束,必须小于起始(不包括) + * @return 结果 + * @since 5.6.0 + */ + public static BigInteger factorial(BigInteger start, BigInteger end) { + Assert.notNull(start, "Factorial start must be not null!"); + Assert.notNull(end, "Factorial end must be not null!"); + if(start.compareTo(BigInteger.ZERO) < 0 || end.compareTo(BigInteger.ZERO) < 0){ + throw new IllegalArgumentException(StrUtil.format("Factorial start and end both must be > 0, but got start={}, end={}", start, end)); + } + + if (start.equals(BigInteger.ZERO)){ + start = BigInteger.ONE; + } + + if(end.compareTo(BigInteger.ONE) < 0){ + end = BigInteger.ONE; + } + + BigInteger result = start; + end = end.add(BigInteger.ONE); + while(start.compareTo(end) > 0) { + start = start.subtract(BigInteger.ONE); + result = result.multiply(start); + } + return result; + } + + /** + * 计算范围阶乘 + *

              + * factorial(start, end) = start * (start - 1) * ... * (end + 1) *

              * * @param start 阶乘起始(包含) diff --git a/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java index a6546efcd..116b75ddc 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java @@ -5,17 +5,18 @@ import org.junit.Assert; import org.junit.Test; import java.math.BigDecimal; +import java.math.BigInteger; import java.math.RoundingMode; import java.util.Set; /** * {@link NumberUtil} 单元测试类 - * + * * @author Looly * */ public class NumberUtilTest { - + @Test public void addTest() { Float a = 3.15f; @@ -23,7 +24,7 @@ public class NumberUtilTest { double result = NumberUtil.add(a, b).doubleValue(); Assert.assertEquals(7.37, result, 2); } - + @Test public void addTest2() { double a = 3.15f; @@ -31,7 +32,7 @@ public class NumberUtilTest { double result = NumberUtil.add(a, b); Assert.assertEquals(7.37, result, 2); } - + @Test public void addTest3() { float a = 3.15f; @@ -39,13 +40,13 @@ public class NumberUtilTest { double result = NumberUtil.add(a, b, a, b).doubleValue(); Assert.assertEquals(14.74, result, 2); } - + @Test public void addTest4() { BigDecimal result = NumberUtil.add(new BigDecimal("133"), new BigDecimal("331")); Assert.assertEquals(new BigDecimal("464"), result); } - + @Test public void isIntegerTest() { Assert.assertTrue(NumberUtil.isInteger("-12")); @@ -54,7 +55,7 @@ public class NumberUtilTest { Assert.assertTrue(NumberUtil.isInteger("0")); Assert.assertFalse(NumberUtil.isInteger("23.4")); } - + @Test public void isLongTest() { Assert.assertTrue(NumberUtil.isLong("-12")); @@ -63,7 +64,7 @@ public class NumberUtilTest { Assert.assertTrue(NumberUtil.isLong("0")); Assert.assertFalse(NumberUtil.isLong("23.4")); } - + @Test public void isNumberTest() { Assert.assertTrue(NumberUtil.isNumber("28.55")); @@ -78,7 +79,7 @@ public class NumberUtilTest { double result = NumberUtil.div(0, 1); Assert.assertEquals(0.0, result, 0); } - + @Test public void roundTest() { @@ -93,7 +94,7 @@ public class NumberUtilTest { String round4 = NumberUtil.roundStr("2.675", 2); Assert.assertEquals("2.68", round3); Assert.assertEquals("2.68", round4); - + // 四舍六入五成双 String round31 = NumberUtil.roundStr(4.245, 2, RoundingMode.HALF_EVEN); String round41 = NumberUtil.roundStr("4.2451", 2, RoundingMode.HALF_EVEN); @@ -105,7 +106,7 @@ public class NumberUtilTest { String round6 = NumberUtil.roundStr("2.6005", 2); Assert.assertEquals("2.60", round5); Assert.assertEquals("2.60", round6); - + // 补0 String round7 = NumberUtil.roundStr(2.600, 2); String round8 = NumberUtil.roundStr("2.600", 2); @@ -118,7 +119,7 @@ public class NumberUtilTest { String roundStr = NumberUtil.roundStr(2.647, 2); Assert.assertEquals(roundStr, "2.65"); } - + @Test public void roundHalfEvenTest() { String roundStr = NumberUtil.roundHalfEven(4.245, 2).toString(); @@ -129,7 +130,7 @@ public class NumberUtilTest { Assert.assertEquals(roundStr, "4.25"); roundStr = NumberUtil.roundHalfEven(4.2250, 2).toString(); Assert.assertEquals(roundStr, "4.22"); - + roundStr = NumberUtil.roundHalfEven(1.2050, 2).toString(); Assert.assertEquals(roundStr, "1.20"); roundStr = NumberUtil.roundHalfEven(1.2150, 2).toString(); @@ -159,14 +160,14 @@ public class NumberUtilTest { String format = NumberUtil.decimalFormat(",###", c); Assert.assertEquals("299,792,458", format); } - + @Test public void decimalFormatMoneyTest() { double c = 299792400.543534534; - + String format = NumberUtil.decimalFormatMoney(c); Assert.assertEquals("299,792,400.54", format); - + double value = 0.5; String money = NumberUtil.decimalFormatMoney(value); Assert.assertEquals("0.50", money); @@ -176,17 +177,17 @@ public class NumberUtilTest { public void equalsTest() { Assert.assertTrue(NumberUtil.equals(new BigDecimal("0.00"), BigDecimal.ZERO)); } - + @Test public void formatPercentTest() { String str = NumberUtil.formatPercent(0.33543545, 2); Assert.assertEquals("33.54%", str); } - + @Test public void toBigDecimalTest() { double a = 3.14; - + BigDecimal bigDecimal = NumberUtil.toBigDecimal(a); Assert.assertEquals("3.14", bigDecimal.toString()); @@ -208,7 +209,7 @@ public class NumberUtilTest { int min = NumberUtil.min(5,4,3,6,1); Assert.assertEquals(1, min); } - + @Test public void parseIntTest() { int number = NumberUtil.parseInt("0xFF"); @@ -258,7 +259,7 @@ public class NumberUtilTest { Number v2 = NumberUtil.parseNumber("1,482.00D"); Assert.assertEquals(1482L, v2); } - + @Test public void parseLongTest() { long number = NumberUtil.parseLong("0xFF"); @@ -303,18 +304,36 @@ public class NumberUtilTest { Assert.assertEquals(120, factorial); factorial = NumberUtil.factorial(5, 1); Assert.assertEquals(120, factorial); - + Assert.assertEquals(5, NumberUtil.factorial(5, 4)); Assert.assertEquals(2432902008176640000L, NumberUtil.factorial(20, 0)); } + @Test + public void factorialTest2(){ + long factorial = NumberUtil.factorial(new BigInteger("0")).longValue(); + Assert.assertEquals(1, factorial); + + Assert.assertEquals(1L, NumberUtil.factorial(new BigInteger("1")).longValue()); + Assert.assertEquals(1307674368000L, NumberUtil.factorial(new BigInteger("15")).longValue()); + Assert.assertEquals(2432902008176640000L, NumberUtil.factorial(20)); + + factorial = NumberUtil.factorial(new BigInteger("5"), new BigInteger("0")).longValue(); + Assert.assertEquals(120, factorial); + factorial = NumberUtil.factorial(new BigInteger("5"), BigInteger.ONE).longValue(); + Assert.assertEquals(120, factorial); + + Assert.assertEquals(5, NumberUtil.factorial(new BigInteger("5"), new BigInteger("4")).longValue()); + Assert.assertEquals(2432902008176640000L, NumberUtil.factorial(new BigInteger("20"), BigInteger.ZERO).longValue()); + } + @Test public void mulTest(){ final BigDecimal mul = NumberUtil.mul(new BigDecimal("10"), null); Assert.assertEquals(BigDecimal.ZERO, mul); } - - + + @Test public void isPowerOfTwoTest() { Assert.assertFalse(NumberUtil.isPowerOfTwo(-1)); From 50df7381b5a40a15924bc8c9249e83bfdad01ebc Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 7 Mar 2021 11:51:33 +0800 Subject: [PATCH 44/47] fix code --- .../src/main/java/cn/hutool/core/util/ClassUtil.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java index ae3715a83..f6b9b913c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java @@ -294,7 +294,7 @@ public class ClassUtil { } /** - * 查找指定Public方法 如果找不到对应的方法或方法不为public的则返回null + * 查找指定Public方法 如果找不到对应的方法或方法不为public的则返回{@code null} * * @param clazz 类 * @param methodName 方法名 @@ -341,7 +341,7 @@ public class ClassUtil { } /** - * 查找指定类中的所有方法(包括非public方法),也包括父类和Object类的方法 找不到方法会返回null + * 查找指定类中的所有方法(包括非public方法),也包括父类和Object类的方法 找不到方法会返回{@code null} * * @param clazz 被查找的类 * @param methodName 方法名 @@ -356,7 +356,7 @@ public class ClassUtil { // ----------------------------------------------------------------------------------------- Field /** - * 查找指定类中的所有字段(包括非public字段), 字段不存在则返回null + * 查找指定类中的所有字段(包括非public字段), 字段不存在则返回{@code null} * * @param clazz 被查找字段的类 * @param fieldName 字段名 @@ -558,7 +558,7 @@ public class ClassUtil { } /** - * 比较判断types1和types2两组类,如果types1中所有的类都与types2对应位置的类相同,或者是其父类或接口,则返回true + * 比较判断types1和types2两组类,如果types1中所有的类都与types2对应位置的类相同,或者是其父类或接口,则返回{@code true} * * @param types1 类组1 * @param types2 类组2 @@ -626,7 +626,7 @@ public class ClassUtil { * 非单例模式,如果是非静态方法,每次创建一个新对象 * * @param 对象类型 - * @param classNameWithMethodName 类名和方法名表达式,类名与方法名用.#连接 例如:com.xiaoleilu.hutool.StrUtil.isEmpty 或 com.xiaoleilu.hutool.StrUtil#isEmpty + * @param classNameWithMethodName 类名和方法名表达式,类名与方法名用{@code .}或{@code #}连接 例如:com.xiaoleilu.hutool.StrUtil.isEmpty 或 com.xiaoleilu.hutool.StrUtil#isEmpty * @param args 参数,必须严格对应指定方法的参数类型和数量 * @return 返回结果 */ @@ -1092,4 +1092,4 @@ public class ClassUtil { } return location.getPath(); } -} \ No newline at end of file +} From ac5cdae89239137c52d0fdb3b2925b372814cce9 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 8 Mar 2021 10:14:49 +0800 Subject: [PATCH 45/47] fix comment --- .../src/main/java/cn/hutool/core/thread/ExecutorBuilder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/thread/ExecutorBuilder.java b/hutool-core/src/main/java/cn/hutool/core/thread/ExecutorBuilder.java index 7a9951b95..418e67068 100644 --- a/hutool-core/src/main/java/cn/hutool/core/thread/ExecutorBuilder.java +++ b/hutool-core/src/main/java/cn/hutool/core/thread/ExecutorBuilder.java @@ -200,7 +200,7 @@ public class ExecutorBuilder implements Builder { /** * 创建ExecutorBuilder,开始构建 * - * @return {@link ExecutorBuilder} + * @return this */ public static ExecutorBuilder create() { return new ExecutorBuilder(); @@ -227,7 +227,7 @@ public class ExecutorBuilder implements Builder { /** * 构建ThreadPoolExecutor * - * @param builder {@link ExecutorBuilder} + * @param builder this * @return {@link ThreadPoolExecutor} */ private static ThreadPoolExecutor build(ExecutorBuilder builder) { From 2aae44e5693e76ec248648563b8d4cd110836183 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 9 Mar 2021 16:42:40 +0800 Subject: [PATCH 46/47] remove final --- hutool-json/src/main/java/cn/hutool/json/JSONUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java index 9ee553319..e57756e69 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java @@ -35,7 +35,7 @@ import java.util.ResourceBundle; * * @author Looly */ -public final class JSONUtil { +public class JSONUtil { // -------------------------------------------------------------------- Pause start From f7cf53455f66ada5d6c3caf012931a219622568b Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 10 Mar 2021 11:35:48 +0800 Subject: [PATCH 47/47] add equals --- CHANGELOG.md | 3 ++- .../cn/hutool/core/lang/tree/TreeNode.java | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36780cfc4..18b91a983 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.6.0 (2021-03-07) +# 5.6.0 (2021-03-10) ### 新特性 * 【poi 】 重要:不再兼容POI-3.x,增加兼容POI-5.x(issue#I35J6B@Gitee) @@ -13,6 +13,7 @@ * 【core 】 增加FuncKeyMap(issue#1402@Github) * 【core 】 增加StrMatcher(issue#1379@Github) * 【core 】 NumberUtil增加factorial针对BigInterger方法(issue#1379@Github) +* 【core 】 TreeNode增加equals方法(issue#1467@Github) ### Bug修复 * 【socket 】 修复Client创建失败资源未释放问题。 diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/tree/TreeNode.java b/hutool-core/src/main/java/cn/hutool/core/lang/tree/TreeNode.java index 3fc1942e4..034cc8c04 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/tree/TreeNode.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/tree/TreeNode.java @@ -2,6 +2,7 @@ package cn.hutool.core.lang.tree; import java.util.Map; +import java.util.Objects; /** * 树节点 每个属性都可以在{@link TreeNodeConfig}中被重命名
              @@ -129,4 +130,21 @@ public class TreeNode implements Node { this.extra = extra; return this; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TreeNode treeNode = (TreeNode) o; + return Objects.equals(id, treeNode.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } }