com.gitee.l0km.codegen.base.NewSourceInfoAbstract Maven / Gradle / Ivy
package com.gitee.l0km.codegen.base;
import static com.gitee.l0km.com4j.basex.bean.jdk.BeanPropertySupportImpl.BEAN_SUPPORT;
import java.beans.PropertyDescriptor;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitee.l0km.codegen.base.Method.Parameter;
import com.gitee.l0km.com4j.base.Assert;
import com.gitee.l0km.com4j.base.BaseParameterNames;
import com.gitee.l0km.com4j.base.Judge;
import com.gitee.l0km.com4j.base.ParameterNames;
import com.gitee.l0km.com4j.basex.AnnotationProxy;
import com.gitee.l0km.com4j.basex.ReflectionUtils;
import com.gitee.l0km.com4j.basex.reflection.generics.EnhancedTypeResolver;
import com.gitee.l0km.javadocreader.JavadocParameterNames;
import com.gitee.l0km.javadocreader.JavadocReader;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* {@link NewSourceInfo}抽象实现
* @author guyadong
*
* @param
*/
public abstract class NewSourceInfoAbstract extends AbstractSchema implements NewSourceInfo {
private static final Logger logger = LoggerFactory.getLogger(NewSourceInfoAbstract.class);
protected final Class interfaceClass;
protected final Class extends T> refClass;
protected final List methodsNeedGenerated = new ArrayList();
protected final BaseParameterNames paramTable;
protected final Map properties;
/**
* 当前生成的类型的泛型变量与实际类型参数的映射,非泛型类为空
*/
protected final EnhancedTypeResolver typeResolver;
private final AnnotationHelper annotationHelper = new AnnotationHelper();
abstract protected void createMethodsNeedGenerated();
protected AnnotationHelper getAnnHelper() {
return annotationHelper;
}
@Override
protected void addImportedClassFromMethod(Method method, boolean importExceptions, boolean importReturn, boolean importAnnotation) {
addImportedClass(typeResolver.resolveTypes(method.getGenericParameterTypes()));
if(importExceptions) {
addImportedClass(typeResolver.resolveTypes(method.getGenericExceptionTypes()));
}
if(importReturn) {
addImportedClass(typeResolver.resolveType(method.getGenericReturnType()));
}
}
/**
* @param interfaceClass
* @param refClass
* 参考类
* @param baseClass
* 父类
*/
public NewSourceInfoAbstract(Class interfaceClass, Class extends T> refClass, Class extends T> baseClass) {
checkClass(interfaceClass,refClass,baseClass);
this.interfaceClass = interfaceClass;
this.baseClass = baseClass;
this.refClass = refClass;
initImportList();
try {
if(refClass != null){
paramTable = makeBaseParameterNames(refClass);
typeResolver = new EnhancedTypeResolver(ReflectionUtils.getNormalizedTypeVariables(refClass, true));
}else if(interfaceClass != null){
paramTable = makeBaseParameterNames(interfaceClass);
typeResolver = new EnhancedTypeResolver(Collections.emptyMap());
}else if(baseClass != null && baseClass.isEnum()){
// enum support 不需要paramTable
paramTable = null;
typeResolver = new EnhancedTypeResolver(Collections.emptyMap());
}else if(baseClass != null){
paramTable = makeBaseParameterNames(baseClass);
typeResolver = new EnhancedTypeResolver(ReflectionUtils.getNormalizedTypeVariables(baseClass, true));
}else{
throw new IllegalStateException("cann't construct paramTable instance caused by interfaceClass and refClass both are null");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
properties = readProperties();
}
@Override
protected void initImportList() {
if (null != baseClass){
addImportedClass(baseClass);
addImportedClass(baseClass.getTypeParameters());
}
else if(interfaceClass != null){
addImportedClass(interfaceClass);
addImportedClass(interfaceClass.getTypeParameters());
}
}
private static BaseParameterNames makeBaseParameterNames(Class> clazz) {
return (clazz.isInterface() || !Modifier.isAbstract(clazz.getModifiers())) && JavadocReader.existSourceOf(clazz)
? new JavadocParameterNames(clazz) : new ParameterNames(clazz);
}
/**
* 检查构造方法传入的参数,子类可以重写此方法
* @param interfaceClass
* @param refClass
* @param baseClass
*/
protected void checkClass(Class interfaceClass, Class extends T> refClass, Class extends T> baseClass){
Assert.notNull(interfaceClass, "interfaceClass");
Assert.notNull(refClass, "refClass");
if (!interfaceClass.isInterface()){
throw new IllegalArgumentException("interfaceClass must be Interface(必须是接口)");
}
if (!interfaceClass.isAssignableFrom(refClass)
|| refClass.isInterface()
|| Modifier.isAbstract(refClass.getModifiers())){
throw new IllegalArgumentException(String.format(
"refClass must implement [%s] and not be abstract class(必须实现接口,且不能是抽象类)",
interfaceClass.getName()));
}
if (null != baseClass && (!interfaceClass.isAssignableFrom(baseClass) || baseClass.isInterface())) {
throw new IllegalArgumentException(String.format("baseClass must implement [%s](必须实现接口)",
interfaceClass.getName()));
}
}
protected final void addImportedClassFromMethods() {
Iterator it = methodsNeedGenerated.iterator();
while (it.hasNext()) {
Method im = it.next();
addImportedClassFromMethod(im, true, true, true);
}
}
@Override
public Class getInterfaceClass() {
return interfaceClass;
}
@Override
public List getMethodsNeedGenerated() {
if (methodsNeedGenerated.isEmpty()){
createMethodsNeedGenerated();
}
return methodsNeedGenerated;
}
protected final static boolean isImplementedMethod(java.lang.reflect.Method im, java.lang.reflect.Method m) {
if (!Judge.hasNull(im, m)) {
if ((im.getDeclaringClass().isAssignableFrom(m.getDeclaringClass()) && im.getName().equals(m.getName()))) {
if (!im.getReturnType().equals(m.getReturnType()))
return false;
Class>[] params1 = im.getParameterTypes();
Class>[] params2 = m.getParameterTypes();
if (params1.length == params2.length) {
for (int i = 0; i < params1.length; i++) {
if (params1[i] != params2[i])
return false;
}
return true;
}
}
}
return false;
}
protected final static boolean isImplemented(java.lang.reflect.Method[] methods, java.lang.reflect.Method im) {
return getImplementedMethod(methods,im)!=null;
}
protected final static boolean isImplemented(Class> claz, java.lang.reflect.Method im) {
return getImplementedMethod(claz.getDeclaredMethods(),im)!=null;
}
protected final static java.lang.reflect.Method getImplementedMethod(java.lang.reflect.Method[] methods, java.lang.reflect.Method im) {
for (java.lang.reflect.Method m : methods) {
if (isImplementedMethod(im, m) && !Modifier.isAbstract(m.getModifiers())) {
logger.debug("IMPLEMENTED METHOD:{}", im);
return m;
}
}
return null;
}
/**
* @return refClass
*/
@Override
public Class extends T> getRefClass() {
return refClass;
}
@Override
public boolean compile() {
boolean compileOk = false;
try {
createMethodsNeedGenerated();
addImportedClassFromMethods();
compileOk = true;
} finally {
}
return compileOk;
}
private static final Method getMethod(java.lang.reflect.Method[] methods, String signature) {
Assert.notEmpty(signature, "signature");
for (java.lang.reflect.Method m : methods) {
if (Method.getSignature(m).equals(signature)){
ParameterNames pt = new ParameterNames(m.getDeclaringClass());
try {
return new Method(m,pt.getParameterNames(m.getName(), m.getParameterTypes()));
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
return null;
}
public final Method getMethod(Class> clazz, String signature) {
Assert.notNull(clazz, "methods");
return getMethod(clazz.getMethods(),signature);
}
public final Method getDeclaredMethods(Class> clazz, String signature) {
Assert.notNull(clazz, "methods");
return getMethod(clazz.getDeclaredMethods(),signature);
}
public final Method getMatchedGenericMethod(Class> clazz, Method method, Class> expectedType,
String[] genericParamNames, Class> targetType) throws MethodException {
return getMatchedGenericMethod(clazz, method, expectedType, genericParamNames, targetType,null);
}
public final Method getMatchedGenericMethod(Class> clazz, Method method, Class> expectedType,
String[] genericParamNames, Class> targetType,String name) throws MethodException {
Assert.notNull(clazz, "clzzz");
Assert.notNull(method, "method");
Assert.notNull(genericParamNames, "genericParamNames");
Assert.notNull(targetType, "targetType");
Assert.notNull(expectedType, "expectedType");
if(Judge.hasEmpty(genericParamNames))
throw new MethodException("the genericParamNames's element must not be empty");
Parameter[] params = method.getParameters();
Class>[] parameterTypes = new Class>[params.length];
for(int i=0;i nameSet;
if (null == (nameSet = CodeGenUtils.toSetIfnotDup(genericParamNames)))
throw new MethodException("genericParamNames has duplicated elements");
//代入期望类型
for (int i = 0; i < parameterTypes.length; i++) {
if (nameSet.contains(params[i].name)) {
if (params[i].type != targetType)
throw new MethodException(String.format(
"the %s's type that from genericParamNames is not targetType %s", params[i].name,
targetType.getName()));
parameterTypes[i]=expectedType;
}
}
try {
return new Method(getGenericMethod(clazz, name==null||name.isEmpty()?method.getName():name, parameterTypes), method.getParameterNames());
} catch (NoSuchMethodException e) {
throw new MethodException(String.format("not found matched generic method for %s",
method.getDocSignature()));
}
}
protected Map readProperties() {
return interfaceClass != null ? BEAN_SUPPORT.getProperties(this.interfaceClass, 0, true) : Collections.emptyMap();
}
/**
* @param excludePropertyMethod 是否排除属性的getter/setter方法,为{@code false}时效果同{@link #getMethodsNeedGenerated()}
* @return 需要生成的方法列表
* @see #getMethodsNeedGenerated()
*/
public List getMethodsNeedGenerated(final boolean excludePropertyMethod) {
Predicate p = new Predicate() {
@Override
public boolean apply(Method input) {
return excludePropertyMethod ? null == propertyDescriptorOf(input) : true;
}
};
Iterable filtered = Iterables.filter(getMethodsNeedGenerated(), p);
return Lists.newArrayList(filtered);
}
/**
* 返回所有getter/setter方法定义的属性
* @return 属性名--PropertyDescriptor 映射,没有返回空
*/
public Map getProperties() {
return properties;
}
public PropertyDescriptor propertyDescriptorOf(Method method) {
if(null != method){
for(PropertyDescriptor descriptor:properties.values()){
if(method.delegate().equals(descriptor.getReadMethod())){
return descriptor;
}
if(method.delegate().equals(descriptor.getWriteMethod())){
return descriptor;
}
}
}
return null;
}
public boolean isReadable(PropertyDescriptor propertyDescriptor) {
return propertyDescriptor != null && propertyDescriptor.getReadMethod() != null;
}
public boolean isWritable(PropertyDescriptor propertyDescriptor) {
return propertyDescriptor != null && propertyDescriptor.getWriteMethod() != null;
}
public boolean isIs(java.lang.reflect.Method getter) {
return (getter != null &&
getter.getName().startsWith("is") &&
(getter.getReturnType().equals(Boolean.TYPE) ||
getter.getReturnType().equals(Boolean.class)));
}
/**
* 返回参数实际的类型
* @param parameter
* @since 2.2.8
* @see EnhancedTypeResolver#resolveType(Type)
*/
public Type actualTypeOf(Parameter parameter) {
return typeResolver.resolveType(parameter.getGenericType());
}
/**
*
* @since 2.2.9
*/
public EnhancedTypeResolver getTypeResolver() {
return typeResolver;
}
/**
* @since 2.3.0
*/
public List> annotationOf(Method method) {
return getAnnHelper().annotationOf(method, "SUPERCLASS");
}
/**
* @since 2.3.0
*/
public List> annotationOf(Parameter parameter) {
return getAnnHelper().annotationOf(parameter);
}
/**
* @since 2.3.0
*/
public String annoationCodeOf(Parameter parameter, String delim) {
return getAnnHelper().annoationCodeOf(parameter, delim, fullNameInstanceByImportList);
}
/**
* @since 2.3.0
*/
public String annoationCodeOf(Method method, String delim) {
return getAnnHelper().annoationCodeOf(method,delim, "SUPERCLASS", fullNameInstanceByImportList);
}
/**
* @since 2.3.0
*/
public List> annotationOf(AnnotatedElement element) {
return getAnnHelper().annotationOf(element, "SUPERCLASS");
}
/**
* @since 2.3.0
*/
public String annoationCodeOf(AnnotatedElement element, String delim) {
return getAnnHelper().annoationCodeOf(element,delim, "SUPERCLASS", fullNameInstanceByImportList);
}
/**
* @since 2.3.0
*/
public boolean withAnnotation(Method method,String annotationType) {
return getAnnHelper().withAnnotation(method, annotationType, "SUPERCLASS");
}
/**
* @since 2.3.0
*/
public boolean withAnnotation(AnnotatedElement element,String annotationType) {
return getAnnHelper().withAnnotation(element, annotationType, "SUPERCLASS");
}
private static final Map, Class>> PRIMITIVE_TYPE_MAP = new HashMap, Class>>() {
private static final long serialVersionUID = 2638066380035384674L;
{
put(int.class, Integer.class);
put(boolean.class, Boolean.class);
put(byte.class, Byte.class);
put(short.class, Short.class);
put(char.class, Character.class);
put(long.class, Long.class);
put(float.class, Float.class);
put(double.class, Double.class);
}
};
/**
* 查找指定的方法
* @param clazz 要搜索的类
* @param name 方法名
* @param parameterTypes 希望匹配的参数类型数组
* @throws NoSuchMethodException
*/
public static final java.lang.reflect.Method getGenericMethod(Class>clazz,String name,Class>... parameterTypes) throws NoSuchMethodException{
List methods=new ArrayList();
//查找同名且参数数目相同的所有方法
for (java.lang.reflect.Method m : clazz.getMethods())
if (m.getName().equals(name) && m.getParameterTypes().length == parameterTypes.length)
methods.add(m);
if (!methods.isEmpty()) {
//过滤掉所有不能匹配的方法
for (int i = 0; i < parameterTypes.length; i++) {
for (Iterator it = methods.iterator(); it.hasNext();) {
if (!isConvert(it.next().getParameterTypes()[i], parameterTypes[i]))
it.remove();
}
if (methods.size() <= 1)
break;
}
if (methods.size() > 1) {
//如果还有多个方法满足条件,再过滤掉不能直接赋值的方法
for (int i = 0; i < parameterTypes.length; i++) {
for (Iterator it = methods.iterator(); it.hasNext();) {
if (!isAssignable(it.next().getParameterTypes()[i], parameterTypes[i]))
it.remove();
}
if (methods.size() <= 1)
break;
}
}
if (methods.size() == 1)
return methods.iterator().next();
else if (methods.size() > 1){
//如果还有多个方法满足条件,再过滤掉类型不相等的方法
for (int i = 0; i < parameterTypes.length; i++) {
for (Iterator it = methods.iterator(); it.hasNext();) {
if (it.next().getParameterTypes()[i]!= parameterTypes[i])
it.remove();
}
if (methods.size() <= 1)
break;
}
if (methods.size() == 1)
return methods.iterator().next();
else if (methods.size() > 1)
throw new IllegalStateException("found more matched method");
}
}
throw new NoSuchMethodException();
}
/**
* from对象能否则直接赋值给to
* @param to
* @param from
*/
public static final boolean isAssignable(Class> to,Class>from){
if (from.isPrimitive()) {
if (to != from && !to.isAssignableFrom(PRIMITIVE_TYPE_MAP.get(from)))
return false;
} else if (!to.isAssignableFrom(from))
return false;
return true;
}
/**
* from对象是否能转换成to
* @param to
* @param from
*/
public static final boolean isConvert(Class> to, Class> from) {
if (!isAssignable(to, from)){
if (to.isPrimitive() && PRIMITIVE_TYPE_MAP.get(to) == from) {
return true;
}
return false;
}
return true;
}
/**
* 判断 {@code refClass}是否实现了{@code interfaceClass}的所有方法
* @param interfaceClass
* @param refClass
*/
public static boolean isFullImplemented(Class>interfaceClass,Class> refClass){
if(null == interfaceClass || null == refClass){
return false;
}
if(!interfaceClass.isInterface()){
throw new IllegalArgumentException(String.format("the interface [%s] is not a interface",
interfaceClass.getName()));
}
if(refClass.isInterface() || !interfaceClass.isAssignableFrom(refClass)){
throw new IllegalArgumentException(String.format("refClass must implement [%s]",
refClass.getName()));
}
java.lang.reflect.Method[] interfaceMethods = interfaceClass.getMethods();
java.lang.reflect.Method[] refMethods = refClass.getMethods();
for(java.lang.reflect.Method im:interfaceMethods){
if(!isImplemented(refMethods,im)){
return false;
}
}
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy