All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gitee.l0km.codegen.base.AbstractSchema Maven / Gradle / Ivy

There is a newer version: 3.5.0
Show newest version
package com.gitee.l0km.codegen.base;

import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.gitee.l0km.aocache.annotations.AoWeakCacheable;
import com.gitee.l0km.codegen.base.Method.Parameter;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;

import net.gdface.utils.Assert;
import net.gdface.utils.TypeNameUtils;
import net.gdface.utils.TypeNameUtils.FullName;

public abstract class AbstractSchema {
	protected final Map> importedList = new HashMap>();
	protected Map> importedListBackup ;
	protected final FullNameByImporList fullNameInstanceByImportList;
	protected Class baseClass=null;
	protected AbstractSchema() {
		this.fullNameInstanceByImportList = new FullNameByImporList(importedList);
	}
	protected void initImportList() {
	}
	public Map> getImportedList() {
		return importedList;
	}
	/**
	 * @since 2.3.3
	 */
	public boolean imported(Type type) {
		return importedList.containsValue(type);
	}
	public void removeClassFromImports(Class clazz){
		if(null != clazz){
			importedList.remove(clazz.getSimpleName());
		}
	}
	public void removeClassFromImports(Class... array){
		if(null !=array){
			removeClassFromImports(Arrays.asList(array));
		}
	}
	public void removeClassFromImports(Collection> collection){
		if(null != collection){
			for(Class clazz:collection){
				removeClassFromImports(clazz);
			}
		}
	}
	@AoWeakCacheable
	private static final String getTypeName0(Type type, FullName fn) {
		Assert.notNull(type,"type");
		return TypeNameUtils.getTypeName(type,fn);
	}
	public final String getTypeDefine(Type type) {
		return getTypeName0(type,fullNameInstanceByImportList);
	}

	public final String getTypeName(Type type) {
		return getTypeName0(type,fullNameInstanceByImportList);
	}
	@AoWeakCacheable
	public final String getFullTypeName(Type type) {
		Assert.notNull(type,"type");
		return TypeNameUtils.getTypeName(type,true);
	}
	public final String getRawTypeName(Type type) {
		if(type instanceof ParameterizedType){
			ParameterizedType parameterizedType = (ParameterizedType)type;
			return getTypeName(parameterizedType.getRawType());
		}
		return getTypeName(type);
	}
	
	/**
	 * 将类型变量转为定义字符串,如 {@code T extends Serializable &  Comparable }
	 * @param input
	 * @param fullName 是否输出类的全名
	 */
	private final String defineTypeVariable(TypeVariable input,boolean fullName){
		StringBuffer buffer = new StringBuffer(input.getName());
		Type[] bounds = input.getBounds();
		if(!Object.class.equals(bounds[0])){
			buffer.append(" extends ");
			boolean first=true;
			for(Type type:bounds){
				if(!first){
					buffer.append(" & ");
				}
				first=true;
				if(fullName){
					buffer.append(getFullTypeName(type));
				}else{
					buffer.append(getTypeName(type));
				}
			}
		}
		return buffer.toString();
	
	}
	/**
	 * 将类或方法(实现{@link GenericDeclaration}的类)中的类型变量转为定义字符串,
	 * 如 {@code ,S> }
	 * @param genericDeclaration
	 * @param fullName 是否输出类的全名
	 * @return  {@code genericDeclaration}为{@code null}或无类型变量时返回空字符串
	 */
	public final String defineTypeVariables(GenericDeclaration genericDeclaration,final boolean fullName){
		if(null != genericDeclaration){
			TypeVariable[] typeparms = genericDeclaration.getTypeParameters();	
			if(typeparms.length > 0){
				List typeDefines = Lists.transform(Arrays.asList(typeparms), new Function,String>(){

					@Override
					public String apply(TypeVariable input) {
						return defineTypeVariable(input,fullName);
					}});
				return " <" + Joiner.on(",").join(typeDefines) + "> ";
			}
		}
		return "";
	}
	/**
	 * @see #defineTypeVariables(GenericDeclaration, boolean)
	 */
	public final String defineTypeVariables(Method method,boolean fullName){
		return null == method ? "" : defineTypeVariables(method.delegate(),fullName);
	}

