package jdepend.metadata; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import jdepend.framework.util.StringUtil; import jdepend.metadata.annotation.AnnotationDefs; import jdepend.metadata.annotation.AnnotationParse; import jdepend.metadata.annotation.Controller; import jdepend.metadata.annotation.RequestMapping; import jdepend.metadata.annotation.Service; import jdepend.metadata.util.JavaClassCollection; import org.apache.bcel.classfile.AnnotationEntry; import org.apache.bcel.classfile.ElementValuePair; public class JavaClassDetail implements Serializable { /** * */ private static final long serialVersionUID = 3437990183453118207L; private final JavaClass javaClass; private String superClassName; private Collection<String> interfaceNames = new ArrayList<String>(); private final Collection<Attribute> attributes = new ArrayList<Attribute>(); private final Collection<Method> methods = new ArrayList<Method>(); private final Collection<String> variableTypes = new ArrayList<String>(); private final Collection<TableInfo> tables = new ArrayList<TableInfo>(); private AnnotationDefs annotationDefs; private boolean httpCaller; private transient JavaClass superClass; private transient Collection<JavaClass> interfaces = new ArrayList<JavaClass>(); private transient Collection<String> attributeTypes; private transient Collection<JavaClass> attributeClasses; private transient Collection<String> paramTypes; private transient Map<String, Attribute> attributeForNames = new HashMap<String, Attribute>(); private transient Collection<String> returnTypes; private transient Collection<String> superTypes; public JavaClassDetail(JavaClass javaClass) { this.javaClass = javaClass; this.annotationDefs = new AnnotationDefs(); } public void parseAnnotation(org.apache.bcel.classfile.JavaClass obj) { // 处理Annotation for (AnnotationEntry annotationEntry : obj.getAnnotationEntries()) { if (annotationEntry.getAnnotationType().equals(AnnotationParse.Table)) { TableInfo tableInfo = AnnotationParse.parseTable(annotationEntry); if (tableInfo != null) { this.addTable(tableInfo); } } else if (annotationEntry.getAnnotationType().equals(AnnotationParse.Transactional)) { this.annotationDefs.setTransactional(AnnotationParse.parseTransactional(annotationEntry)); } else if (annotationEntry.getAnnotationType().equals(AnnotationParse.RequestMapping)) { this.annotationDefs.setRequestMapping(AnnotationParse.parseRequestMapping(annotationEntry)); } else if (annotationEntry.getAnnotationType().equals(AnnotationParse.Controller)) { this.annotationDefs.setController(AnnotationParse.parseController(annotationEntry)); } else if (annotationEntry.getAnnotationType().equals(AnnotationParse.Service)) { this.annotationDefs.setService(AnnotationParse.parseService(annotationEntry)); } } } public AnnotationDefs getAnnotations() { return annotationDefs; } public Collection<String> getAttributeTypes() { if (this.attributeTypes == null) { this.attributeTypes = new HashSet<String>(); for (Attribute attribute : this.attributes) { for (String type : attribute.getTypes()) { this.attributeTypes.add(type); } } } return attributeTypes; } public Collection<JavaClass> getAttributeClasses() { if (this.attributeClasses == null) { this.attributeClasses = new HashSet<JavaClass>(); for (Attribute attribute : this.attributes) { for (JavaClass type : attribute.getTypeClasses()) { this.attributeClasses.add(type); } } } return attributeClasses; } public Collection<String> getInterfaceNames() { return interfaceNames; } public void addInterfaceName(String interfaceName) { if (!this.interfaceNames.contains(interfaceName)) { this.interfaceNames.add(interfaceName); } } public Collection<String> getParamTypes() { if (this.paramTypes == null) { this.paramTypes = new HashSet<String>(); for (Method method : this.methods) { for (String type : method.getArgumentTypes()) { this.paramTypes.add(type); } for (String type : method.getReturnTypes()) { this.paramTypes.add(type); } } } return paramTypes; } public String getSuperClassName() { return superClassName; } public void setSuperClassName(String superClassName) { this.superClassName = superClassName; } public Collection<String> getVariableTypes() { return variableTypes; } public void addVariableType(String variableType) { if (!this.variableTypes.contains(variableType)) { this.variableTypes.add(variableType); } } public Collection<TableInfo> getTables() { return tables; } public void addTable(TableInfo table) { if (!this.tables.contains(table)) { this.tables.add(table); } } public Collection<Attribute> getAttributes() { return attributes; } public void addAttribute(Attribute attribute) { if (!this.attributes.contains(attribute)) { this.attributes.add(attribute); this.attributeForNames.put(attribute.getName(), attribute); } } public Attribute getTheAttribute(String name) { return this.attributeForNames.get(name); } public Collection<Method> getMethods() { return methods; } public Collection<String> getReturnTypes() { if (this.returnTypes == null) { this.returnTypes = new HashSet<String>(); for (Method method : this.methods) { for (String returnType : method.getReturnTypes()) { if (!returnTypes.contains(returnType)) { returnTypes.add(returnType); } } } } return returnTypes; } public void addMethod(Method method) { if (!this.methods.contains(method)) { this.methods.add(method); } } public Collection<String> getSupers() { if (this.superTypes == null) { this.superTypes = new HashSet<String>(); for (String interfaceName : this.getInterfaceNames()) { superTypes.add(interfaceName); } if (this.superClassName != null) { superTypes.add(this.superClassName); } } return superTypes; } public void setSuperClass(JavaClass superClass) { this.superClass = superClass; this.superClass.addSubClass(this.javaClass); } public void setInterfaces(Collection<JavaClass> interfaces) { this.interfaces = interfaces; for (JavaClass interfaceClass : this.interfaces) { interfaceClass.addSubClass(this.javaClass); } } public void setInterfaceNames(Collection<String> interfaceNames) { this.interfaceNames = interfaceNames; } public JavaClass getSuperClass() { return superClass; } public Collection<JavaClass> getInterfaces() { return interfaces; } public RequestMapping getRequestMapping() { return this.annotationDefs.getRequestMapping(); } public String getRequestMappingValue() { if (this.getRequestMapping() == null) { return null; } if (this.getRequestMapping().getValue().startsWith("/")) { return this.getRequestMapping().getValue(); } else { return "/" + this.getRequestMapping().getValue(); } } public Controller getController() { return this.annotationDefs.getController(); } public Service getService() { return this.annotationDefs.getService(); } public boolean isHttpCaller() { return httpCaller; } public void setHttpCaller(boolean httpCaller) { this.httpCaller = httpCaller; } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); this.interfaces = new HashSet<JavaClass>(); this.attributeForNames = new HashMap<String, Attribute>(); } public JavaClassDetail clone(JavaClass javaClass) { JavaClassDetail obj = new JavaClassDetail(javaClass); obj.setSuperClassName(this.getSuperClassName()); obj.setInterfaceNames(this.getInterfaceNames()); for (Attribute attribute : this.getAttributes()) { obj.addAttribute(new Attribute(attribute.getJavaClass().getId(), attribute)); } for (Method method : this.getMethods()) { obj.addMethod(new Method(method.getJavaClass().getId(), method)); } for (String name : this.getVariableTypes()) { obj.addVariableType(name); } for (TableInfo tableRelationInfo : this.getTables()) { obj.addTable(new TableInfo(tableRelationInfo)); } obj.annotationDefs = this.annotationDefs; obj.httpCaller = this.httpCaller; return obj; } public void supply(JavaClassCollection javaClasses) { // 填充superClass和interfaces JavaClass superClass = javaClasses.getTheClass(javaClass.getPlace(), this.getSuperClassName()); if (superClass != null) { this.setSuperClass(superClass); } Collection<JavaClass> interfaces = new HashSet<JavaClass>(); for (String interfaceName : this.getInterfaceNames()) { JavaClass interfaceClass = javaClasses.getTheClass(javaClass.getPlace(), interfaceName); if (interfaceClass != null) { interfaces.add(interfaceClass); } } this.setInterfaces(interfaces); // 填充Attribute中的JavaClass for (Attribute attribute : this.getAttributes()) { attribute.supply(javaClasses); } // 填充Method中的JavaClass for (Method method : this.getMethods()) { method.supply(javaClasses); } } public void filterExternalJavaClass(Collection<JavaClass> javaClasses) { if (!javaClasses.contains(this.superClass)) { this.superClass = null; } for (JavaClass interfaceClass : this.interfaces) { if (!javaClasses.contains(interfaceClass)) { this.interfaces.remove(interfaceClass); } } for (Attribute attribute : this.getAttributes()) { attribute.filterExternalJavaClass(javaClasses); } for (Method method : this.getMethods()) { method.filterExternalJavaClass(javaClasses); } } @Override public String toString() { StringBuilder content = new StringBuilder(500); content.append("Name:"); content.append(this.javaClass.getName()); content.append("\n"); if (this.javaClass.getJavaPackage() != null) { content.append("package:"); content.append(this.javaClass.getJavaPackage().getName()); content.append("\n"); } content.append("ImportPackages:\n"); for (String importPackage : this.javaClass.getImportedPackages()) { content.append(tab()); content.append(importPackage); content.append("\n"); } content.append("\n"); if (superClassName != null) { content.append("SuperClassName:"); content.append(superClassName); content.append("\n"); } if (interfaceNames != null && interfaceNames.size() > 0) { content.append("InterfaceNames:\n"); for (String interfaceName : interfaceNames) { content.append(tab()); content.append(interfaceName); content.append("\n"); } } content.append("isAbstract:"); content.append(this.javaClass.isAbstract()); content.append("\n"); if (this.javaClass.getPlace() != null) { content.append("Place:"); content.append(this.javaClass.getPlace()); content.append("\n"); } if (this.getRequestMappingValue() != null) { content.append("RequestMapping:"); content.append(this.getRequestMappingValue()); content.append("\n"); } if (this.annotationDefs.getTransactional() != null) { content.append("Transactional:"); content.append(this.annotationDefs.getTransactional()); content.append("\n"); } if (this.annotationDefs.getController() != null) { content.append("Controller:"); content.append(this.annotationDefs.getController()); content.append("\n"); } if (this.annotationDefs.getService() != null) { content.append("Service:"); content.append(this.annotationDefs.getService()); content.append("\n"); } content.append("\n"); if (this.getAttributeTypes() != null && this.getAttributeTypes().size() > 0) { content.append("attributeTypes:\n"); for (String attributeType : this.getAttributeTypes()) { content.append(tab()); content.append(attributeType); content.append("\n"); } content.append("\n"); } if (this.getParamTypes() != null && this.getParamTypes().size() > 0) { content.append("paramTypes:\n"); for (String paramType : this.getParamTypes()) { content.append(tab()); content.append(paramType); content.append("\n"); } content.append("\n"); } if (variableTypes != null && variableTypes.size() > 0) { content.append("variableTypes:\n"); for (String variableType : variableTypes) { content.append(tab()); content.append(variableType); content.append("\n"); } content.append("\n"); } if (attributes != null && attributes.size() > 0) { content.append("attributes:\n"); for (Attribute attribute : attributes) { content.append(tab()); content.append(attribute); content.append("\n"); } content.append("\n"); } if (methods != null && methods.size() > 0) { content.append("methods:\n"); for (Method method : methods) { content.append(tab()); content.append(method); content.append("\n"); } content.append("\n"); } if (tables != null && tables.size() > 0) { content.append("tables:\n"); for (TableInfo table : tables) { content.append(tab()); content.append(table); content.append("\n"); } content.append("\n"); } if (this.javaClass.getInnerClasses().size() > 0) { content.append("innerClasses:\n"); for (JavaClass innerClass : this.javaClass.getInnerClasses()) { content.append(tab()); content.append(innerClass.getName()); content.append("\n"); } content.append("\n"); } return content.toString(); } private String tab() { return " "; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + this.getClass().getName().hashCode(); result = prime * result + ((javaClass == null) ? 0 : javaClass.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (getClass() != obj.getClass()) return false; final JavaClassDetail other = (JavaClassDetail) obj; if (!javaClass.equals(other.javaClass)) return false; return true; } }