From 388a37adfe6688f9c74d14af0e4c6cd759c31487 Mon Sep 17 00:00:00 2001 From: johnniang Date: Thu, 25 Apr 2019 19:58:08 +0800 Subject: [PATCH] Enhance InputConverter --- .../app/model/dto/base/InputConverter.java | 17 ++++-- .../app/model/params/BaseCommentParam.java | 48 +++++++++++++++ .../run/halo/app/utils/ReflectionUtils.java | 28 +++++++-- .../halo/app/utils/ReflectionUtilsTest.java | 60 +++++++++++++++++++ 4 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 src/main/java/run/halo/app/model/params/BaseCommentParam.java create mode 100644 src/test/java/run/halo/app/utils/ReflectionUtilsTest.java diff --git a/src/main/java/run/halo/app/model/dto/base/InputConverter.java b/src/main/java/run/halo/app/model/dto/base/InputConverter.java index 64dc3003c..92185f952 100644 --- a/src/main/java/run/halo/app/model/dto/base/InputConverter.java +++ b/src/main/java/run/halo/app/model/dto/base/InputConverter.java @@ -1,15 +1,12 @@ package run.halo.app.model.dto.base; -import run.halo.app.utils.ReflectionUtils; +import org.springframework.lang.Nullable; import run.halo.app.utils.BeanUtils; import run.halo.app.utils.ReflectionUtils; import java.lang.reflect.ParameterizedType; import java.util.Objects; -import static run.halo.app.utils.BeanUtils.transformFrom; -import static run.halo.app.utils.BeanUtils.updateProperties; - /** * Converter interface for input DTO. * @@ -25,7 +22,7 @@ public interface InputConverter { @SuppressWarnings("unchecked") default DOMAIN convertTo() { // Get parameterized type - ParameterizedType currentType = ReflectionUtils.getParameterizedType(InputConverter.class, this.getClass()); + ParameterizedType currentType = getParameterizedType(); // Assert not equal Objects.requireNonNull(currentType, "Cannot fetch actual type because parameterized type is null"); @@ -43,5 +40,15 @@ public interface InputConverter { default void update(DOMAIN domain) { BeanUtils.updateProperties(this, domain); } + + /** + * Get parameterized type. + * + * @return parameterized type or null + */ + @Nullable + default ParameterizedType getParameterizedType() { + return ReflectionUtils.getParameterizedType(InputConverter.class, this.getClass()); + } } diff --git a/src/main/java/run/halo/app/model/params/BaseCommentParam.java b/src/main/java/run/halo/app/model/params/BaseCommentParam.java new file mode 100644 index 000000000..8add9165a --- /dev/null +++ b/src/main/java/run/halo/app/model/params/BaseCommentParam.java @@ -0,0 +1,48 @@ +package run.halo.app.model.params; + +import lombok.Data; +import run.halo.app.model.dto.base.InputConverter; +import run.halo.app.utils.ReflectionUtils; + +import javax.validation.constraints.Email; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.lang.reflect.ParameterizedType; + +/** + * Base Comment param. + * + * @author johnniang + * @date 3/22/19 + */ +@Data +public abstract class BaseCommentParam implements InputConverter { + + @NotBlank(message = "Comment author name must not be blank") + @Size(max = 50, message = "Length of comment author name must not be more than {max}") + private String author; + + @NotBlank(message = "Comment email must not be blank") + @Email(message = "Comment email's format is incorrect") + @Size(max = 255, message = "Length of comment email must not be more than {max}") + private String email; + + @Size(max = 127, message = "Length of comment author url must not be more than {max}") + private String authorUrl; + + @NotBlank(message = "Comment content must not be blank") + @Size(max = 1023, message = "Length of comment content must not be more than {max}") + private String content; + + @Min(value = 1, message = "Post id must not be less than {value}") + private Integer postId; + + @Min(value = 0, message = "Comment parent id must not be less than {value}") + private Long parentId = 0L; + + @Override + public ParameterizedType getParameterizedType() { + return ReflectionUtils.getParameterizedTypeBySuperClass(BaseCommentParam.class, this.getClass()); + } +} diff --git a/src/main/java/run/halo/app/utils/ReflectionUtils.java b/src/main/java/run/halo/app/utils/ReflectionUtils.java index 599275e1a..c24449754 100644 --- a/src/main/java/run/halo/app/utils/ReflectionUtils.java +++ b/src/main/java/run/halo/app/utils/ReflectionUtils.java @@ -20,20 +20,20 @@ public class ReflectionUtils { /** * Gets parameterized type. * - * @param interfaceType interface type must not be null - * @param genericTypes generic type array + * @param superType super type must not be null (super class or super interface) + * @param genericTypes generic type array * @return parameterized type of the interface or null if it is mismatch */ @Nullable - public static ParameterizedType getParameterizedType(@NonNull Class interfaceType, Type... genericTypes) { - Assert.notNull(interfaceType, "Interface type must not be null"); + public static ParameterizedType getParameterizedType(@NonNull Class superType, Type... genericTypes) { + Assert.notNull(superType, "Interface or super type must not be null"); ParameterizedType currentType = null; for (Type genericType : genericTypes) { if (genericType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) genericType; - if (parameterizedType.getRawType().getTypeName().equals(interfaceType.getTypeName())) { + if (parameterizedType.getRawType().getTypeName().equals(superType.getTypeName())) { currentType = parameterizedType; break; } @@ -53,6 +53,7 @@ public class ReflectionUtils { @Nullable public static ParameterizedType getParameterizedType(@NonNull Class interfaceType, Class implementationClass) { Assert.notNull(interfaceType, "Interface type must not be null"); + Assert.isTrue(interfaceType.isInterface(), "The give type must be an interface"); if (implementationClass == null) { // If the super class is Object parent then return null @@ -71,4 +72,21 @@ public class ReflectionUtils { return getParameterizedType(interfaceType, superclass); } + + /** + * Gets parameterized type by super class. + * + * @param superClassType super class type must not be null + * @param extensionClass extension class + * @return parameterized type or null + */ + @Nullable + public static ParameterizedType getParameterizedTypeBySuperClass(@NonNull Class superClassType, Class extensionClass) { + + if (extensionClass == null) { + return null; + } + + return getParameterizedType(superClassType, extensionClass.getGenericSuperclass()); + } } diff --git a/src/test/java/run/halo/app/utils/ReflectionUtilsTest.java b/src/test/java/run/halo/app/utils/ReflectionUtilsTest.java new file mode 100644 index 000000000..c0da6be2d --- /dev/null +++ b/src/test/java/run/halo/app/utils/ReflectionUtilsTest.java @@ -0,0 +1,60 @@ +package run.halo.app.utils; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import run.halo.app.model.dto.base.InputConverter; +import run.halo.app.model.params.BaseCommentParam; +import run.halo.app.model.params.JournalCommentParam; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +/** + * Reflection utils test. + * + * @author johnniang + * @date 19-4-25 + */ +@Slf4j +public class ReflectionUtilsTest { + + @Test + public void getBaseCommentParamParameterizedTypeTest() { + Class paramClass = JournalCommentParam.class; + + log.debug(paramClass.getTypeName()); + log.debug(paramClass.getSuperclass().getTypeName()); + Type genericSuperclass = paramClass.getGenericSuperclass(); + log.debug(genericSuperclass.getTypeName()); + for (Type genericInterface : paramClass.getGenericInterfaces()) { + log.debug(genericInterface.getTypeName()); + log.debug(genericInterface.getClass().toString()); + } + + Type[] genericInterfaces = paramClass.getSuperclass().getGenericInterfaces(); + for (Type genericInterface : genericInterfaces) { + log.debug(genericInterface.getTypeName()); + log.debug(genericInterface.getClass().toString()); + } + + ParameterizedType parameterizedType = ReflectionUtils.getParameterizedTypeBySuperClass(BaseCommentParam.class, paramClass); + + log.debug(parameterizedType.getTypeName()); + for (Type type : parameterizedType.getActualTypeArguments()) { + log.debug(type.getTypeName()); + } + + +// ParameterizedType parameterizedType = ReflectionUtils.getParameterizedType(InputConverter.class, paramClass); +// +// log.debug(parameterizedType.toString()); +// +// log.debug(parameterizedType.getActualTypeArguments()[0].toString()); +// +// parameterizedType = ReflectionUtils.getParameterizedType(BaseCommentParam.class, paramClass); +// +// log.debug(parameterizedType.toString()); +// +// log.debug(parameterizedType.getActualTypeArguments()[0].toString()); + } +} \ No newline at end of file