Merge remote-tracking branch 'origin/v5-dev' into v5-dev

This commit is contained in:
VampireAchao 2022-05-05 19:21:38 +08:00
commit 8d23f4c153
13 changed files with 402 additions and 63 deletions

View File

@ -3,7 +3,7 @@
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.8.0.M5 (2022-04-28) # 5.8.0.M5 (2022-05-05)
### ❌不兼容特性 ### ❌不兼容特性
* 【extra 】 升级jakarta.validation-api到3.x包名变更导致不能向下兼容 * 【extra 】 升级jakarta.validation-api到3.x包名变更导致不能向下兼容
@ -12,6 +12,9 @@
### 🐣新特性 ### 🐣新特性
* 【core 】 Singleton增加部分方法pr#609@Gitee * 【core 】 Singleton增加部分方法pr#609@Gitee
* 【core 】 BeanUtil增加beanToMap重载pr#2292@Github * 【core 】 BeanUtil增加beanToMap重载pr#2292@Github
* 【core 】 Assert增加对应的equals及notEquals方法pr#612@Gitee
* 【core 】 Assert增加对应的equals及notEquals方法pr#612@Gitee
* 【core 】 DigestUtil增加sha512方法issue#2298@Github
### 🐞Bug修复 ### 🐞Bug修复
* 【db 】 修复RedisDS无法设置maxWaitMillis问题issue#I54TZ9@Gitee * 【db 】 修复RedisDS无法设置maxWaitMillis问题issue#I54TZ9@Gitee

View File

