Skip to content

Commit

Permalink
增加method proxy的quick方法
Browse files Browse the repository at this point in the history
  • Loading branch information
leaderli committed Dec 19, 2024
1 parent 85f9ca7 commit cf15b77
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import io.leaderli.litool.core.meta.Lira;
import io.leaderli.litool.core.type.ClassUtil;
import io.leaderli.litool.core.type.LiTypeToken;
import io.leaderli.litool.core.type.PrimitiveEnum;
import io.leaderli.litool.core.type.TypeUtil;

import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Type;

Expand All @@ -25,9 +27,44 @@ public <T> TypeAdapter<T> create(Lean lean, LiTypeToken<T> typeToken) {
return null;
}
type = ((GenericArrayType) type).getGenericComponentType();
Class<?> rawType = TypeUtil.erase(type);
if (rawType.isPrimitive()) {
return new PrimitiveArrayAdapter(rawType);
}
return new ArrayAdapter(rawType, lean.getTypeAdapter(type));

}

@SuppressWarnings({"unchecked", "rawtypes"})
// 原始类型,没有泛型
public static final class PrimitiveArrayAdapter implements TypeAdapter {
private final Class componentType;
private final PrimitiveTypeAdapterFactory.PrimitiveTypeAdapter elementTypeAdapter;

return new ArrayAdapter(TypeUtil.erase(type), lean.getTypeAdapter(type));
public PrimitiveArrayAdapter(Class componentType) {
this.componentType = componentType;
this.elementTypeAdapter = new PrimitiveTypeAdapterFactory.PrimitiveTypeAdapter(PrimitiveEnum.get(componentType));
}

@Override
public Object read(Object source, Lean lean) {

Object[] arr = Lira.iterableItr(source)
.map(e -> elementTypeAdapter.read(e, lean))
.nullable(() -> elementTypeAdapter.read(lean))
.toNullableArray(componentType);
Object copy = Array.newInstance(componentType, arr.length);
for (int i = 0; i < arr.length; i++) {
Array.set(copy, i, arr[i]);
}
return copy;
}


@Override
public Object read(Lean lean) {
return Array.newInstance(componentType, 0);
}
}