	/**
	 * 将方法中的参数列表转为定义字符串
	 * @param params
	 * @param isVarArgs 最后的参数是否为变长参数
	 * @param fullName 是否输出类的全名
	 * @return  {@code genericDeclaration}为{@code null}或无类型变量时返回空字符串
	 */
	private final List paramsDefine(Type[] params, boolean isVarArgs,boolean fullName){
		List types = Lists.newLinkedList();
		if(null != params){
            for (int j = 0; j < params.length; j++) {
                String param = fullName ? getFullTypeName(params[j]) : getTypeName(params[j]);
                if (isVarArgs && (j == params.length - 1)) {
                    param = param.replaceFirst("\\[\\]$", "...");// replace T[] with T...
                }
                types.add(param);
            }
		}
		return types;
	}
	/**
	 * 将方法中的参数类型列表转为定义字符串
	 * @param method
	 * @param fullName 是否输出类的全名
	 * @return  {@code genericDeclaration}为{@code null}或无类型变量时返回空字符串
	 */
	private final List paramTypeNames(java.lang.reflect.Member input, boolean fullName){
		if(input instanceof java.lang.reflect.Method){
			java.lang.reflect.Method member = (java.lang.reflect.Method)input;
			return paramsDefine(member.getGenericParameterTypes(),member.isVarArgs(),fullName);
		}
		if(input instanceof java.lang.reflect.Constructor){
			java.lang.reflect.Constructor member = (java.lang.reflect.Constructor)input;
			return paramsDefine(member.getGenericParameterTypes(),member.isVarArgs(),fullName);
		}
		return Collections.emptyList();
	}
	/**
	 * 将方法中的参数类型列表转为参数定义字符串(参数类型 参数名),支持变长参数正确输出
	 * @param method
	 * @param fullName 是否输出类的全名
	 * @return  {@code genericDeclaration}为{@code null}或无类型变量时返回空字符串
	 */
	public final String paramsDefine(Method method, boolean fullName){
		if(null == method){
			return "";
		}
		List types = paramTypeNames(method.delegate(),fullName);
		Parameter[] names = method.getParameters();
		StringBuilder sb = new StringBuilder();
		for(int i=0; i 0){
				sb.append(",");
			}
			sb.append(types.get(i) + " "  + names[i].name);
		}
		return sb.toString();
	}
	
	public final void addImportedClass(Type... types) {
		CodeGenUtils.addImportedTypes(importedList, types);
	}
	public final void addImportedClass(Iterable types) {
		CodeGenUtils.addImportedTypes(importedList, types);
	}
	protected final void addImportedClass(String... types) throws ClassNotFoundException {
		CodeGenUtils.addImportedTypes(importedList, types);
	}

	/**
	 * {@link #importedList}中的类名排序输出
	 */
	public final String[] getImportedClassNames(){		
		return getImportedClassNames(null).toArray( new String[0]);		
	}
	/**
	 * {@link #importedList}中的类名排序输出
	 * @param omitPkg 忽略的包名,属于该package下的类不输出
	 */
	public final List getImportedClassNames(String omitPkg){
		return getImportedClassNames(omitPkg,Predicates.alwaysTrue());
	}
	/**
	 * {@link #importedList}中的类名排序输出
	 * @param omitPkg 忽略的包名,属于该package下的类不输出
	 */
	private final List getImportedClassNames(String omitPkg,Predicate>filter){
		return FluentIterable.from(CodeGenUtils.sortClass(this.importedList.values()))
			.filter(filter)
			.filter(clazz->!clazz.getPackage().getName().equals(omitPkg))
			.transform(clazz->clazz.getName().replace('$', '.')).toList();
	}
	public Class getBaseClass() {
		return baseClass;
	}
	public abstract boolean compile();

	protected void addImportedClassFromMethod(Method method, boolean importExceptions, boolean importReturn, boolean importAnnotation) {
		addImportedClass(method.getGenericParameterTypes());
		if(importExceptions) {
			addImportedClass(method.getGenericExceptionTypes());
		}
		if(importReturn) {
			addImportedClass(method.getGenericReturnType());
		}
	}

	protected final void addImportedClassFromMethods(Collection methodsNeedGenerated, 
			boolean importExceptions, boolean importReturn, boolean importAnnotation) {
		Iterator it = methodsNeedGenerated.iterator();
		while (it.hasNext()) {
			Method im = it.next();
			addImportedClassFromMethod(im, importExceptions, importReturn, importAnnotation);
		}
	}
	/**
	 * 备份{@link #importedList},必须与{@link #restoreImportedList()}配对使用
	 */
	public void backupImportedList(){
		this.importedListBackup = new HashMap>(this.importedList);
	}
	/**
	 * 恢复{@link #importedList},必须与{@link #backupImportedList()}配对使用
	 */
	public void restoreImportedList(){
		importedList.clear();
		if(null == importedListBackup){
			throw new NullPointerException("importedListBackup is null,must call backupImportedList firstly");
		}
		importedList.putAll(importedListBackup);
	}

	/**
	 * 根据指定的方法列表重新生成imported list
	 * @param methods
	 */
	public void rebuildImportedList(List methods){
		rebuildImportedList(methods,true,true, true);
	}
	/**
	 * 根据指定的方法列表重新生成imported list
	 * @param methods
	 * @param importExceptions 是否导入异常类型
	 * @param importReturn 是否导入返回类型
	 * @param importAnnotation 是否导入注解类型
	 * @since 2.3.0
	 */
	public void rebuildImportedList(List methods,
			boolean importExceptions, boolean importReturn, boolean importAnnotation){
		if(methods != null){
			//compile();
			importedList.clear();
			initImportList();
			addImportedClassFromMethods(methods, importExceptions, importReturn, importAnnotation);
		}
	}
	public String getName() {
		return baseClass.getName();
	}
	public String getPackage(){
		return baseClass.getPackage().getName();
	}
	public void setOutPackage(String pkg) {
		fullNameInstanceByImportList.setPkg(pkg);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy