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

1.1.x #16

Merged
merged 3 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
70 changes: 40 additions & 30 deletions uno-core/src/main/java/cc/allio/uno/core/bean/BeanInfoWrapper.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package cc.allio.uno.core.bean;

import cc.allio.uno.core.reflect.ReflectTools;
import cc.allio.uno.core.type.TypeValue;
import cc.allio.uno.core.type.Types;
import cc.allio.uno.core.util.ClassUtils;
import cc.allio.uno.core.util.Values;
import lombok.Getter;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.K;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
Expand All @@ -15,18 +15,19 @@
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;

/**
* 增强对Bean对象的操作。<b>禁止在Bean上添加{@link lombok.experimental.Accessors}</b>的注解
* <p>required</p>
* <ol>
* <li>Bean必须要是Public</li>
* <li>bean must visibility is public</li>
* <li>bean must be has setter and getter methods</li>
* </ol>
*
* @author j.x
Expand Down Expand Up @@ -63,6 +64,29 @@ public Flux<PropertyDescriptor> findAll() {
});
}

/**
* find all property
*
* @return the property list
*/
public List<PropertyDescriptor> properties() {
AtomicReference<List<PropertyDescriptor>> ref = new AtomicReference<>();
findAll().collectList().doOnNext(ref::set).subscribe();
return ref.get();
}

/**
* find all property name
*
* @return the name list
*/
public List<String> names() {
return Arrays.stream(beanInfo.getPropertyDescriptors())
.map(PropertyDescriptor::getName)
.filter(name -> !"class".equals(name))
.toList();
}

/**
* 根据字段名称查找这个字段对应的Descriptor
*
Expand Down Expand Up @@ -214,13 +238,12 @@ public synchronized <K extends T> K setCoverageForce(K target, String name, bool
public synchronized <K extends T> Mono<K> setCoverage(K target, String name, boolean forceCoverage, Object... value) {
Assert.notNull(name, "target must not null");
return findByName(name)
.flatMap(descriptor ->
write(target, descriptor, forceCoverage, value)
.onErrorContinue((error, o) -> {
if (log.isWarnEnabled()) {
log.warn("target {} setValue field {} value error setValue empty", target.getClass().getSimpleName(), name);
}
}));
.flatMap(descriptor -> write(target, descriptor, forceCoverage, value))
.onErrorContinue((error, o) -> {
if (log.isWarnEnabled()) {
log.warn("target {} setValue field {} value error setValue empty", target.getClass().getSimpleName(), name);
}
});
}

/**
Expand Down Expand Up @@ -260,27 +283,15 @@ private Mono<Object> read(Object target, PropertyDescriptor descriptor) {
private <K extends T> Mono<K> write(K target, PropertyDescriptor descriptor, boolean forceCoverage, Object... args) {
Mono<K> writeMono = Mono.justOrEmpty(descriptor.getWriteMethod())
.flatMap(writeMethod ->
TypeValue.of(writeMethod.getParameterTypes(), args)
.map(TypeValue::tryTransfer)
TypeValue.of(writeMethod.getParameterTypes(), args, () -> ReflectTools.drawn(writeMethod))
.map(TypeValue::tryConvert)
.collectList()
.flatMap(values -> {
try {
Class<?> propertyType = descriptor.getPropertyType();
if (Types.isArray(propertyType)) {
// 数组赋值
Object[] arrayValues = values.stream()
.flatMap(o -> {
if (Types.isArray(o.getClass())) {
return Stream.of((Object[]) o);
}
return Stream.empty();
})
.toArray(Object[]::new);
Object o = Array.newInstance(ClassUtils.getArrayClassType(propertyType), arrayValues.length);
for (int i = 0; i < arrayValues.length; i++) {
Array.set(o, i, arrayValues[i]);
}
writeMethod.invoke(target, o);
Object[] arrayValues = Values.expandCollection(values);
writeMethod.invoke(target, arrayValues);
} else {
writeMethod.invoke(target, values.toArray());
}
Expand All @@ -290,8 +301,7 @@ private <K extends T> Mono<K> write(K target, PropertyDescriptor descriptor, boo
}
}
return Mono.just(target);
})
);
}));
if (forceCoverage) {
return writeMono;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ protected Mono<Object> executeAssignmentAction(String name,
Class<?> type = mappingField.getType();
// 尝试进行类型转换
if (type != null) {
setter = new TypeValue(type, setter).tryTransfer();
setter = new TypeValue(type, setter).tryConvert();
}
// 设置值在values
Object setValue = setter;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package cc.allio.uno.core.reflect;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor(staticName = "of")
public class BinaryClassKey {

private final Class<?> cls1;
private final Class<?> cls2;
}
57 changes: 57 additions & 0 deletions uno-core/src/main/java/cc/allio/uno/core/reflect/DrawnClass.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package cc.allio.uno.core.reflect;

import cc.allio.uno.core.util.ObjectUtils;
import com.google.common.collect.Lists;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
* Drawn to class
*
* @author j.x
* @date 2024/4/4 17:59
* @since 1.1.8
*/
public class DrawnClass implements DrawnGeneric<Class<?>> {

@Override
public ParameterizedFinder drawn(Class<?> reflectType) {
List<ParameterizedType> parameterizedTypes = drawnClass(reflectType);
return new ParameterizedFinder(reflectType, parameterizedTypes);
}

/**
* 从给定的Class对象中获取{@link ParameterizedType}类型,该方法将会递归查找所有范型父类以及范型接口
*
* @param reflectType the reflection class
* @return the {@link ParameterizedType} list
*/
List<ParameterizedType> drawnClass(Class<?> reflectType) {
List<ParameterizedType> types = Lists.newArrayList();
Type genericSuperclass = reflectType.getGenericSuperclass();
if (genericSuperclass != null) {
if (genericSuperclass instanceof Class<?> superClass && !Object.class.isAssignableFrom(superClass)) {
List<ParameterizedType> superParameterizedType = drawnClass(superClass);
types.addAll(superParameterizedType);
}
if (genericSuperclass instanceof ParameterizedType parameterizedSuperclass) {
types.add(parameterizedSuperclass);
}
}
Type[] genericInterfaces = reflectType.getGenericInterfaces();
if (ObjectUtils.isNotEmpty(genericInterfaces)) {
for (Type genericInterface : genericInterfaces) {
if (genericInterface instanceof Class<?> superInterface) {
List<ParameterizedType> superParameterizedType = drawnClass(superInterface);
types.addAll(superParameterizedType);
}
if (genericInterface instanceof ParameterizedType parameterizedType) {
types.add(parameterizedType);
}
}
}
return types;
}
}
27 changes: 27 additions & 0 deletions uno-core/src/main/java/cc/allio/uno/core/reflect/DrawnField.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package cc.allio.uno.core.reflect;

