package com.github.geequery.codegen.ast; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import jef.tools.Assert; import jef.tools.StringUtils; import jef.tools.reflect.GenericUtils; import org.apache.commons.lang.ArrayUtils; public interface IClass { static final String[] PRIMITIVE_TYPES= {"int","short","long","float","double","boolean","char","byte"}; static final String[] WRAPPED_TYPES= {"Integer","Short","Long","Float","Double","Boolean","Character","Byte"}; //得到类名 String getName(); //得到简称 String getSimpleName(); //是否数组 boolean isArray(); //是否原生 boolean isPrimitive(); //得到数组的元素类型 IClass getComponentType(); String toSimpleString(); Type toJavaType()throws ClassNotFoundException; public static class GenericClass implements IClass { IClass raw; List<IClass> paramTypes; GenericClass(String k, String... vs) { this.raw = new VirtualClass(k); paramTypes = new ArrayList<IClass>(); for (String v : vs) { paramTypes.add(new VirtualClass(v)); } } GenericClass(IClass k, IClass... vs) { this.raw = k; paramTypes = new ArrayList<IClass>(); paramTypes.addAll(Arrays.asList(vs)); } public void addGenericParamType(IClass type) { paramTypes.add(type); } public String getName() { return raw.getName(); } public String getSimpleName() { return raw.getSimpleName(); } public boolean isArray() { return raw.isArray(); } public IClass getComponentType() { return raw.getComponentType(); } public IClass getRawClass() { return raw; } public List<IClass> getParamTypes() { return paramTypes; } public boolean isPrimitive() { return raw.isPrimitive(); } @Override public String toString() { StringBuilder sb=new StringBuilder(); if(raw.isArray()){ sb.append(raw.getComponentType().toString()); }else{ sb.append(raw.toString()); } if(paramTypes!=null && !paramTypes.isEmpty()){ sb.append('<'); int n=0; for(IClass c:paramTypes){ if(n>0)sb.append(','); sb.append(c.toString()); n++; } sb.append('>'); } if(raw.isArray()){ sb.append("[]"); } return sb.toString(); } public String toSimpleString() { StringBuilder sb=new StringBuilder(); if(raw.isArray()){ sb.append(raw.getComponentType().toSimpleString()); }else{ sb.append(raw.toSimpleString()); } if(paramTypes!=null && !paramTypes.isEmpty()){ sb.append('<'); int n=0; for(IClass c:paramTypes){ if(n>0)sb.append(','); sb.append(c.toSimpleString()); n++; } sb.append('>'); } if(raw.isArray()){ sb.append("[]"); } return sb.toString(); } public Type toJavaType() throws ClassNotFoundException{ Class<?> rawType=(Class<?>)raw.toJavaType(); Type[] types=new Type[this.paramTypes.size()]; for(int i=0;i<paramTypes.size();i++){ types[i]=paramTypes.get(i).toJavaType(); } return GenericUtils.newGenericType(rawType, types); } } public static class VirtualClass implements IClass { private String name; VirtualClass(String c) { Assert.isNotEmpty(c); this.name = c; } public String getName() { return name; } public boolean isArray() { if (name.endsWith("[]")) return true; if (name.startsWith("[")) return true; return false; } public IClass getComponentType() { if (name.endsWith("[]")) { return new VirtualClass(StringUtils.substringBeforeLast(name, "[")); } else if ("[I".equals(name)) { return new RealClass(new int[0].getClass()); } else if ("[B".equals(name)) { return new RealClass(new byte[0].getClass()); } else if ("[Z".equals(name)) { return new RealClass(new boolean[0].getClass()); } else if ("[C".equals(name)) { return new RealClass(new char[0].getClass()); } else if ("[D".equals(name)) { return new RealClass(new double[0].getClass()); } else if ("[F".equals(name)) { return new RealClass(new float[0].getClass()); } else if ("[J".equals(name)) { return new RealClass(new long[0].getClass()); } else if ("[S".equals(name)) { return new RealClass(new short[0].getClass()); } else if (name.startsWith("[L")) { return new VirtualClass(StringUtils.substringBetween(name, "[L", ";")); } else { return null; } } public String getSimpleName() { String n = name; if (name.indexOf('<') > -1) { n = StringUtils.substringBefore(name, "<"); } if (n.indexOf('.') > -1) return StringUtils.substringAfterLast(n, "."); return n; } @Override public int hashCode() { return getName().hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof IClass) { return getName().equals(((IClass) obj).getName()); } else if (obj instanceof String) { return getName().equals((String) obj); } return false; } public boolean isPrimitive() { return ArrayUtils.contains(PRIMITIVE_TYPES, name); } @Override public String toString() { return name; } public String toSimpleString() { return getSimpleName(); } public Type toJavaType() throws ClassNotFoundException { if(this.isArray()){ return GenericUtils.newArrayClass(this.getComponentType().toJavaType()); }else{ return Class.forName(name); } } } public static class RealClass implements IClass { RealClass(Class<?> c) { this.cls = c; } private Class<?> cls; public String getName() { return cls.getName().replace('$', '.'); } public boolean isArray() { return cls.isArray(); } public IClass getComponentType() { return new RealClass(cls.getComponentType()); } public String getSimpleName() { return cls.getSimpleName(); } @Override public int hashCode() { return getName().hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof IClass) { return getName().equals(((IClass) obj).getName()); } else if (obj instanceof String) { return getName().equals((String) obj); } return false; } public boolean isPrimitive() { return cls.isPrimitive(); } @Override public String toString() { return cls.getName(); } public Class<?> getCls() { return cls; } public String toSimpleString() { return getSimpleName(); } public Type toJavaType() throws ClassNotFoundException { return cls; } } }