Skip to content

Commit

Permalink
Merge pull request #15 from jitwxs/dev
Browse files Browse the repository at this point in the history
1.15-RELEASE
  • Loading branch information
jitwxs committed Apr 10, 2023
2 parents 701f961 + dbffae4 commit 8d3331a
Show file tree
Hide file tree
Showing 22 changed files with 370 additions and 83 deletions.
17 changes: 16 additions & 1 deletion easydata-sample/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.agrona</groupId>
<artifactId>agrona</artifactId>
<version>1.18.0</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
<version>4.1.91.Final</version>
</dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
<version>8.5.12</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
Expand Down Expand Up @@ -57,7 +72,7 @@
<dependency>
<groupId>io.github.jitwxs</groupId>
<artifactId>easydata</artifactId>
<version>1.14-RELEASE</version>
<version>1.15-RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package io.github.jitwxs.easydata.sample.core.mock.primitive;

import io.github.jitwxs.easydata.common.bean.MockConfig;
import io.github.jitwxs.easydata.core.mock.EasyMock;
import io.github.jitwxs.easydata.core.mock.TypeKit;
import org.agrona.collections.Long2LongHashMap;
import org.agrona.collections.Long2ObjectHashMap;
import org.agrona.collections.LongHashSet;
import org.agrona.collections.Object2IntHashMap;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.function.Supplier;

import static org.junit.jupiter.api.Assertions.*;