import com.google.common.collect.Lists;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;

/**
* Drawn to {@link Field}
*
* @author j.x
* @date 2024/4/4 18:00
* @since 1.1.8
*/
public class DrawnField implements DrawnGeneric<Field> {

@Override
public ParameterizedFinder drawn(Field reflectType) {
Type genericType = reflectType.getGenericType();
if (genericType instanceof ParameterizedType parameterizedType) {
return new ParameterizedFinder(reflectType, Lists.newArrayList(parameterizedType));
}
return new ParameterizedFinder(reflectType, Collections.emptyList());
}
}
22 changes: 22 additions & 0 deletions uno-core/src/main/java/cc/allio/uno/core/reflect/DrawnGeneric.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cc.allio.uno.core.reflect;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;

/**
* drawn reflection type to actual generic type
*
* @author j.x
* @date 2024/4/4 17:58
* @since 1.1.8
*/
public interface DrawnGeneric<T> {

/**
* returns {@link ParameterizedType} of list base on reflect type.
*
* @param reflectType like as {@link Class}, {@link Method} ...
* @return the {@link ParameterizedType} list
*/
ParameterizedFinder drawn(T reflectType);
}
36 changes: 36 additions & 0 deletions uno-core/src/main/java/cc/allio/uno/core/reflect/DrawnMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package cc.allio.uno.core.reflect;

import com.google.common.collect.Streams;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.stream.Stream;

/**
* Drawn to method
*
* @author j.x
* @date 2024/4/4 18:00
* @since 1.1.8
*/
public class DrawnMethod implements DrawnGeneric<Method> {

@Override
public ParameterizedFinder drawn(Method reflectType) {
Type genericReturnType = reflectType.getGenericReturnType();
Type[] genericExceptionTypes = reflectType.getGenericExceptionTypes();
Type[] genericParameterTypes = reflectType.getGenericParameterTypes();
List<ParameterizedType> parameterizedTypes =
Streams.concat(
Stream.of(genericReturnType),
Stream.of(genericExceptionTypes),
Stream.of(genericParameterTypes)
)
.filter(type -> ParameterizedType.class.isAssignableFrom(type.getClass()))
.map(ParameterizedType.class::cast)
.toList();
return new ParameterizedFinder(reflectType, parameterizedTypes);
}
}
Loading
Loading