package jdepend.util.analyzer.element; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import jdepend.metadata.JavaClass; import jdepend.metadata.Method; import jdepend.model.result.AnalysisResult; import jdepend.util.analyzer.framework.AbstractAnalyzer; import jdepend.util.analyzer.framework.Analyzer; import jdepend.util.analyzer.framework.AnalyzerException; public final class TogetherInvokeMethod extends AbstractAnalyzer { private static final long serialVersionUID = -8417592572714047463L; public TogetherInvokeMethod() { super("识别共同调用的方法集合", Analyzer.Attention, "识别同一个类的多个方法被共同调用的情况"); } @Override protected void doExecute(AnalysisResult result) throws AnalyzerException { Map<JavaClass, Collection<Method>> invokedMethods; CollectionMethod cm; Map<CollectionMethod, Collection<Method>> cms = new HashMap<CollectionMethod, Collection<Method>>(); for (Method method : result.getMethods()) { // 对方法中调用的方法按着类进行分组 invokedMethods = new HashMap<JavaClass, Collection<Method>>(); for (Method invokeMethod1 : method.getInvokeMethods()) { if (!invokeMethod1.getJavaClass().equals(method.getJavaClass())) { if (!invokedMethods.containsKey(invokeMethod1.getJavaClass())) { invokedMethods.put(invokeMethod1.getJavaClass(), new ArrayList<Method>()); } invokedMethods.get(invokeMethod1.getJavaClass()).add(invokeMethod1); } } // 收集分组后大于一个方法的方法集合 for (JavaClass javaClass : invokedMethods.keySet()) { if (invokedMethods.get(javaClass).size() > 1) { cm = new CollectionMethod(invokedMethods.get(javaClass)); // 收集方法集合大于1处调用的情况 if (!cms.containsKey(cm)) { cms.put(cm, new ArrayList<Method>()); } cms.get(cm).add(method); } } this.progress(); } for (CollectionMethod cm1 : cms.keySet()) { if (cms.get(cm1).size() > 1) { for (Method invokeMethod : cms.get(cm1)) { this.printTable("类名", cm1.getJavaClass().getName()); this.printTable("方法集合名", cm1.toString()); this.printTable("出现的次数", cms.get(cm1).size()); this.printTable("调用者类名", invokeMethod.getJavaClass().getName()); this.printTable("调用者方法名", invokeMethod.getInfo()); } } } } @Override public int getMaxProgress(AnalysisResult result) { return result.getMethods().size(); } @Override public String getExplain() { StringBuilder explain = new StringBuilder(); explain.append("当一个类中的多个方法经常在一起被其他方法调用时,应考虑是否应该进行合并。<br>"); return explain.toString(); } class CollectionMethod { private Collection<Method> methods; public CollectionMethod(Collection<Method> methods) { super(); this.methods = methods; } public Collection<Method> getMethods() { return methods; } public JavaClass getJavaClass() { return methods.iterator().next().getJavaClass(); } @Override public String toString() { StringBuilder info = new StringBuilder(); for (Method method : methods) { info.append(method.getInfo()); info.append("\n"); } info.delete(info.length() - 1, info.length()); return info.toString(); } @Override public int hashCode() { int code = 0; for (Method method : methods) { code += method.hashCode(); } return code; } @Override public boolean equals(Object obj) { CollectionMethod cm = (CollectionMethod) obj; for (Method method : methods) { if (!cm.methods.contains(method)) { return false; } } for (Method method : cm.methods) { if (!methods.contains(method)) { return false; } } return true; } } }