@ -3,6 +3,7 @@ package cn.hutool.core.lang;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import java.util.Map; import java.util.Map;
@ -1003,6 +1004,99 @@ public class Assert {
return value; return value;
} }
/**
* 断言两个对象是否不相等,如果两个对象相等 抛出IllegalArgumentException 异常
* <pre class="code">
* Assert.notEquals(obj1,obj2);
* </pre>
*
* @param obj1 对象1
* @param obj2 对象2
* @throws IllegalArgumentException obj1 must be not equals obj2
*/
public static void notEquals(Object obj1, Object obj2) {
notEquals(obj1, obj2, "({}) must be not equals ({})", obj1, obj2);
}
/**
* 断言两个对象是否不相等,如果两个对象相等 抛出IllegalArgumentException 异常
* <pre class="code">
* Assert.notEquals(obj1,obj2,"obj1 must be not equals obj2");
* </pre>
*
* @param obj1 对象1
* @param obj2 对象2
* @param errorMsgTemplate 异常信息模板类似于"aa{}bb{}cc"
* @param params 异常信息参数用于替换"{}"占位符
* @throws IllegalArgumentException obj1 must be not equals obj2
*/
public static void notEquals(Object obj1, Object obj2, String errorMsgTemplate, Object... params) throws IllegalArgumentException {
notEquals(obj1, obj2, () -> new IllegalArgumentException(StrUtil.format(errorMsgTemplate, params)));
}
/**
* 断言两个对象是否不相等,如果两个对象相等,抛出指定类型异常,并使用指定的函数获取错误信息返回
*
* @param obj1 对象1
* @param obj2 对象2
* @param errorSupplier 错误抛出异常附带的消息生产接口
* @param <X> 异常类型
* @throws X obj1 must be not equals obj2
*/
public static <X extends Throwable> void notEquals(Object obj1, Object obj2, Supplier<X> errorSupplier) throws X {
if (ObjectUtil.equals(obj1, obj2)) {
throw errorSupplier.get();
}
}
// ----------------------------------------------------------------------------------------------------------- Check not equals
/**
* 断言两个对象是否相等,如果两个对象不相等 抛出IllegalArgumentException 异常
* <pre class="code">
* Assert.isEquals(obj1,obj2);
* </pre>
*
* @param obj1 对象1
* @param obj2 对象2
* @throws IllegalArgumentException obj1 must be equals obj2
*/
public static void equals(Object obj1, Object obj2) {
equals(obj1, obj2, "({}) must be equals ({})", obj1, obj2);
}
/**
* 断言两个对象是否相等,如果两个对象不相等 抛出IllegalArgumentException 异常
* <pre class="code">
* Assert.isEquals(obj1,obj2,"obj1 must be equals obj2");
* </pre>
*
* @param obj1 对象1
* @param obj2 对象2
* @param errorMsgTemplate 异常信息模板类似于"aa{}bb{}cc"
* @param params 异常信息参数用于替换"{}"占位符
* @throws IllegalArgumentException obj1 must be equals obj2
*/
public static void equals(Object obj1, Object obj2, String errorMsgTemplate, Object... params) throws IllegalArgumentException {
equals(obj1, obj2, () -> new IllegalArgumentException(StrUtil.format(errorMsgTemplate, params)));
}
/**
* 断言两个对象是否相等,如果两个对象不相等,抛出指定类型异常,并使用指定的函数获取错误信息返回
*
* @param obj1 对象1
* @param obj2 对象2
* @param errorSupplier 错误抛出异常附带的消息生产接口
* @param <X> 异常类型
* @throws X obj1 must be equals obj2
*/
public static <X extends Throwable> void equals(Object obj1, Object obj2, Supplier<X> errorSupplier) throws X {
if (ObjectUtil.notEqual(obj1, obj2)) {
throw errorSupplier.get();
}
}
// ----------------------------------------------------------------------------------------------------------- Check is equals
// -------------------------------------------------------------------------------------------------------------------------------------------- Private method start // -------------------------------------------------------------------------------------------------------------------------------------------- Private method start
/** /**

View File

@ -41,7 +41,7 @@ import java.util.stream.Stream;
/** /**
* 复制jdk16中的Optional以及自己进行了一点调整和新增比jdk8中的Optional多了几个实用的函数<br> * 复制jdk16中的Optional以及自己进行了一点调整和新增比jdk8中的Optional多了几个实用的函数<br>
* 详细见https://gitee.com/dromara/hutool/pulls/426 * 详细见<a href="https://gitee.com/dromara/hutool/pulls/426">https://gitee.com/dromara/hutool/pulls/426</a>
* *
* @param <T> 包裹里元素的类型 * @param <T> 包裹里元素的类型
* @author VampireAchao * @author VampireAchao
@ -60,8 +60,7 @@ public class Opt<T> {
* @return Opt * @return Opt
*/ */
public static <T> Opt<T> empty() { public static <T> Opt<T> empty() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked") final Opt<T> t = (Opt<T>) EMPTY;
Opt<T> t = (Opt<T>) EMPTY;
return t; return t;
} }
@ -322,7 +321,7 @@ public class Opt<T> {
return empty(); return empty();
} else { } else {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Opt<U> r = (Opt<U>) mapper.apply(value); final Opt<U> r = (Opt<U>) mapper.apply(value);
return Objects.requireNonNull(r); return Objects.requireNonNull(r);
} }
} }
@ -400,8 +399,7 @@ public class Opt<T> {
if (isPresent()) { if (isPresent()) {
return this; return this;
} else { } else {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked") final Opt<T> r = (Opt<T>) supplier.get();
Opt<T> r = (Opt<T>) supplier.get();
return Objects.requireNonNull(r); return Objects.requireNonNull(r);
} }
} }
@ -544,7 +542,7 @@ public class Opt<T> {
return false; return false;
} }
Opt<?> other = (Opt<?>) obj; final Opt<?> other = (Opt<?>) obj;
return Objects.equals(value, other.value); return Objects.equals(value, other.value);
} }

View File

@ -104,7 +104,7 @@ public class ObjectUtil {
int count; int count;
if (obj instanceof Iterator) { if (obj instanceof Iterator) {
Iterator<?> iter = (Iterator<?>) obj; final Iterator<?> iter = (Iterator<?>) obj;
count = 0; count = 0;
while (iter.hasNext()) { while (iter.hasNext()) {
count++; count++;
@ -113,7 +113,7 @@ public class ObjectUtil {
return count; return count;
} }
if (obj instanceof Enumeration) { if (obj instanceof Enumeration) {
Enumeration<?> enumeration = (Enumeration<?>) obj; final Enumeration<?> enumeration = (Enumeration<?>) obj;
count = 0; count = 0;
while (enumeration.hasMoreElements()) { while (enumeration.hasMoreElements()) {
count++; count++;
@ -161,9 +161,9 @@ public class ObjectUtil {
} }
if (obj instanceof Iterator) { if (obj instanceof Iterator) {
Iterator<?> iter = (Iterator<?>) obj; final Iterator<?> iter = (Iterator<?>) obj;
while (iter.hasNext()) { while (iter.hasNext()) {
Object o = iter.next(); final Object o = iter.next();
if (equal(o, element)) { if (equal(o, element)) {
return true; return true;
} }
@ -171,9 +171,9 @@ public class ObjectUtil {
return false; return false;
} }
if (obj instanceof Enumeration) { if (obj instanceof Enumeration) {
Enumeration<?> enumeration = (Enumeration<?>) obj; final Enumeration<?> enumeration = (Enumeration<?>) obj;
while (enumeration.hasMoreElements()) { while (enumeration.hasMoreElements()) {
Object o = enumeration.nextElement(); final Object o = enumeration.nextElement();
if (equal(o, element)) { if (equal(o, element)) {
return true; return true;
} }
@ -181,9 +181,9 @@ public class ObjectUtil {
return false; return false;
} }
if (obj.getClass().isArray() == true) { if (obj.getClass().isArray() == true) {
int len = Array.getLength(obj); final int len = Array.getLength(obj);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
Object o = Array.get(obj, i); final Object o = Array.get(obj, i);
if (equal(o, element)) { if (equal(o, element)) {
return true; return true;
} }

View File

@ -1064,6 +1064,17 @@ public class DateUtilTest {
Assert.assertFalse(DateUtil.isOverlap(startTime,endTime,realStartTime1,realEndTime1)); Assert.assertFalse(DateUtil.isOverlap(startTime,endTime,realStartTime1,realEndTime1));
} }
@Test
public void isOverlapTest2() {
DateTime oneStartTime = DateUtil.parseDate("2021-02-01");
DateTime oneEndTime = DateUtil.parseDate("2022-06-30");
DateTime oneStartTime2 = DateUtil.parseDate("2019-04-05");
DateTime oneEndTime2 = DateUtil.parseDate("2021-04-05");
Assert.assertTrue(DateUtil.isOverlap(oneStartTime, oneEndTime, oneStartTime2, oneEndTime2));
}
@Test @Test
public void isInTest(){ public void isInTest(){
String sourceStr = "2022-04-19 00:00:00"; String sourceStr = "2022-04-19 00:00:00";

View File

@ -1,5 +1,6 @@
package cn.hutool.core.lang; package cn.hutool.core.lang;
import cn.hutool.core.util.StrUtil;
import org.junit.Test; import org.junit.Test;
public class AssertTest { public class AssertTest {
@ -35,4 +36,28 @@ public class AssertTest {
//noinspection ConstantConditions //noinspection ConstantConditions
Assert.isTrue(i > 0, () -> new IndexOutOfBoundsException("relation message to return")); Assert.isTrue(i > 0, () -> new IndexOutOfBoundsException("relation message to return"));
} }
@Test
public void equalsTest() {
//String a="ab";
//final String b = new String("abc");
String a = null;
final String b = null;
Assert.equals(a, b);
Assert.equals(a, b, "{}不等于{}", a, b);
Assert.equals(a, b, () -> new RuntimeException(StrUtil.format("{}和{}不相等", a, b)));
}
@Test
public void notEqualsTest() {
//String c="19";
//final String d = new String("19");
String c = null;
final String d = "null";
//Assert.notEquals(c,d);
//Assert.notEquals(c,d,"{}等于{}",c,d);
Assert.notEquals(c, d, () -> new RuntimeException(StrUtil.format("{}和{}相等", c, d)));
}
} }

View File

@ -1,9 +1,13 @@
package cn.hutool.core.net; package cn.hutool.core.net;
import cn.hutool.core.codec.PercentCodec;
import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.CharsetUtil;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class RFC3986Test { public class RFC3986Test {
@Test @Test
@ -26,4 +30,12 @@ public class RFC3986Test {
String encode = RFC3986.QUERY_PARAM_VALUE.encode("a=%25", CharsetUtil.CHARSET_UTF_8, '%'); String encode = RFC3986.QUERY_PARAM_VALUE.encode("a=%25", CharsetUtil.CHARSET_UTF_8, '%');
Assert.assertEquals("a=%25", encode); Assert.assertEquals("a=%25", encode);
} }
@Test
public void encodeAllTest() throws UnsupportedEncodingException {
String toVerifyText = "行吧行吧 cargo:1.0,\"Deta-ils:[{";
final String encode = PercentCodec.of(RFC3986.UNRESERVED).setEncodeSpaceAsPlus(true).encode(toVerifyText, CharsetUtil.CHARSET_UTF_8);
final String encodeJdk = URLEncoder.encode(toVerifyText, "UTF-8");
Assert.assertEquals(encode, encodeJdk);
}
} }

View File

@ -487,4 +487,110 @@ public class DigestUtil {
public static boolean bcryptCheck(String password, String hashed) { public static boolean bcryptCheck(String password, String hashed) {
return BCrypt.checkpw(password, hashed); return BCrypt.checkpw(password, hashed);
} }
// ------------------------------------------------------------------------------------------- SHA-512
/**
* 计算SHA-512摘要值
*
* @param data 被摘要数据
* @return SHA-512摘要
*/
public static byte[] sha512(final byte[] data) {
return new Digester(DigestAlgorithm.SHA512).digest(data);
}
/**
* 计算SHA-512摘要值
*
* @param data 被摘要数据
* @param charset 编码
* @return SHA-512摘要
* @since 3.0.8
*/
public static byte[] sha512(final String data, final String charset) {
return new Digester(DigestAlgorithm.SHA512).digest(data, charset);
}
/**
* 计算sha512摘要值使用UTF-8编码
*
* @param data 被摘要数据
* @return MD5摘要
*/
public static byte[] sha512(final String data) {
return sha512(data, CharsetUtil.UTF_8);
}
/**
* 计算SHA-512摘要值
*
* @param data 被摘要数据
* @return SHA-512摘要
*/
public static byte[] sha512(final InputStream data) {
return new Digester(DigestAlgorithm.SHA512).digest(data);
}
/**
* 计算SHA-512摘要值
*
* @param file 被摘要文件
* @return SHA-512摘要
*/
public static byte[] sha512(final File file) {
return new Digester(DigestAlgorithm.SHA512).digest(file);
}
/**
* 计算SHA-1摘要值并转为16进制字符串
*
* @param data 被摘要数据
* @return SHA-512摘要的16进制表示
*/
public static String sha512Hex(final byte[] data) {
return new Digester(DigestAlgorithm.SHA512).digestHex(data);
}
/**
* 计算SHA-512摘要值并转为16进制字符串
*
* @param data 被摘要数据
* @param charset 编码
* @return SHA-512摘要的16进制表示
*/
public static String sha512Hex(final String data, final String charset) {
return new Digester(DigestAlgorithm.SHA512).digestHex(data, charset);
}
/**
* 计算SHA-512摘要值并转为16进制字符串
*
* @param data 被摘要数据
* @return SHA-512摘要的16进制表示
*/
public static String sha512Hex(final String data) {
return sha512Hex(data, CharsetUtil.UTF_8);
}
/**
* 计算SHA-512摘要值并转为16进制字符串
*
* @param data 被摘要数据
* @return SHA-512摘要的16进制表示
*/
public static String sha512Hex(final InputStream data) {
return new Digester(DigestAlgorithm.SHA512).digestHex(data);
}
/**
* 计算SHA-512摘要值并转为16进制字符串
*
* @param file 被摘要文件
* @return SHA-512摘要的16进制表示
*/
public static String sha512Hex(final File file) {
return new Digester(DigestAlgorithm.SHA512).digestHex(file);
}
} }

View File

@ -82,13 +82,13 @@ public class MetaUtil {
conn = ds.getConnection(); conn = ds.getConnection();
// catalog和schema获取失败默认使用null代替 // catalog和schema获取失败默认使用null代替
String catalog = getCatalog(conn); final String catalog = getCatalog(conn);
if (null == schema) { if (null == schema) {
schema = getSchema(conn); schema = getSchema(conn);
} }
final DatabaseMetaData metaData = conn.getMetaData(); final DatabaseMetaData metaData = conn.getMetaData();
try (ResultSet rs = metaData.getTables(catalog, schema, tableName, Convert.toStrArray(types))) { try (final ResultSet rs = metaData.getTables(catalog, schema, tableName, Convert.toStrArray(types))) {
if (null != rs) { if (null != rs) {
String table; String table;
while (rs.next()) { while (rs.next()) {
@ -116,9 +116,9 @@ public class MetaUtil {
*/ */
public static String[] getColumnNames(ResultSet rs) throws DbRuntimeException { public static String[] getColumnNames(ResultSet rs) throws DbRuntimeException {
try { try {
ResultSetMetaData rsmd = rs.getMetaData(); final ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount(); final int columnCount = rsmd.getColumnCount();
String[] labelNames = new String[columnCount]; final String[] labelNames = new String[columnCount];
for (int i = 0; i < labelNames.length; i++) { for (int i = 0; i < labelNames.length; i++) {
labelNames[i] = rsmd.getColumnLabel(i + 1); labelNames[i] = rsmd.getColumnLabel(i + 1);
} }
@ -137,17 +137,17 @@ public class MetaUtil {
* @throws DbRuntimeException SQL执行异常 * @throws DbRuntimeException SQL执行异常
*/ */
public static String[] getColumnNames(DataSource ds, String tableName) { public static String[] getColumnNames(DataSource ds, String tableName) {
List<String> columnNames = new ArrayList<>(); final List<String> columnNames = new ArrayList<>();
Connection conn = null; Connection conn = null;
try { try {
conn = ds.getConnection(); conn = ds.getConnection();
// catalog和schema获取失败默认使用null代替 // catalog和schema获取失败默认使用null代替
String catalog = getCatalog(conn); final String catalog = getCatalog(conn);
String schema = getSchema(conn); final String schema = getSchema(conn);
final DatabaseMetaData metaData = conn.getMetaData(); final DatabaseMetaData metaData = conn.getMetaData();
try (ResultSet rs = metaData.getColumns(catalog, schema, tableName, null)) { try (final ResultSet rs = metaData.getColumns(catalog, schema, tableName, null)) {
if (null != rs) { if (null != rs) {
while (rs.next()) { while (rs.next()) {
columnNames.add(rs.getString("COLUMN_NAME")); columnNames.add(rs.getString("COLUMN_NAME"));
@ -225,7 +225,7 @@ public class MetaUtil {
final DatabaseMetaData metaData = conn.getMetaData(); final DatabaseMetaData metaData = conn.getMetaData();
// 获得表元数据表注释 // 获得表元数据表注释
try (ResultSet rs = metaData.getTables(catalog, schema, tableName, new String[]{TableType.TABLE.value()})) { try (final ResultSet rs = metaData.getTables(catalog, schema, tableName, new String[]{TableType.TABLE.value()})) {
if (null != rs) { if (null != rs) {
if (rs.next()) { if (rs.next()) {
table.setComment(rs.getString("REMARKS")); table.setComment(rs.getString("REMARKS"));
@ -235,7 +235,7 @@ public class MetaUtil {
} }
// 获得主键 // 获得主键
try (ResultSet rs = metaData.getPrimaryKeys(catalog, schema, tableName)) { try (final ResultSet rs = metaData.getPrimaryKeys(catalog, schema, tableName)) {
if (null != rs) { if (null != rs) {
while (rs.next()) { while (rs.next()) {
table.addPk(rs.getString("COLUMN_NAME")); table.addPk(rs.getString("COLUMN_NAME"));
@ -244,7 +244,7 @@ public class MetaUtil {
} }
// 获得列 // 获得列
try (ResultSet rs = metaData.getColumns(catalog, schema, tableName, null)) { try (final ResultSet rs = metaData.getColumns(catalog, schema, tableName, null)) {
if (null != rs) { if (null != rs) {
while (rs.next()) { while (rs.next()) {
table.setColumn(Column.create(table, rs)); table.setColumn(Column.create(table, rs));
@ -253,7 +253,7 @@ public class MetaUtil {
} }
// 获得索引信息(since 5.7.23) // 获得索引信息(since 5.7.23)
try (ResultSet rs = metaData.getIndexInfo(catalog, schema, tableName, false, false)) { try (final ResultSet rs = metaData.getIndexInfo(catalog, schema, tableName, false, false)) {
final Map<String, IndexInfo> indexInfoMap = new LinkedHashMap<>(); final Map<String, IndexInfo> indexInfoMap = new LinkedHashMap<>();
if (null != rs) { if (null != rs) {
while (rs.next()) { while (rs.next()) {

View File

@ -2,6 +2,7 @@ package cn.hutool.db.meta;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.db.DbRuntimeException;
import cn.hutool.db.ds.DSFactory; import cn.hutool.db.ds.DSFactory;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -20,25 +21,34 @@ public class MetaUtilTest {
@Test @Test
public void getTablesTest() { public void getTablesTest() {
List<String> tables = MetaUtil.getTables(ds); final List<String> tables = MetaUtil.getTables(ds);
Assert.assertEquals("user", tables.get(0)); Assert.assertEquals("user", tables.get(0));
} }
@Test @Test
public void getTableMetaTest() { public void getTableMetaTest() {
Table table = MetaUtil.getTableMeta(ds, "user"); final Table table = MetaUtil.getTableMeta(ds, "user");
Assert.assertEquals(CollectionUtil.newHashSet("id"), table.getPkNames()); Assert.assertEquals(CollectionUtil.newHashSet("id"), table.getPkNames());
} }
@Test @Test
public void getColumnNamesTest() { public void getColumnNamesTest() {
String[] names = MetaUtil.getColumnNames(ds, "user"); final String[] names = MetaUtil.getColumnNames(ds, "user");
Assert.assertArrayEquals(StrUtil.splitToArray("id,name,age,birthday,gender", ','), names); Assert.assertArrayEquals(StrUtil.splitToArray("id,name,age,birthday,gender", ','), names);
} }
@Test @Test
public void getTableIndexInfoTest() { public void getTableIndexInfoTest() {
Table table = MetaUtil.getTableMeta(ds, "user_1"); final Table table = MetaUtil.getTableMeta(ds, "user_1");
Assert.assertEquals(table.getIndexInfoList().size(), 2);
}
/**
* 表不存在抛出异常
*/
@Test(expected = DbRuntimeException.class)
public void getTableNotExistTest() {
final Table table = MetaUtil.getTableMeta(ds, "user_not_exist");
Assert.assertEquals(table.getIndexInfoList().size(), 2); Assert.assertEquals(table.getIndexInfoList().size(), 2);
} }
} }

View File

@ -194,7 +194,7 @@ public final class SensitiveUtil {
* @return 敏感词过滤处理后的bean对象 * @return 敏感词过滤处理后的bean对象
*/ */
public static <T> T sensitiveFilter(T bean, boolean isGreedMatch, SensitiveProcessor sensitiveProcessor) { public static <T> T sensitiveFilter(T bean, boolean isGreedMatch, SensitiveProcessor sensitiveProcessor) {
String jsonText = JSONUtil.toJsonStr(bean); final String jsonText = JSONUtil.toJsonStr(bean);
@SuppressWarnings("unchecked") final Class<T> c = (Class<T>) bean.getClass(); @SuppressWarnings("unchecked") final Class<T> c = (Class<T>) bean.getClass();
return JSONUtil.toBean(sensitiveFilter(jsonText, isGreedMatch, sensitiveProcessor), c); return JSONUtil.toBean(sensitiveFilter(jsonText, isGreedMatch, sensitiveProcessor), c);
} }
@ -224,7 +224,7 @@ public final class SensitiveUtil {
} }
//敏感词过滤场景下不需要密集匹配 //敏感词过滤场景下不需要密集匹配
List<FoundWord> foundWordList = getFoundAllSensitive(text, true, isGreedMatch); final List<FoundWord> foundWordList = getFoundAllSensitive(text, true, isGreedMatch);
if (CollUtil.isEmpty(foundWordList)) { if (CollUtil.isEmpty(foundWordList)) {
return text; return text;
} }
@ -233,10 +233,10 @@ public final class SensitiveUtil {
final Map<Integer, FoundWord> foundWordMap = new HashMap<>(foundWordList.size(), 1); final Map<Integer, FoundWord> foundWordMap = new HashMap<>(foundWordList.size(), 1);
foundWordList.forEach(foundWord -> foundWordMap.put(foundWord.getStartIndex(), foundWord)); foundWordList.forEach(foundWord -> foundWordMap.put(foundWord.getStartIndex(), foundWord));
int length = text.length(); final int length = text.length();
StringBuilder textStringBuilder = new StringBuilder(); final StringBuilder textStringBuilder = new StringBuilder();
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
FoundWord fw = foundWordMap.get(i); final FoundWord fw = foundWordMap.get(i);
if (fw != null) { if (fw != null) {
textStringBuilder.append(sensitiveProcessor.process(fw)); textStringBuilder.append(sensitiveProcessor.process(fw));
i = fw.getEndIndex(); i = fw.getEndIndex();

View File

@ -105,7 +105,7 @@ public class CellUtil {
cellType = cell.getCellType(); cellType = cell.getCellType();
} }
Object value; final Object value;
switch (cellType) { switch (cellType) {
case NUMERIC: case NUMERIC:
value = new NumericCellValue(cell).getValue(); value = new NumericCellValue(cell).getValue();
@ -199,14 +199,14 @@ public class CellUtil {
* *
* @param row Excel表的行 * @param row Excel表的行
* @param cellIndex 列号 * @param cellIndex 列号
* @return {@link Row} * @return {@link Cell}
* @since 5.5.0 * @since 5.5.0
*/ */
public static Cell getCell(Row row, int cellIndex) { public static Cell getCell(Row row, int cellIndex) {
if (null == row) { if (null == row) {
return null; return null;
} }
Cell cell = row.getCell(cellIndex); final Cell cell = row.getCell(cellIndex);
if (null == cell) { if (null == cell) {
return new NullCell(row, cellIndex); return new NullCell(row, cellIndex);
} }
@ -218,7 +218,7 @@ public class CellUtil {
* *
* @param row Excel表的行 * @param row Excel表的行
* @param cellIndex 列号 * @param cellIndex 列号
* @return {@link Row} * @return {@link Cell}
* @since 4.0.2 * @since 4.0.2
*/ */
public static Cell getOrCreateCell(Row row, int cellIndex) { public static Cell getOrCreateCell(Row row, int cellIndex) {
@ -262,9 +262,10 @@ public class CellUtil {
* @param sheet {@link Sheet} * @param sheet {@link Sheet}
* @param x 列号从0开始 * @param x 列号从0开始
* @param y 行号从0开始 * @param y 行号从0开始
* @return 是否是合并单元格 * @return 是否是合并单元格如果提供的sheet为{@code null}返回{@code false}
*/ */
public static boolean isMergedRegion(Sheet sheet, int x, int y) { public static boolean isMergedRegion(Sheet sheet, int x, int y) {
if (sheet != null) {
final int sheetMergeCount = sheet.getNumMergedRegions(); final int sheetMergeCount = sheet.getNumMergedRegions();
CellRangeAddress ca; CellRangeAddress ca;
for (int i = 0; i < sheetMergeCount; i++) { for (int i = 0; i < sheetMergeCount; i++) {
@ -274,9 +275,71 @@ public class CellUtil {
return true; return true;
} }
} }
}
return false; return false;
} }
/**
* 获取合并单元格{@link CellRangeAddress}如果不是返回null
*
* @param sheet {@link Sheet}
* @param locationRef 单元格地址标识符例如A11B5
* @return {@link CellRangeAddress}
* @since 5.8.0
*/
public static CellRangeAddress getCellRangeAddress(Sheet sheet, String locationRef) {
final CellLocation cellLocation = ExcelUtil.toLocation(locationRef);
return getCellRangeAddress(sheet, cellLocation.getX(), cellLocation.getY());
}
/**
* 获取合并单元格{@link CellRangeAddress}如果不是返回null
*
* @param cell {@link Cell}
* @return {@link CellRangeAddress}
* @since 5.8.0
*/
public static CellRangeAddress getCellRangeAddress(Cell cell) {
return getCellRangeAddress(cell.getSheet(), cell.getColumnIndex(), cell.getRowIndex());
}
/**
* 获取合并单元格{@link CellRangeAddress}如果不是返回null
*
* @param sheet {@link Sheet}
* @param x 列号从0开始
* @param y 行号从0开始
* @return {@link CellRangeAddress}
* @since 5.8.0
*/
public static CellRangeAddress getCellRangeAddress(Sheet sheet, int x, int y) {
if (sheet != null) {
final int sheetMergeCount = sheet.getNumMergedRegions();
CellRangeAddress ca;
for (int i = 0; i < sheetMergeCount; i++) {
ca = sheet.getMergedRegion(i);
if (y >= ca.getFirstRow() && y <= ca.getLastRow()
&& x >= ca.getFirstColumn() && x <= ca.getLastColumn()) {
return ca;
}
}
}
return null;
}
/**
* 设置合并单元格样式如果不是则不设置
*
* @param cell {@link Cell}
* @param cellStyle {@link CellStyle}
*/
public static void setMergedRegionStyle(Cell cell, CellStyle cellStyle) {
final CellRangeAddress cellRangeAddress = getCellRangeAddress(cell);
if (cellRangeAddress != null) {
setMergeCellStyle(cellStyle, cellRangeAddress, cell.getSheet());
}
}
/** /**
* 合并单元格可以根据设置的值来合并行和列 * 合并单元格可以根据设置的值来合并行和列
* *
@ -310,16 +373,7 @@ public class CellUtil {
lastColumn // last column (0-based) lastColumn // last column (0-based)
); );
if (null != cellStyle) { setMergeCellStyle(cellStyle, 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);
RegionUtil.setTopBorderColor(cellStyle.getTopBorderColor(),cellRangeAddress,sheet);
RegionUtil.setRightBorderColor(cellStyle.getRightBorderColor(),cellRangeAddress,sheet);
RegionUtil.setLeftBorderColor(cellStyle.getLeftBorderColor(),cellRangeAddress,sheet);
RegionUtil.setBottomBorderColor(cellStyle.getBottomBorderColor(),cellRangeAddress,sheet);
}
return sheet.addMergedRegion(cellRangeAddress); return sheet.addMergedRegion(cellRangeAddress);
} }
@ -406,7 +460,7 @@ public class CellUtil {
anchor.setRow1(cell.getRowIndex()); anchor.setRow1(cell.getRowIndex());
anchor.setRow2(cell.getRowIndex() + 2); anchor.setRow2(cell.getRowIndex() + 2);
} }
Comment comment = drawing.createCellComment(anchor); final Comment comment = drawing.createCellComment(anchor);
comment.setString(factory.createRichTextString(commentText)); comment.setString(factory.createRichTextString(commentText));
comment.setAuthor(StrUtil.nullToEmpty(commentAuthor)); comment.setAuthor(StrUtil.nullToEmpty(commentAuthor));
cell.setCellComment(comment); cell.setCellComment(comment);
@ -435,5 +489,25 @@ public class CellUtil {
} }
return null; return null;
} }
/**
* 根据{@link CellStyle}设置合并单元格边框样式
*
* @param cellStyle {@link CellStyle}
* @param cellRangeAddress {@link CellRangeAddress}
* @param sheet {@link Sheet}
*/
private static void setMergeCellStyle(CellStyle cellStyle, CellRangeAddress cellRangeAddress, Sheet sheet) {
if (null != cellStyle) {
RegionUtil.setBorderTop(cellStyle.getBorderTop(), cellRangeAddress, sheet);
RegionUtil.setBorderRight(cellStyle.getBorderRight(), cellRangeAddress, sheet);
RegionUtil.setBorderBottom(cellStyle.getBorderBottom(), cellRangeAddress, sheet);
RegionUtil.setBorderLeft(cellStyle.getBorderLeft(), cellRangeAddress, sheet);
RegionUtil.setTopBorderColor(cellStyle.getTopBorderColor(), cellRangeAddress, sheet);
RegionUtil.setRightBorderColor(cellStyle.getRightBorderColor(), cellRangeAddress, sheet);
RegionUtil.setLeftBorderColor(cellStyle.getLeftBorderColor(), cellRangeAddress, sheet);
RegionUtil.setBottomBorderColor(cellStyle.getBottomBorderColor(), cellRangeAddress, sheet);
}
}
// -------------------------------------------------------------------------------------------------------------- Private method end // -------------------------------------------------------------------------------------------------------------- Private method end
} }

View File

@ -0,0 +1,6 @@
/**
* Excel中单元格设置相关类一些{@link cn.hutool.poi.excel.cell.CellSetter}的实现类
*
* @author looly
*/
package cn.hutool.poi.excel.cell.setters;