mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
Merge remote-tracking branch 'origin/v5-dev' into v5-dev
This commit is contained in:
commit
8d23f4c153
@ -3,7 +3,7 @@
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 5.8.0.M5 (2022-04-28)
|
||||
# 5.8.0.M5 (2022-05-05)
|
||||
|
||||
### ❌不兼容特性
|
||||
* 【extra 】 升级jakarta.validation-api到3.x,包名变更导致不能向下兼容
|
||||
@ -12,6 +12,9 @@
|
||||
### 🐣新特性
|
||||
* 【core 】 Singleton增加部分方法(pr#609@Gitee)
|
||||
* 【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修复
|
||||
* 【db 】 修复RedisDS无法设置maxWaitMillis问题(issue#I54TZ9@Gitee)
|
||||
|
@ -3,6 +3,7 @@ package cn.hutool.core.lang;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.Map;
|
||||
@ -1003,6 +1004,99 @@ public class Assert {
|
||||
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
|
||||
|
||||
/**
|
||||
|
@ -41,7 +41,7 @@ import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 复制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> 包裹里元素的类型
|
||||
* @author VampireAchao
|
||||
@ -60,8 +60,7 @@ public class Opt<T> {
|
||||
* @return Opt
|
||||
*/
|
||||
public static <T> Opt<T> empty() {
|
||||
@SuppressWarnings("unchecked")
|
||||
Opt<T> t = (Opt<T>) EMPTY;
|
||||
@SuppressWarnings("unchecked") final Opt<T> t = (Opt<T>) EMPTY;
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -322,7 +321,7 @@ public class Opt<T> {
|
||||
return empty();
|
||||
} else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Opt<U> r = (Opt<U>) mapper.apply(value);
|
||||
final Opt<U> r = (Opt<U>) mapper.apply(value);
|
||||
return Objects.requireNonNull(r);
|
||||
}
|
||||
}
|
||||
@ -400,8 +399,7 @@ public class Opt<T> {
|
||||
if (isPresent()) {
|
||||
return this;
|
||||
} else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Opt<T> r = (Opt<T>) supplier.get();
|
||||
@SuppressWarnings("unchecked") final Opt<T> r = (Opt<T>) supplier.get();
|
||||
return Objects.requireNonNull(r);
|
||||
}
|
||||
}
|
||||
@ -544,7 +542,7 @@ public class Opt<T> {
|
||||
return false;
|
||||
}
|
||||
|
||||
Opt<?> other = (Opt<?>) obj;
|
||||
final Opt<?> other = (Opt<?>) obj;
|
||||
return Objects.equals(value, other.value);
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ public class ObjectUtil {
|
||||
|
||||
int count;
|
||||
if (obj instanceof Iterator) {
|
||||
Iterator<?> iter = (Iterator<?>) obj;
|
||||
final Iterator<?> iter = (Iterator<?>) obj;
|
||||
count = 0;
|
||||
while (iter.hasNext()) {
|
||||
count++;
|
||||
@ -113,7 +113,7 @@ public class ObjectUtil {
|
||||
return count;
|
||||
}
|
||||
if (obj instanceof Enumeration) {
|
||||
Enumeration<?> enumeration = (Enumeration<?>) obj;
|
||||
final Enumeration<?> enumeration = (Enumeration<?>) obj;
|
||||
count = 0;
|
||||
while (enumeration.hasMoreElements()) {
|
||||
count++;
|
||||
@ -161,9 +161,9 @@ public class ObjectUtil {
|
||||
}
|
||||
|
||||
if (obj instanceof Iterator) {
|
||||
Iterator<?> iter = (Iterator<?>) obj;
|
||||
final Iterator<?> iter = (Iterator<?>) obj;
|
||||
while (iter.hasNext()) {
|
||||
Object o = iter.next();
|
||||
final Object o = iter.next();
|
||||
if (equal(o, element)) {
|
||||
return true;
|
||||
}
|
||||
@ -171,9 +171,9 @@ public class ObjectUtil {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof Enumeration) {
|
||||
Enumeration<?> enumeration = (Enumeration<?>) obj;
|
||||
final Enumeration<?> enumeration = (Enumeration<?>) obj;
|
||||
while (enumeration.hasMoreElements()) {
|
||||
Object o = enumeration.nextElement();
|
||||
final Object o = enumeration.nextElement();
|
||||
if (equal(o, element)) {
|
||||
return true;
|
||||
}
|
||||
@ -181,9 +181,9 @@ public class ObjectUtil {
|
||||
return false;
|
||||
}
|
||||
if (obj.getClass().isArray() == true) {
|
||||
int len = Array.getLength(obj);
|
||||
final int len = Array.getLength(obj);
|
||||
for (int i = 0; i < len; i++) {
|
||||
Object o = Array.get(obj, i);
|
||||
final Object o = Array.get(obj, i);
|
||||
if (equal(o, element)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1064,6 +1064,17 @@ public class DateUtilTest {
|
||||
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
|
||||
public void isInTest(){
|
||||
String sourceStr = "2022-04-19 00:00:00";
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.hutool.core.lang;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
public class AssertTest {
|
||||
@ -35,4 +36,28 @@ public class AssertTest {
|
||||
//noinspection ConstantConditions
|
||||
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)));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
package cn.hutool.core.net;
|
||||
|
||||
import cn.hutool.core.codec.PercentCodec;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
public class RFC3986Test {
|
||||
|
||||
@Test
|
||||
@ -26,4 +30,12 @@ public class RFC3986Test {
|
||||
String encode = RFC3986.QUERY_PARAM_VALUE.encode("a=%25", CharsetUtil.CHARSET_UTF_8, '%');
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -487,4 +487,110 @@ public class DigestUtil {
|
||||
public static boolean bcryptCheck(String password, String 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -82,13 +82,13 @@ public class MetaUtil {
|
||||
conn = ds.getConnection();
|
||||
|
||||
// catalog和schema获取失败默认使用null代替
|
||||
String catalog = getCatalog(conn);
|
||||
final String catalog = getCatalog(conn);
|
||||
if (null == schema) {
|
||||
schema = getSchema(conn);
|
||||
}
|
||||
|
||||
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) {
|
||||
String table;
|
||||
while (rs.next()) {
|
||||
@ -116,9 +116,9 @@ public class MetaUtil {
|
||||
*/
|
||||
public static String[] getColumnNames(ResultSet rs) throws DbRuntimeException {
|
||||
try {
|
||||
ResultSetMetaData rsmd = rs.getMetaData();
|
||||
int columnCount = rsmd.getColumnCount();
|
||||
String[] labelNames = new String[columnCount];
|
||||
final ResultSetMetaData rsmd = rs.getMetaData();
|
||||
final int columnCount = rsmd.getColumnCount();
|
||||
final String[] labelNames = new String[columnCount];
|
||||
for (int i = 0; i < labelNames.length; i++) {
|
||||
labelNames[i] = rsmd.getColumnLabel(i + 1);
|
||||
}
|
||||
@ -137,17 +137,17 @@ public class MetaUtil {
|
||||
* @throws DbRuntimeException SQL执行异常
|
||||
*/
|
||||
public static String[] getColumnNames(DataSource ds, String tableName) {
|
||||
List<String> columnNames = new ArrayList<>();
|
||||
final List<String> columnNames = new ArrayList<>();
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = ds.getConnection();
|
||||
|
||||
// catalog和schema获取失败默认使用null代替
|
||||
String catalog = getCatalog(conn);
|
||||
String schema = getSchema(conn);
|
||||
final String catalog = getCatalog(conn);
|
||||
final String schema = getSchema(conn);
|
||||
|
||||
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) {
|
||||
while (rs.next()) {
|
||||
columnNames.add(rs.getString("COLUMN_NAME"));
|
||||
@ -225,7 +225,7 @@ public class MetaUtil {
|
||||
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 (rs.next()) {
|
||||
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) {
|
||||
while (rs.next()) {
|
||||
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) {
|
||||
while (rs.next()) {
|
||||
table.setColumn(Column.create(table, rs));
|
||||
@ -253,7 +253,7 @@ public class MetaUtil {
|
||||
}
|
||||
|
||||
// 获得索引信息(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<>();
|
||||
if (null != rs) {
|
||||
while (rs.next()) {
|
||||
|
@ -2,6 +2,7 @@ package cn.hutool.db.meta;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.db.DbRuntimeException;
|
||||
import cn.hutool.db.ds.DSFactory;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
@ -20,25 +21,34 @@ public class MetaUtilTest {
|
||||
|
||||
@Test
|
||||
public void getTablesTest() {
|
||||
List<String> tables = MetaUtil.getTables(ds);
|
||||
final List<String> tables = MetaUtil.getTables(ds);
|
||||
Assert.assertEquals("user", tables.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTableMetaTest() {
|
||||
Table table = MetaUtil.getTableMeta(ds, "user");
|
||||
final Table table = MetaUtil.getTableMeta(ds, "user");
|
||||
Assert.assertEquals(CollectionUtil.newHashSet("id"), table.getPkNames());
|
||||
}
|
||||
|
||||
@Test
|
||||
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);
|
||||
}
|
||||
|
||||
@Test
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ public final class SensitiveUtil {
|
||||
* @return 敏感词过滤处理后的bean对象
|
||||
*/
|
||||
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();
|
||||
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)) {
|
||||
return text;
|
||||
}
|
||||
@ -233,10 +233,10 @@ public final class SensitiveUtil {
|
||||
|
||||
final Map<Integer, FoundWord> foundWordMap = new HashMap<>(foundWordList.size(), 1);
|
||||
foundWordList.forEach(foundWord -> foundWordMap.put(foundWord.getStartIndex(), foundWord));
|
||||
int length = text.length();
|
||||
StringBuilder textStringBuilder = new StringBuilder();
|
||||
final int length = text.length();
|
||||
final StringBuilder textStringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
FoundWord fw = foundWordMap.get(i);
|
||||
final FoundWord fw = foundWordMap.get(i);
|
||||
if (fw != null) {
|
||||
textStringBuilder.append(sensitiveProcessor.process(fw));
|
||||
i = fw.getEndIndex();
|
||||
|
@ -105,7 +105,7 @@ public class CellUtil {
|
||||
cellType = cell.getCellType();
|
||||
}
|
||||
|
||||
Object value;
|
||||
final Object value;
|
||||
switch (cellType) {
|
||||
case NUMERIC:
|
||||
value = new NumericCellValue(cell).getValue();
|
||||
@ -199,14 +199,14 @@ public class CellUtil {
|
||||
*
|
||||
* @param row Excel表的行
|
||||
* @param cellIndex 列号
|
||||
* @return {@link Row}
|
||||
* @return {@link Cell}
|
||||
* @since 5.5.0
|
||||
*/
|
||||
public static Cell getCell(Row row, int cellIndex) {
|
||||
if (null == row) {
|
||||
return null;
|
||||
}
|
||||
Cell cell = row.getCell(cellIndex);
|
||||
final Cell cell = row.getCell(cellIndex);
|
||||
if (null == cell) {
|
||||
return new NullCell(row, cellIndex);
|
||||
}
|
||||
@ -218,7 +218,7 @@ public class CellUtil {
|
||||
*
|
||||
* @param row Excel表的行
|
||||
* @param cellIndex 列号
|
||||
* @return {@link Row}
|
||||
* @return {@link Cell}
|
||||
* @since 4.0.2
|
||||
*/
|
||||
public static Cell getOrCreateCell(Row row, int cellIndex) {
|
||||
@ -262,9 +262,10 @@ public class CellUtil {
|
||||
* @param sheet {@link Sheet}
|
||||
* @param x 列号,从0开始
|
||||
* @param y 行号,从0开始
|
||||
* @return 是否是合并单元格
|
||||
* @return 是否是合并单元格,如果提供的sheet为{@code null},返回{@code false}
|
||||
*/
|
||||
public static boolean isMergedRegion(Sheet sheet, int x, int y) {
|
||||
if (sheet != null) {
|
||||
final int sheetMergeCount = sheet.getNumMergedRegions();
|
||||
CellRangeAddress ca;
|
||||
for (int i = 0; i < sheetMergeCount; i++) {
|
||||
@ -274,9 +275,71 @@ public class CellUtil {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取合并单元格{@link CellRangeAddress},如果不是返回null
|
||||
*
|
||||
* @param sheet {@link Sheet}
|
||||
* @param locationRef 单元格地址标识符,例如A11,B5
|
||||
* @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)
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
setMergeCellStyle(cellStyle, cellRangeAddress, sheet);
|
||||
return sheet.addMergedRegion(cellRangeAddress);
|
||||
}
|
||||
|
||||
@ -406,7 +460,7 @@ public class CellUtil {
|
||||
anchor.setRow1(cell.getRowIndex());
|
||||
anchor.setRow2(cell.getRowIndex() + 2);
|
||||
}
|
||||
Comment comment = drawing.createCellComment(anchor);
|
||||
final Comment comment = drawing.createCellComment(anchor);
|
||||
comment.setString(factory.createRichTextString(commentText));
|
||||
comment.setAuthor(StrUtil.nullToEmpty(commentAuthor));
|
||||
cell.setCellComment(comment);
|
||||
@ -435,5 +489,25 @@ public class CellUtil {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Excel中单元格设置相关类,一些{@link cn.hutool.poi.excel.cell.CellSetter}的实现类
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
package cn.hutool.poi.excel.cell.setters;
|
Loading…
x
Reference in New Issue
Block a user