Enhance InputConverter

pull/146/head
johnniang 2019-04-25 19:58:08 +08:00
parent 60d56dc99d
commit 388a37adfe
4 changed files with 143 additions and 10 deletions

View File

@ -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<DOMAIN> {
@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<DOMAIN> {
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());
}
}

View File

@ -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<COMMENT> implements InputConverter<COMMENT> {
@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());
}
}

View File

@ -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());
}
}

View File

@ -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<JournalCommentParam> 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());
}
}