com.gitee.l0km.codegen.base.AbstractSchema Maven / Gradle / Ivy
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.gitee.l0km.com4j.base.Assert;
import com.gitee.l0km.com4j.basex.TypeNameUtils;
import com.gitee.l0km.com4j.basex.TypeNameUtils.FullName;
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;
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