public static final class ArrayAdapter<E> implements TypeAdapter<E[]> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,36 @@
*/
public class PrimitiveTypeAdapterFactory implements TypeAdapterFactory {

@SuppressWarnings("unchecked")
// 原始类型,没有泛型
@Override
public <T> TypeAdapter<T> create(Lean lean, LiTypeToken<T> typeToken) {
Class<? super T> rawType = typeToken.getRawType();
PrimitiveEnum primitiveEnum = PrimitiveEnum.get(rawType);
if (primitiveEnum == PrimitiveEnum.OBJECT) {
return null;
}
return new PrimitiveTypeAdapter<>(primitiveEnum);
return new PrimitiveTypeAdapter(primitiveEnum);
}

static class PrimitiveTypeAdapter<T> implements TypeAdapter<T> {
@SuppressWarnings("rawtypes")
static class PrimitiveTypeAdapter implements TypeAdapter {
private final PrimitiveEnum primitiveEnum;

PrimitiveTypeAdapter(PrimitiveEnum primitiveEnum) {
this.primitiveEnum = primitiveEnum;
}

@Override
public T read(Object source, Lean lean) {
public Object read(Object source, Lean lean) {
return primitiveEnum.read(source);
}

@SuppressWarnings("unchecked")
@Override
public T read(Lean lean) {
return (T) primitiveEnum.zero_value;

public Object read(Lean lean) {
return primitiveEnum.zero_value;
}


}

}
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,12 @@ void test11() {

@Test
void copyBean() {
String json = "{\"name\": [\"123\"],\"ages\": [10,18]}";
String json = "{\"name\": [\"123\"],\"ages\": [10,18],\"height\": [110,120]}";

Lean lean = new Lean();
Bean12<Integer> bean = lean.fromBean(gson.fromJson(json, Map.class), new LiTypeToken<Bean12<Integer>>() {
});
Assertions.assertEquals(110, bean.height[0]);
Assertions.assertEquals(10, bean.ages[0]);
Assertions.assertThrows(ClassCastException.class, () -> {
Bean12<Integer> bean12 = lean.fromBean(gson.fromJson(json, Map.class), new LiTypeToken<Bean12<Integer>>() {
Expand Down Expand Up @@ -322,6 +323,7 @@ private static class Bean13 {
private static class Bean12<T> {
private String[] name;
private T[] ages;
private int[] height;
}

private static class Bean11<T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ void tuple() {
@Test
void toArray() {

int[] aa = new int[1];
System.out.println(Arrays.toString(Lira.of(IterableItr.of(new int[]{1, 2, 3})).toArray(int.class)));
Assertions.assertArrayEquals(new Number[0], Lira.of().cast(Integer.class).toArray(Number.class));

Number[] nums = Lira.of(1, 2, 3, 4.0).cast(Integer.class).toArray(Number.class);
Expand Down
34 changes: 34 additions & 0 deletions litool-test/src/main/java/io/leaderli/litool/test/MethodProxy.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package io.leaderli.litool.test;

import io.leaderli.litool.core.lang.lean.Lean;
import io.leaderli.litool.core.type.ClassUtil;
import io.leaderli.litool.core.type.ReflectUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public interface MethodProxy<T> {

Expand All @@ -25,6 +31,34 @@ static MethodProxy<?> of() {
return (m, args) -> ReflectUtil.newInstance(m.getReturnType()).assertNotNone().get();
}

@SuppressWarnings({"unchecked", "rawtypes"})
static MethodProxy<?> quick(Object... items) {
return (m, args) -> {
Class<?> returnType = m.getReturnType();
if (ClassUtil.isAssignableFromOrIsWrapper(Collection.class, returnType) || returnType.isArray()) {
return Lean.INSTANCE.fromBean(items, returnType);
// Object o = BeanCreator.create(returnType).build().create();
// Collection list = (Collection) ((?) o).assertNotNone().get();
// list.addAll(Arrays.asList(items));
// return list;
} else if (ClassUtil.isAssignableFromOrIsWrapper(Map.class, returnType)) {
Map map = (Map) Lean.INSTANCE.fromBean(null, returnType);
for (int i = 0; i < items.length - 1; i = i + 2) {
map.put(items[i], items[i + 1]);
}
return map;
}
Object bean = Lean.INSTANCE.fromBean(new Object(), returnType);
if (bean != null) {
List<Field> fields = ReflectUtil.getFields(returnType).get();
for (int i = 0; i < items.length; i++) {
ReflectUtil.setFieldValue(bean, fields.get(i), items[i]);
}
}
return bean;
};
}

/**
* 增加多线程支持,避免相互影响
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package io.leaderli.litool.test;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

class MethodProxyTest {

MethodProxyTest() throws NoSuchMethodException {
}

@SuppressWarnings("rawtypes")
@Test
void test() throws Throwable {

MethodProxy<?> quick = MethodProxy.quick(1, 2, 3);

Assertions.assertArrayEquals(new Integer[]{1, 2, 3}, (Object[]) quick.apply(m1, null));
Assertions.assertArrayEquals(new int[]{1, 2, 3}, (int[]) quick.apply(m2, null));
List list = (List) quick.apply(m3, null);
Assertions.assertEquals(3, list.size());
Map map = (Map) quick.apply(m4, null);
Assertions.assertEquals(1, map.size());

Bean bean = (Bean) quick.apply(m5, null);
Assertions.assertEquals(2, bean.age);
Assertions.assertEquals(3, bean.gender);
}

Method m1 = MethodProxyTest.class.getMethod("m1");
Method m2 = MethodProxyTest.class.getMethod("m2");
Method m3 = MethodProxyTest.class.getMethod("m3");
Method m4 = MethodProxyTest.class.getMethod("m4");
Method m5 = MethodProxyTest.class.getMethod("m5");

public Integer[] m1() {
return null;
}

public int[] m2() {
return null;
}

public List<Integer> m3() {
return null;
}

public Map<String, Integer> m4() {
return null;
}

public Bean m5() {
return null;
}

private static class Bean {
private final String name = "0";
/**
* 测试只有get
*/
private int age;
/**
* 测试只有set
*/
private Integer gender;
}
}

0 comments on commit cf15b77

Please sign in to comment.