package cn.org.rapid_framework.generator.provider.java.model; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import cn.org.rapid_framework.generator.provider.java.model.JavaMethod.FieldMethodInvocation; import cn.org.rapid_framework.generator.util.IOHelper; import cn.org.rapid_framework.generator.util.StringHelper; import cn.org.rapid_framework.generator.util.typemapping.ActionScriptDataTypesUtils; import cn.org.rapid_framework.generator.util.typemapping.JavaImport; import cn.org.rapid_framework.generator.util.typemapping.JavaPrimitiveTypeMapping; public class JavaClass { private Class clazz; public JavaClass(Class clazz) { this.clazz = clazz; } public String getClassName() { return getClassName(getSimpleJavaType()); } static String getClassName(String simpleJavaType) { return simpleJavaType.indexOf('$') >= 0 ? simpleJavaType.substring(simpleJavaType.indexOf('$')+1) : simpleJavaType; } public String getPackageName() { return clazz.getPackage().getName(); } public String getLastPackageName() { return StringHelper.getExtension(getPackageName()); } public String getLastPackageNameFirstUpper() { return getLastPackageName() == null ? "" : StringHelper.capitalize(getLastPackageName()); } public boolean isHasDefaultConstructor() { if(clazz.isInterface() || clazz.isAnnotation() || clazz.isEnum() || Modifier.isAbstract(clazz.getModifiers())) return false; for(Constructor c : clazz.getConstructors()) { if(Modifier.isPublic(c.getModifiers())) { if(c.getParameterTypes().length == 0) { return true; } } } return false; } public Set<JavaClass> getImportClasses() { Set<JavaClass> set = new LinkedHashSet<JavaClass>(); for(Method m :clazz.getMethods()) { Class[] clazzes = { m.getReturnType() }; JavaImport.addImportClass(set,clazzes); JavaImport.addImportClass(set,m.getParameterTypes()); JavaImport.addImportClass(set,m.getExceptionTypes()); } if(clazz.isMemberClass()) { Class[] clazzes = { clazz }; JavaImport.addImportClass(set,clazzes); } for(Field f :clazz.getFields()) { Class[] clazzes = { f.getType() }; JavaImport.addImportClass(set,clazzes); } for(Field f :clazz.getDeclaredFields()) { Class[] clazzes = { f.getType() }; JavaImport.addImportClass(set,clazzes); } for(Constructor c : clazz.getDeclaredConstructors()) { JavaImport.addImportClass(set,c.getExceptionTypes()); JavaImport.addImportClass(set,c.getParameterTypes()); } for(Constructor c : clazz.getConstructors()) { JavaImport.addImportClass(set,c.getExceptionTypes()); JavaImport.addImportClass(set,c.getParameterTypes()); } for(Class c : clazz.getDeclaredClasses()) { JavaImport.addImportClass(set,c); } return set; } public Set<JavaClass> getPropertiesImportClasses() throws Exception { Set<JavaClass> set = getImportClasses(); for(JavaProperty prop : getProperties()) { set.addAll(prop.getPropertyType().getImportClasses()); } return set; } public String getSuperclassName() { return clazz.getSuperclass() != null ? clazz.getSuperclass().getName() : null; } public JavaMethod[] getMethods() { return toJavaMethods(clazz.getDeclaredMethods()); } public JavaMethod getMethod(String methodName) { for(Method m : clazz.getMethods()) { if(m.getName().equals(methodName)) { return new JavaMethod(m,this); //FIXME javaClazz关联错误,现在会覆盖父类的引用. } } return null; } public JavaMethod[] getPublicMethods() { Method[] methods = clazz.getDeclaredMethods(); return toJavaMethods(filterByModifiers(methods,Modifier.PUBLIC)); } public JavaMethod[] getPublicStaticMethods() { Method[] methods = clazz.getDeclaredMethods(); return toJavaMethods(filterByModifiers(methods,Modifier.PUBLIC,Modifier.STATIC)); } public JavaMethod[] getPublicNotStaticMethods() { Method[] staticMethods = filterByModifiers(clazz.getDeclaredMethods(),Modifier.STATIC); Method[] publicMethods = filterByModifiers(clazz.getDeclaredMethods(),Modifier.PUBLIC); Method[] filtered = exclude(publicMethods,staticMethods).toArray(new Method[0]); return toJavaMethods(filtered); } public JavaProperty[] getReadProperties() throws Exception { List result = new ArrayList(); for(JavaProperty p : getProperties()) { if(p.isHasReadMethod()) { result.add(p); } } return (JavaProperty[])result.toArray(new JavaProperty[0]); } public JavaProperty[] getWriteProperties() throws Exception { List result = new ArrayList(); for(JavaProperty p : getProperties()) { if(p.isHasWriteMethod()) { result.add(p); } } return (JavaProperty[])result.toArray(new JavaProperty[0]); } public JavaProperty[] getProperties() throws Exception { List<JavaProperty> result = new ArrayList<JavaProperty>(); BeanInfo beanInfo = Introspector.getBeanInfo(clazz); PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); for(PropertyDescriptor pd : pds) { if(!"class".equalsIgnoreCase(pd.getName())) { result.add(new JavaProperty(pd,this)); } } return (JavaProperty[])result.toArray(new JavaProperty[0]); } public List<JavaField> getFields() { Field[] fields = clazz.getDeclaredFields(); List result = new ArrayList(); for(Field f : fields) { result.add(new JavaField(f,this)); } return result; } /** * 得到当前类包名称对应的文件路径,如 com.company.project包,将返回 com/company/project * */ public String getPackagePath(){ return getPackageName().replace(".", "/"); } /** * 得到当前类父一级的包名称如 com.company.project包,将返回com.company * */ public String getParentPackageName() { return getPackageName().substring(0,getPackageName().lastIndexOf(".")); } /** * 得到当前类父一级的包名称对应的文件路径,如 com.company.project包,将返回com/company * */ public String getParentPackagePath() { return getParentPackageName().replace(".", "/"); } /** * 得到当前类是从那里装载的绝对路径 * */ public String getClassFile() { return clazz.getClassLoader().getResource(clazz.getName().replace('.', '/')+".class").getFile(); } /** * 得到当前类对应的java源文件名称 * */ public String getJavaSourceFile() { return clazz.getName().replace('.', '/')+".java"; } /** * 得到 当前类对应的测试代码的文件路径 * @return */ public String getMavenJavaTestSourceFile() { return MavenHelper.getMavenJavaTestSourceFile(getClassFile()); } /** * 得到 当前类对应的源代码的文件路径 * @return */ public String getMavenJavaSourceFile() { return MavenHelper.getMavenJavaSourceFile(getClassFile()); } /** * 得到 当前类的源代码内容 * @return */ private String mavenJavaSourceFileContent; public String getMavenJavaSourceFileContent() { if(mavenJavaSourceFileContent == null){ if(getMavenJavaSourceFile() != null) { File file = new File(getMavenJavaSourceFile()); if(file.exists()) { mavenJavaSourceFileContent = IOHelper.readFile(file); } //TODO 增加读取 maven app-sources.jar只的源代码文件地址. } } return mavenJavaSourceFileContent; } public static class MavenHelper { public static String getMavenJavaTestSourceFile(String clazzFile) { if(clazzFile == null) return null; clazzFile = clazzFile.replace('\\', '/'); clazzFile = clazzFile.replaceAll("\\w+\\$", ""); // for inner class User$1.class and User$Info.class if(clazzFile.indexOf("target/classes") >= 0) { String result = StringHelper.replace(clazzFile, "target/classes", "src/test/java"); return StringHelper.replace(result, ".class", "Test.java"); } else if (clazzFile.indexOf("target/test-classes") >= 0){ String result = StringHelper.replace(clazzFile, "target/test-classes", "src/test/java"); return StringHelper.replace(result, ".class", "Test.java"); }else { return null; } } public static String getMavenJavaSourceFile(String clazzFile) { if(clazzFile == null) return null; clazzFile = clazzFile.replace('\\', '/'); clazzFile = clazzFile.replaceAll("\\$\\w+", ""); // for inner class User$1.class and User$Info.class if(clazzFile.indexOf("target/classes") >= 0) { String result = StringHelper.replace(clazzFile, "target/classes", "src/main/java"); return StringHelper.replace(result, ".class", ".java"); } else if (clazzFile.indexOf("target/test-classes") >= 0){ String result = StringHelper.replace(clazzFile, "target/test-classes", "src/test/java"); return StringHelper.replace(result, ".class", ".java"); } else { return null; } } } /** * 得到class是在那个classpath路径装载 * @return */ public String getLoadedClasspath() { return getClassFile().substring(0,getClassFile().length() - (clazz.getName()+".class").length()); } public String getAsType() { return ActionScriptDataTypesUtils.getPreferredAsType(getJavaType()); } public String getJavaType() { if(isArray()) { return clazz.getComponentType().getName().replace("$", "."); }else { return clazz.getName().replace("$", "."); } } public String getPrimitiveJavaType() { return JavaPrimitiveTypeMapping.getPrimitiveType(getJavaType()); } public String getSimpleJavaType() { if(isArray()) { return clazz.getComponentType().getSimpleName(); }else { return clazz.getSimpleName(); } } public String getNullValue () { return JavaPrimitiveTypeMapping.getDefaultValue(getJavaType()); } public String getCanonicalName() { return clazz.getCanonicalName(); } public JavaField getField(String name) throws NoSuchFieldException,SecurityException { return new JavaField(clazz.getDeclaredField(name),this); } public JavaClass getSuperclass() { return new JavaClass(clazz.getSuperclass()); } public boolean isAnnotation() { return clazz.isAnnotation(); } public boolean isAnonymousClass() { return clazz.isAnonymousClass(); } public boolean isArray() { return clazz.isArray(); } public boolean isBooleanType() { return "boolean".equals(clazz.getName()) || "Boolean".equals(clazz.getSimpleName()); } public boolean isEnum() { return clazz.isEnum(); } public boolean isInstance(Object obj) { return clazz.isInstance(obj); } public boolean isInterface() { return clazz.isInterface(); } public boolean isLocalClass() { return clazz.isLocalClass(); } public boolean isMemberClass() { return clazz.isMemberClass(); } public boolean isPrimitive() { return clazz.isPrimitive(); } public boolean isSynthetic() { return clazz.isSynthetic(); } public Class getClazz() { return clazz; } public Set<FieldMethodInvocation> getFieldMethodInvocationSequences() { Set<FieldMethodInvocation> set = new LinkedHashSet<FieldMethodInvocation>(); for(JavaMethod m : getMethods()) { set.addAll(m.getFieldMethodInvocationSequences()); } return set; } private Method[] filterByModifiers(Method[] methods,int... filteredModifiers) { List<Method> filtered = new ArrayList<Method>(); for(int i = 0; i < methods.length; i++) { for(int j = 0; j < filteredModifiers.length; j++) { if((filteredModifiers[j] & methods[i].getModifiers()) != 0) { filtered.add(methods[i]); } } } return filtered.toArray(new Method[0]); } private JavaMethod[] toJavaMethods(Method[] declaredMethods) { JavaMethod[] methods = new JavaMethod[declaredMethods.length]; for(int i = 0; i < declaredMethods.length; i++) { methods[i] = new JavaMethod(declaredMethods[i],this); } return methods; } private <T> List<T> exclude(T[] methods, T[] excludeMethods) { List<T> result = new ArrayList<T>(); outerLoop: for(int i = 0; i < methods.length; i++) { for(int j = 0;j < excludeMethods.length; j++) { if(methods[i].equals(excludeMethods[j])) { break outerLoop; } } result.add(methods[i]); } return result; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((clazz == null) ? 0 : clazz.hashCode()); return result; } public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; JavaClass other = (JavaClass) obj; if (clazz == null) { if (other.clazz != null) return false; } else if (!clazz.equals(other.clazz)) return false; return true; } public String toString() { return clazz.getName(); } }