Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 2.3.1 #13

Merged
merged 23 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
881eb84
Upgrade 2.1.0
Aug 23, 2023
75276f0
【json】注解 Sensitive 增加 strategyType 用于定义脱敏策略类,优先级高于 strategy
Sep 4, 2023
8f3b0a6
【beans】字符串拼接优化
Sep 4, 2023
6e34679
【core】修复 ClassUtils instantiate 方法初始化类时,参数长度错误判断异常
Sep 4, 2023
1ad633f
【httpclient】okhttp3 连接池关闭时驱逐连接资源
Sep 4, 2023
541bb3c
【ALL】代码格式化
Sep 4, 2023
d4c3dfa
【web】修复获取客户端真实 IP 注解判断错误 BUG
Sep 4, 2023
42c31a4
【ALL】代码格式化
Sep 4, 2023
56256a9
【dao】数据库分页插件
Sep 15, 2023
2811913
【json】优化脱敏序列化
Sep 15, 2023
31b070e
【ALL】代码格式化
Sep 15, 2023
da1e585
【dao】分页插件优化
Sep 15, 2023
4443121
【dao】mybatis 分页插件优化
Sep 15, 2023
c80187d
【core】新增日期、时间格式化工具类
Sep 21, 2023
04870a0
【dao】修改 MyBatisDao 的 @Target 值
Sep 21, 2023
c76af91
【core】新增线程池饱和策略、DateTime 新增日期时间对象、日历对象、时钟对象转换为时间戳方法
Oct 10, 2023
f7f246b
【beans】新增 bean 转换器 BeanConverter , 支持 map、bean 互转
Nov 16, 2023
f165f54
【core】代码格式优化
Nov 16, 2023
af5a511
【lang】根据原始类型返回其包装类型
Nov 16, 2023
9c31365
【dao】修复修改数据 BUG
Nov 16, 2023
14c3748
【beans】属性转换优化
Nov 16, 2023
5b85acb
Release 2.3.1
Nov 17, 2023
662cee2
Merge pull request #12 from buession/development
eduosi Nov 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 37 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,41 @@
===========================


## [2.3.0](https://github.com/buession/buession-security/releases/tag/v2.3.0) (2023-08-15)
## [2.3.1](https://github.com/buession/buessionframework/releases/tag/v2.3.1) (2023-11-17)

### 🔨依赖升级

