Skip to content

Commit

Permalink
Merge pull request #16 from ClearXs/1.1.x
Browse files Browse the repository at this point in the history
1.1.x
  • Loading branch information
ClearXs authored Apr 4, 2024
2 parents fd7189d + e7e0977 commit a7c6d1d
Show file tree
Hide file tree
Showing 51 changed files with 990 additions and 401 deletions.
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

0 comments on commit a7c6d1d

Please sign in to comment.