/**
* test primitive data struct support with easymock
*
* this case will use <a href="https://github.com/real-logic/agrona">agrona</a> library
*
* @author jitwxs@foxmail.com
* @since 2023-04-11 0:15
*/
public class AgronaPrimitiveStructTest {
@Test
@DisplayName("agrona | key map")
public void testAgronaKMap() {
// initial with TypeKit
final Long2ObjectHashMap<String> map = assertDoesNotThrow(() -> EasyMock.run(new TypeKit<Long2ObjectHashMap<String>>() {
}));
assertFalse(map.isEmpty());

// initial with generic
final Long2ObjectHashMap map1 = assertDoesNotThrow(() -> EasyMock.run(Long2ObjectHashMap.class));
assertFalse(map1.isEmpty());
}

@Test
@DisplayName("agrona | value map")
public void testAgronaVMap() {
final Supplier<MockConfig> mockConfigSupplier = () -> new MockConfig().registerConstructorSupplier(() -> new Object2IntHashMap(-1));

// initial with TypeKit
final Object2IntHashMap<String> map = assertDoesNotThrow(() -> EasyMock.run(new TypeKit<Object2IntHashMap<String>>() {
}, mockConfigSupplier.get()));
assertFalse(map.isEmpty());

// initial with generic
final Object2IntHashMap map1 = assertDoesNotThrow(() -> EasyMock.run(Object2IntHashMap.class, mockConfigSupplier.get()));
assertFalse(map1.isEmpty());
}

@Test
@DisplayName("agrona | key-value map")
public void testAgronaKVMap() {
final Supplier<MockConfig> mockConfigSupplier = () -> new MockConfig().registerConstructorSupplier(() -> new Long2LongHashMap(-1));

// initial with TypeKit
final Long2LongHashMap map = assertDoesNotThrow(() -> EasyMock.run(new TypeKit<Long2LongHashMap>() {
}, mockConfigSupplier.get()));
assertFalse(map.isEmpty());

// initial with generic
final Long2LongHashMap map1 = assertDoesNotThrow(() -> EasyMock.run(Long2LongHashMap.class, mockConfigSupplier.get()));
assertFalse(map1.isEmpty());
}

@Test
@DisplayName("agrona | key set")
public void testAgronaKSet() {
// initial with TypeKit
final LongHashSet set = assertDoesNotThrow(() -> EasyMock.run(new TypeKit<LongHashSet>() {
}));
assertFalse(set.isEmpty());

// initial with generic
final LongHashSet set1 = assertDoesNotThrow(() -> EasyMock.run(LongHashSet.class));
assertFalse(set1.isEmpty());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package io.github.jitwxs.easydata.sample.core.mock.primitive;

import io.github.jitwxs.easydata.core.mock.EasyMock;
import io.github.jitwxs.easydata.core.mock.TypeKit;
import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertFalse;

/**
* test primitive data struct support with easymock
*
* this case will use <a href="https://github.com/vigna/fastutil">fastutil</a> library
*
* @author jitwxs@foxmail.com
* @since 2023-04-11 0:15
*/
public class FastutilPrimitiveStructTest {
@Test
@DisplayName("fastutil | key map")
public void testFastutilaKMap() {
// initial with TypeKit
final Long2ObjectOpenHashMap<String> map = assertDoesNotThrow(() -> EasyMock.run(new TypeKit<Long2ObjectOpenHashMap<String>>() {
}));
assertFalse(map.isEmpty());

// initial with generic
final Long2ObjectOpenHashMap map1 = assertDoesNotThrow(() -> EasyMock.run(Long2ObjectOpenHashMap.class));
assertFalse(map1.isEmpty());
}

@Test
@DisplayName("fastutil | value map")
public void testFastutilaVMap() {
// initial with TypeKit
final Object2IntOpenHashMap<String> map = assertDoesNotThrow(() -> EasyMock.run(new TypeKit<Object2IntOpenHashMap<String>>() {
}));
assertFalse(map.isEmpty());

// initial with generic
final Object2IntOpenHashMap map1 = assertDoesNotThrow(() -> EasyMock.run(Object2IntOpenHashMap.class));
assertFalse(map1.isEmpty());
}

@Test
@DisplayName("fastutil | key-value map")
public void testFastutilaKVMap() {
// initial with TypeKit
final Long2LongOpenHashMap map = assertDoesNotThrow(() -> EasyMock.run(new TypeKit<Long2LongOpenHashMap>() {
}));
assertFalse(map.isEmpty());

// initial with generic
final Long2LongOpenHashMap map1 = assertDoesNotThrow(() -> EasyMock.run(Long2LongOpenHashMap.class));
assertFalse(map1.isEmpty());
}

@Test
@DisplayName("fastutil | key set")
public void testFastutilaKSet() {
// initial with TypeKit
final LongOpenHashSet set = assertDoesNotThrow(() -> EasyMock.run(new TypeKit<LongOpenHashSet>() {
}));
assertFalse(set.isEmpty());

// initial with generic
final LongOpenHashSet set1 = assertDoesNotThrow(() -> EasyMock.run(LongOpenHashSet.class));
assertFalse(set1.isEmpty());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.github.jitwxs.easydata.sample.core.mock.primitive;

import io.github.jitwxs.easydata.core.mock.EasyMock;
import io.github.jitwxs.easydata.core.mock.TypeKit;
import io.netty.util.collection.LongObjectHashMap;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertFalse;

/**
* test primitive data struct support with easymock
*
* this case will use <a href="https://github.com/netty/netty">netty</a> library
*
* @author jitwxs@foxmail.com
* @since 2023-04-11 0:15
*/
public class NettyPrimitiveStructTest {
@Test
@DisplayName("netty | key map")
public void testNettyKMap() {
// initial with TypeKit
final LongObjectHashMap<String> map = assertDoesNotThrow(() -> EasyMock.run(new TypeKit<LongObjectHashMap<String>>() {
}));
assertFalse(map.isEmpty());

// initial with generic
final LongObjectHashMap map1 = assertDoesNotThrow(() -> EasyMock.run(LongObjectHashMap.class));
assertFalse(map1.isEmpty());
}
}
2 changes: 1 addition & 1 deletion easydata/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>io.github.jitwxs</groupId>
<artifactId>easydata</artifactId>
<version>1.14-RELEASE</version>
<version>1.15-RELEASE</version>
<packaging>jar</packaging>

<name>easydata</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private static Map<String, FieldProperty> createByProtoBean(final Class<?> baseT
if (classGroup == ClassGroupEnum.PROTOBUF_MESSAGE) {
builder = (Message.Builder) ObjectUtils.createBuilder(baseTarget, ClassGroupEnum.Group.PROTOBUF);
} else {
builder = (Message.Builder) ObjectUtils.create(baseTarget);
builder = (Message.Builder) ObjectUtils.create(baseTarget, null);
}

final Map<String, FieldProperty> resultMap = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;

/**
* @author jitwxs@foxmail.com
Expand Down Expand Up @@ -79,6 +80,8 @@ public class MockConfig {

private final Map<Class<?>, BeanMockInterceptor<?>> beanMockInterceptorMap = new HashMap<>();

private final Map<Class<?>, Supplier> constructorSupplierMap = new HashMap<>();

@SuppressWarnings("rawtypes")
public MockConfig init(Type type) {
if (type instanceof ParameterizedType) {
Expand Down Expand Up @@ -206,6 +209,22 @@ public <T> MockConfig registerBeanMockerInterceptor(Class<T> clazz, BeanMockInte
return this;
}

/**
* 手动指定构造器方法
*
* @param constructorSupplier 构造器初始化方法
* @return mockConfig instance in chain invoke
*/
public MockConfig registerConstructorSupplier(Supplier<?> constructorSupplier) {
this.constructorSupplierMap.put(constructorSupplier.get().getClass(), constructorSupplier);

return this;
}

public Supplier getConstructorSupplier(final Class<?> target) {
return this.constructorSupplierMap.get(target);
}

/**
* 获取 BeanMocker 拦截器
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
* @author jitwxs@foxmail.com
Expand All @@ -32,16 +33,22 @@ public class ObjectUtils {
/**
* 根据 class 创建对象,智能调用构造方法
*
* @param target create object's class
* @param <T> create object's generic
* @param target create object's class
* @param constructorSupplier 构造器方法
* @param <T> create object's generic
* @return instance
*/
public static <T> T create(Class<T> target) {
public static <T> T create(Class<T> target, Supplier<T> constructorSupplier) {
try {
// 基于构造方法
// 基于默认无参构造方法
return delegate.create(target);
} catch (ReflectionException e) {
// 基于 builder 构造器
// 使用提供的构造器方法
if (constructorSupplier != null) {
return constructorSupplier.get();
}

// 使用 builder 构造器兜底
final Object builder = createBuilder(target, ClassGroupEnum.Group.NATIVE);
if (builder != null) {
return (T) buildBuilder(builder);
Expand All @@ -51,19 +58,6 @@ public static <T> T create(Class<T> target) {
throw new EasyDataException("failed create object, please try provide create function to resolve this exception");
}

/**
* 根据 class 创建对象,指定构造方法
*
* @param target create object's class
* @param <T> create object's generic
* @param constructorArgTypes 构造方法参数类型
* @param constructorArgs 构造方法参数
* @return instance
*/
public static <T> T create(Class<T> target, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return delegate.create(target, constructorArgTypes, constructorArgs);
}

/**
* 根据 class 创建 protobuf builder 对象
*
Expand Down Expand Up @@ -118,6 +112,7 @@ public static Object buildBuilder(Object builderBean) {
* 构造 proto 对象,并填充属性
*
* @param target proto 对象类型
* @param constructorSupplier 构造器方法
* @param fieldIgnoreGeneratorFunc 属性是否忽略判断
* @param newInstanceConsume 当对象构造完毕后,回调消费方法
* @param fieldGeneratorFunc 属性生成方法
Expand All @@ -129,10 +124,11 @@ public static Object buildBuilder(Object builderBean) {
* @throws Throwable 内部流程处理异常
*/
public static <T> T createJava(final Class<T> target,
final Supplier<T> constructorSupplier,
final ThrowableFunction<Field, Boolean> fieldIgnoreGeneratorFunc,
final Consumer<Object> newInstanceConsume,
final ThrowableBiFunction<String, Type, Object> fieldGeneratorFunc) throws Throwable {
final Object invoke = ObjectUtils.create(target);
final Object invoke = ObjectUtils.create(target, constructorSupplier);

if (newInstanceConsume != null) {
newInstanceConsume.accept(invoke);
Expand Down Expand Up @@ -204,7 +200,7 @@ public static <T> T createProtoMessage(final Class<T> target,
public static <T> T createProtoBuilder(final Class<T> target,
final Consumer<Object> newInstanceConsume,
final ThrowableBiFunction<String, Type, Object> fieldGeneratorFunc) throws Throwable {
final T invoke = ObjectUtils.create(target);
final T invoke = ObjectUtils.create(target, null);

if (invoke == null) {
return null;
Expand Down

0 comments on commit 8d3331a

Please sign in to comment.