- [依赖库版本升级和安全漏洞修复](https://github.com/buession/buession-parent/releases/tag/v2.3.1)


### ⭐ 新特性

- **buession-beans:** 新增 bean 转换器 BeanConverter , 支持 map、bean 互转
- **buession-core:** 新增日期、时间格式化工具类 DateFormatUtils
- **buession-core:** DateTime 新增日期时间对象、日历对象、时钟对象转换为时间戳方法
- **buession-core:** 新增线程池饱和策略 ThreadPolicy
- **buession-dao:** 新增实验性的 MyBatis 分页插件
- **buession-json:** 注解 Sensitive 增加 strategyType 用于定义脱敏策略类,优先级高于 strategy


### 🐞 Bug 修复

- **buession-core:** 修复 ClassUtils instantiate 方法初始化类时,参数长度错误判断异常
- **buession-core:** 修复 MapBuilder 增加 putIfPresent 方法,值不为 null 时添加到 Map 中
- **buession-dao:** 修复修改数据 BUG
- **buession-web:** 修复获取客户端真实 IP 注解判断错误 BUG
- **buession-web:** 修复 velocity JsonTool 为设置日期时间格式时,无法设置时区的 BUG


### ⏪ 优化

- **buession-httpclient:** okhttp3 连接池关闭时驱逐连接资源


---


## [2.3.0](https://github.com/buession/buessionframework/releases/tag/v2.3.0) (2023-08-15)

### 🔨依赖升级

Expand Down Expand Up @@ -66,7 +100,7 @@
---


## [2.2.1](https://github.com/buession/buession-security/releases/tag/v2.2.1) (2023-03-31)
## [2.2.1](https://github.com/buession/buessionframework/releases/tag/v2.2.1) (2023-03-31)

### 🔨依赖升级

Expand All @@ -86,7 +120,7 @@
---


## [2.2.0](https://github.com/buession/buession-security/releases/tag/v2.2.0) (2023-03-10)
## [2.2.0](https://github.com/buession/buessionframework/releases/tag/v2.2.0) (2023-03-10)

### 🔨依赖升级

Expand Down
2 changes: 1 addition & 1 deletion buession-aop/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>com.buession</groupId>
<artifactId>buession-parent</artifactId>
<relativePath>../buession-parent</relativePath>
<version>2.3.0</version>
<version>2.3.1</version>
</parent>
<artifactId>buession-aop</artifactId>
<url>http://www.buession.com/</url>
Expand Down
2 changes: 1 addition & 1 deletion buession-beans/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>com.buession</groupId>
<artifactId>buession-parent</artifactId>
<relativePath>../buession-parent</relativePath>
<version>2.3.0</version>
<version>2.3.1</version>
</parent>
<artifactId>buession-beans</artifactId>
<url>http://www.buession.com/</url>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*
* =========================================================================================================
*
* This software consists of voluntary contributions made by many individuals on behalf of the
* Apache Software Foundation. For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* +-------------------------------------------------------------------------------------------------------+
* | License: http://www.apache.org/licenses/LICENSE-2.0.txt |
* | Author: Yong.Teng <webmaster@buession.com> |
* | Copyright @ 2013-2023 Buession.com Inc. |
* +-------------------------------------------------------------------------------------------------------+
*/
package com.buession.beans;

import com.buession.beans.converters.*;
import com.buession.core.utils.Assert;
import com.buession.core.utils.FieldUtils;
import com.buession.core.utils.StringUtils;
import com.buession.lang.Primitive;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.beans.BeanMap;

import java.io.File;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* Bean 转换器抽象类
*
* @author Yong.Teng
* @since 2.3.1
*/
public abstract class AbstractBeanConverter implements BeanConverter {

private final static Map<String, BeanCopier> BEAN_COPIERS = new ConcurrentHashMap<>(32);

private final static Map<String, BeanMap> BEAN_MAPS = new ConcurrentHashMap<>(32);

private final static Map<Class<?>, BeanPropertyConverter<?>> converters = new ConcurrentHashMap<>(24);

private final static Logger logger = LoggerFactory.getLogger(AbstractBeanConverter.class);

/**
* 构造函数
*/
public AbstractBeanConverter() {
initDefaultBeanPropertyConverters();
}

/**
* 注册 bean 属性转换器
*
* @param type
* 类型
* @param propertyConverter
* bean 属性转换器
*/
public void registerConverter(Class<?> type, BeanPropertyConverter<?> propertyConverter) {
converters.put(type, propertyConverter);
}

@Override
public <S, T> T convert(final S source, final T target) {
Assert.isNull(target, "No destination bean specified.");

if(source == null){
return null;
}

final boolean isSourceMap = source instanceof Map;
final boolean isTargetMap = target instanceof Map;

if(isSourceMap && isTargetMap){
return mapToMap(source, target);
}

if(isSourceMap && isTargetMap == false){
return mapToBean(source, target);
}

if(isSourceMap == false && isTargetMap){
return beanToMap(source, target);
}

return beanToBean(source, target);
}

@SuppressWarnings({"unchecked"})
protected <S, T> T mapToMap(final S source, final T target) {
Map<Object, Object> sourceMap = (Map<Object, Object>) source;
Map<Object, Object> targetMap = (Map<Object, Object>) target;

targetMap.putAll(sourceMap);

return target;
}

@SuppressWarnings({"unchecked"})
protected <S, T> T mapToBean(final S source, final T target) {
final Map<Object, Object> sourceMap = (Map<Object, Object>) source;
final String cacheKey = buildCacheKey(source, target);
final BeanMap beanMap = BEAN_MAPS.computeIfAbsent(cacheKey, (key)->BeanMap.create(target));

sourceMap.forEach((key, value)->{
if(key instanceof CharSequence){
String strKey = (String) key;
String propertyName;

if(StringUtils.contains(strKey, '_')){
StringBuilder sb = new StringBuilder(strKey.length());

for(int i = 0; i < strKey.length(); i++){
char c = strKey.charAt(i);

if(c == '_'){
c = strKey.charAt(++i);
sb.append((char) (c - 32));
}else{
sb.append(c);
}
}

propertyName = sb.toString();
}else{
propertyName = strKey;
}

Field field = FieldUtils.getField(target.getClass(), propertyName, true);

if(field != null){
Class<?> fieldType = field.getType();
final BeanPropertyConverter<?> propertyConverter = converters.get(
Primitive.primitiveToWrapper(fieldType));

try{
if(propertyConverter == null){
beanMap.put(propertyName, value);
}else{
beanMap.put(propertyName, propertyConverter.convert(value));
}
}catch(Exception e){
if(logger.isWarnEnabled()){
logger.warn(e.getMessage());
}
}
}
}
});

return target;
}

@SuppressWarnings({"unchecked"})
protected <S, T> T beanToMap(final S source, final T target) {
final String cacheKey = buildCacheKey(source, target);
final BeanMap beanMap = BEAN_MAPS.computeIfAbsent(cacheKey, (key)->BeanMap.create(source));
final Map<Object, Object> targetMap = (Map<Object, Object>) target;

targetMap.putAll(beanMap);

return target;
}

@SuppressWarnings({"unchecked", "rawtype"})
protected <S, T> T beanToBean(final S source, final T target) {
final String cacheKey = buildCacheKey(source, target);
final BeanCopier beanCopier = BEAN_COPIERS.computeIfAbsent(cacheKey,
(key)->BeanCopier.create(source.getClass(), target.getClass(), true));

beanCopier.copy(source, target, (value, targetType, setter)->{
if(value == null){
return null;
}else if(targetType.equals(value.getClass())){
return value;
}else{
final BeanPropertyConverter<?> propertyConverter = converters.get(
Primitive.primitiveToWrapper(targetType));

if(propertyConverter == null){
return value;
}else{
return propertyConverter.convert(value);
}
}
});

return target;
}

private static <S, T> String buildCacheKey(final S source, final T target) {
return source.getClass().getName() + '_' + target.getClass().getName();
}

private void initDefaultBeanPropertyConverters() {
converters.put(Byte.class, new BytePropertyConverter());
converters.put(Short.class, new ShortPropertyConverter());
converters.put(Integer.class, new IntegerPropertyConverter());
converters.put(Long.class, new LongPropertyConverter());
converters.put(Float.class, new FloatPropertyConverter());
converters.put(Double.class, new DoublePropertyConverter());
converters.put(BigDecimal.class, new BigDecimalPropertyConverter());
converters.put(BigInteger.class, new BigIntegerPropertyConverter());

converters.put(Boolean.class, new BooleanPropertyConverter());

converters.put(Character.class, new CharacterPropertyConverter());
converters.put(String.class, new StringPropertyConverter());

converters.put(Calendar.class, new CalendarPropertyConverter());
converters.put(java.util.Date.class, new DatePropertyConverter());
converters.put(LocalDate.class, new LocalDatePropertyConverter());
converters.put(LocalDateTime.class, new LocalDateTimePropertyConverter());
converters.put(java.sql.Date.class, new SqlDatePropertyConverter());
converters.put(java.sql.Time.class, new SqlTimePropertyConverter());
converters.put(java.sql.Timestamp.class, new SqlTimestampPropertyConverter());
converters.put(Instant.class, new InstantPropertyConverter());

converters.put(Class.class, new ClassPropertyConverter());

converters.put(File.class, new FilePropertyConverter());
converters.put(Path.class, new PathPropertyConverter());

converters.put(URI.class, new URIPropertyConverter());
converters.put(URL.class, new URLPropertyConverter());
}

}
Loading
Loading