package com.github.geequery.codegen.ast; import java.io.IOException; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import com.github.geequery.codegen.ast.IClass.GenericClass; import com.github.geequery.codegen.ast.IClass.RealClass; import com.github.geequery.codegen.ast.IClass.VirtualClass; import jef.common.log.LogUtil; import jef.tools.Assert; import jef.tools.StringUtils; import jef.tools.reflect.GenericUtils; import jef.tools.string.JefStringReader; public class IClassUtil { static final char[] SEP = new char[] { '<', ',' }; static final char[] CLOSE = new char[] { '>' }; public static IClass generic(String rawClz,String... paramTypes){ IClass raw=getIClass(rawClz); return generic(raw,paramTypes); } public static IClass generic(IClass raw,IClass... types){ if(types.length==0)return raw; return new GenericClass(raw, types); } public static IClass generic(String rawClz, IClass... types){ IClass raw=getIClass(rawClz); return generic(raw,types); } public static IClass generic(IClass raw, String... paramTypes){ List<IClass> types = new ArrayList<IClass>(); for(String s:paramTypes){ types.add(getIClass(s)); } return generic(raw,types.toArray(new IClass[types.size()])); } public static IClass getIClass(String name) { name=name.trim(); Assert.isNotEmpty(name); int n = name.indexOf('<'); if (n > -1) { String thisname=name.substring(0, n); if(name.endsWith("[]")){ name=name.substring(0,name.length()-2); thisname+="[]"; } IClass raw = getIClass(thisname); List<IClass> types = new ArrayList<IClass>(); String paramStr = name.substring(n + 1); paramStr = StringUtils.substringBeforeLast(paramStr, ">"); JefStringReader reader = new JefStringReader(paramStr); while (reader.nextChar() != -1) { try { StringBuilder sb = new StringBuilder(); sb.append(reader.readUntilCharIs(SEP)); if (reader.nextChar() == '<') { int left=1; sb.append((char)reader.read()); while(left>0){ int i=reader.read(); if(i==-1){ break; } char c=(char)i; if(c=='<'){ left++; }else if(c=='>'){ left--; } sb.append(c); } }else{ reader.read(); } String clz=StringUtils.trimToNull(sb.toString()); if(clz!=null){ types.add(getIClass(clz)); } } catch (IOException e) { LogUtil.exception(e); } } return new GenericClass(raw, types.toArray(new IClass[types.size()])); } else { return new VirtualClass(name); } } public static IClass getIClass(Type type) { type = GenericUtils.resolve(null, type); if (type instanceof Class) { return new RealClass((Class<?>) type); } else if (type instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType) type; IClass raw = new RealClass((Class<?>) pType.getRawType()); IClass[] params = new IClass[pType.getActualTypeArguments().length]; for (int n = 0; n < pType.getActualTypeArguments().length; n++) { params[n] = getIClass(pType.getActualTypeArguments()[n]); } return new GenericClass(raw, params); } else if (type instanceof GenericArrayType) { GenericArrayType array = (GenericArrayType) type; return new VirtualClass(array.getGenericComponentType().toString() + "[]"); } else { throw new UnsupportedOperationException(); } } /** * 对于AST框架的getRaw功能 * @param clz * @return */ public static IClass getRaw(IClass clz){ if(clz instanceof GenericClass){ return getRaw(((GenericClass)clz).getRawClass()); }else if(clz instanceof RealClass){ return clz; }else if(clz instanceof VirtualClass){ if(clz.getName().indexOf('<')<0)return clz; return IClassUtil.getIClass(StringUtils.substringBefore(clz.getName(), "<")); } throw new RuntimeException(); } /** * 为JavaUnit添加一个apache common log的对象 */ public static boolean addCommonsLog(JavaUnit unit){ JavaField field=unit.addField(Modifier.PROTECTED|Modifier.STATIC,"org.apache.commons.logging.Log","log"); if(field==null)return false; unit.addImport("org.apache.commons.logging.LogFactory"); field.setInitValue("LogFactory.getLog("+unit.getSimpleName()+".class)"); return true; } /** * 是否out * @param param * @return */ public static boolean isOut(JavaParameter param){ for(String s:param.getAnnotation()){ if("@Out".equals(s) || "@InOut".equals(s)){ return true; } } return false; } /** * 是否In * @param param * @return */ public static boolean isIn(JavaParameter param){ for(String s:param.getAnnotation()){ if("@In".equals(s) || "@InOut".equals(s)){ return true; } } return false; } public static String newInstance(JavaUnit unit,IClass clz,String... params){ unit.addImport(clz); StringBuilder sb=new StringBuilder("new ").append(clz.toSimpleString()); sb.append("("); for(int n=0;n<params.length;n++){ sb.append(params[n]); if(n<params.length-1)sb.append(','); } sb.append(")"); return sb.toString(); } public static String defaultValue(IClass clz){ if(!clz.isPrimitive())return "null"; String name=clz.getName(); if ("char".equals(name)) { return "(char)0"; } else if ("byte".equals(name)) { return "(byte)0"; } else if ("float".equals(name)) { return "0F"; } else if ("double".equals(name)) { return "(double)0"; } else if ("int".equals(name)) { return "0"; } else if ("short".equals(name)) { return "(short)0"; } else if ("long".equals(name)) { return "0L"; } else if("boolean".equals(name)){ return "false"; } return "null"; } }