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;
}
}