package jdepend.util.analyzer.element;
import java.util.Collection;
import java.util.HashSet;
import jdepend.metadata.JavaClass;
import jdepend.metadata.Method;
import jdepend.model.JavaClassUnit;
import jdepend.model.result.AnalysisResult;
import jdepend.util.analyzer.framework.AbstractAnalyzer;
import jdepend.util.analyzer.framework.Analyzer;
import jdepend.util.analyzer.framework.AnalyzerException;
public class IdentifyCallback extends AbstractAnalyzer {
private static final long serialVersionUID = -4566409232231165490L;
public IdentifyCallback() {
super("Callback识别", Analyzer.Attention, "识别在组件中设置Callback的情况");
}
@Override
protected void doExecute(AnalysisResult result) throws AnalyzerException {
boolean isCallback1;// 该类为接口,并且其方法有返回值,该方法被本组件调用
boolean isCallback2;// 该类的实现类不与该类处于一个组件内
boolean isCallback3;// 实现类的构造过程不在该组件内
Method callbackMethod = null;
Method method1 = null;
JavaClass subClass2 = null;
Collection<Method> method3s = null;
for (JavaClassUnit javaClass : result.getClasses()) {
isCallback1 = false;
if (javaClass.getJavaClass().isInterface()) {
L: for (Method method : javaClass.getJavaClass().getSelfMethods()) {
if (method.existReturn()) {
for (Method invokedMethod : method.getInvokedMethods()) {
if (result.getTheClass(invokedMethod.getJavaClass().getId()).getComponent()
.equals(javaClass.getComponent())) {
callbackMethod = method;
method1 = invokedMethod;
isCallback1 = true;
break L;
}
}
}
}
}
isCallback2 = false;
isCallback3 = false;
if (isCallback1) {
M: for (JavaClass subClass : javaClass.getJavaClass().getSubClasses()) {
if (!result.getTheClass(subClass.getId()).getComponent().equals(javaClass.getComponent())) {
isCallback2 = true;
subClass2 = subClass;
isCallback3 = true;
method3s = new HashSet<Method>();
for (Method method : subClass.getConstructorMethods()) {
for (Method invokedMethod : method.getInvokedMethods()) {
if (result.getTheClass(invokedMethod.getJavaClass().getId()).getComponent()
.equals(javaClass.getComponent())) {
isCallback3 = false;
break M;
}
method3s.add(invokedMethod);
}
}
}
}
}
if (isCallback2 && isCallback3) {
this.print("\nComponent:" + javaClass.getComponent().getName() + "\n");
this.print("Callback : " + javaClass.getName() + "." + callbackMethod.getName() + "\n");
this.printTab();
this.print("is Invoked Method : " + method1.getJavaClass().getName() + "." + method1.getName() + "\n");
this.printTab();
this.print("have subClass : " + subClass2.getName() + " Constructors InvokedMethods:\n");
for (Method method : method3s) {
this.printTab();
this.printTab();
this.print("Invoked Method : " + method.getJavaClass().getName() + "." + method.getName() + "\n");
}
}
}
}
@Override
public String getExplain() {
StringBuilder explain = new StringBuilder();
explain.append("当一个组件中内置了Callback后,其测试结果依赖于Callback接口的实例化类,这会增加测试的难度和组件运行时的不确定性。<br>");
explain.append("识别Callback的规则是:<br>");
explain.append("1、该类为接口,并且其方法有返回值,该方法被本组件调用<br>");
explain.append("2、该类的实现类不与该类处于一个组件内<br>");
explain.append("3、实现类的构造过程不在该组件内<br>");
return explain.toString();
}
}