001: /*
002: * FindBugs - Find Bugs in Java programs
003: * Copyright (C) 2003-2007 University of Maryland
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package edu.umd.cs.findbugs.detect;
021:
022: import java.util.Iterator;
023:
024: import edu.umd.cs.findbugs.BugReporter;
025: import edu.umd.cs.findbugs.Detector2;
026: import edu.umd.cs.findbugs.DetectorFactoryCollection;
027: import edu.umd.cs.findbugs.NonReportingDetector;
028: import edu.umd.cs.findbugs.Plugin;
029: import edu.umd.cs.findbugs.PluginLoader;
030: import edu.umd.cs.findbugs.SystemProperties;
031: import edu.umd.cs.findbugs.ba.Dataflow;
032: import edu.umd.cs.findbugs.ba.DataflowCFGPrinter;
033: import edu.umd.cs.findbugs.ba.SignatureConverter;
034: import edu.umd.cs.findbugs.ba.XMethod;
035: import edu.umd.cs.findbugs.classfile.CheckedAnalysisException;
036: import edu.umd.cs.findbugs.classfile.ClassDescriptor;
037: import edu.umd.cs.findbugs.classfile.Global;
038: import edu.umd.cs.findbugs.classfile.IAnalysisCache;
039: import edu.umd.cs.findbugs.classfile.MethodDescriptor;
040: import edu.umd.cs.findbugs.classfile.analysis.ClassInfo;
041:
042: /**
043: * This detector is just a test harness to test a dataflow
044: * analysis class specified by the dataflow.classname property.
045: *
046: * @author David Hovemeyer
047: */
048: public class TestDataflowAnalysis implements Detector2,
049: NonReportingDetector {
050:
051: private String dataflowClassName;
052: private String methodName;
053: private Class<? extends Dataflow> dataflowClass;
054: private boolean initialized;
055:
056: public TestDataflowAnalysis(BugReporter bugReporter) {
057: dataflowClassName = SystemProperties
058: .getProperty("dataflow.classname");
059: methodName = SystemProperties.getProperty("dataflow.method");
060: }
061:
062: /* (non-Javadoc)
063: * @see edu.umd.cs.findbugs.Detector2#finishPass()
064: */
065: public void finishPass() {
066: }
067:
068: /* (non-Javadoc)
069: * @see edu.umd.cs.findbugs.Detector2#getDetectorClassName()
070: */
071: public String getDetectorClassName() {
072: return getClass().getName();
073: }
074:
075: /* (non-Javadoc)
076: * @see edu.umd.cs.findbugs.Detector2#visitClass(edu.umd.cs.findbugs.classfile.ClassDescriptor)
077: */
078: public void visitClass(ClassDescriptor classDescriptor)
079: throws CheckedAnalysisException {
080: if (dataflowClassName == null) {
081: return;
082: }
083:
084: if (!initialized) {
085: initialize();
086: }
087:
088: if (dataflowClass == null) {
089: return;
090: }
091:
092: IAnalysisCache analysisCache = Global.getAnalysisCache();
093:
094: ClassInfo classInfo = analysisCache.getClassAnalysis(
095: ClassInfo.class, classDescriptor);
096:
097: // Test dataflow analysis on each method]
098: for (XMethod xMethod : classInfo.getXMethods()) {
099: if (methodName != null
100: && !methodName.equals(xMethod.getName())) {
101: continue;
102: }
103: MethodDescriptor methodDescriptor = xMethod
104: .getMethodDescriptor();
105:
106: System.out
107: .println("-----------------------------------------------------------------");
108: System.out.println("Method: "
109: + SignatureConverter
110: .convertMethodSignature(methodDescriptor));
111: System.out
112: .println("-----------------------------------------------------------------");
113:
114: // Create and execute the dataflow analysis
115: Dataflow dataflow = analysisCache.getMethodAnalysis(
116: dataflowClass, methodDescriptor);
117:
118: System.out.println("Dataflow finished after "
119: + dataflow.getNumIterations());
120:
121: if (SystemProperties.getBoolean("dataflow.printcfg")) {
122: DataflowCFGPrinter cfgPrinter = new DataflowCFGPrinter(
123: dataflow);
124: cfgPrinter.print(System.out);
125: }
126:
127: }
128: }
129:
130: private void initialize() throws CheckedAnalysisException {
131: initialized = true;
132:
133: IAnalysisCache analysisCache = Global.getAnalysisCache();
134:
135: Class<?> cls = null;
136:
137: // First, try loading the dataflow class from the general findBugs code.
138: try {
139: cls = getClass().getClassLoader().loadClass(
140: dataflowClassName);
141: } catch (ClassNotFoundException e) {
142: // Ignore
143: }
144:
145: if (cls == null) {
146: // Find the dataflow class from the plugin in which it was loaded
147:
148: DetectorFactoryCollection detectorFactoryCollection = analysisCache
149: .getDatabase(DetectorFactoryCollection.class);
150: for (Iterator<Plugin> i = detectorFactoryCollection
151: .pluginIterator(); i.hasNext();) {
152: Plugin plugin = i.next();
153: PluginLoader pluginLoader = plugin.getPluginLoader();
154:
155: try {
156: cls = pluginLoader.getClassLoader().loadClass(
157: dataflowClassName);
158: break;
159: } catch (ClassNotFoundException e) {
160: // Ignore
161: }
162:
163: }
164: }
165:
166: if (cls == null) {
167: analysisCache.getErrorLogger().logError(
168: "TestDataflowAnalysis: could not load class "
169: + dataflowClassName);
170: return;
171: }
172:
173: if (!Dataflow.class.isAssignableFrom(cls)) {
174: analysisCache.getErrorLogger().logError(
175: "TestDataflowAnalysis: " + dataflowClassName
176: + " is not a Dataflow class");
177: return;
178: }
179:
180: dataflowClass = (Class<? extends Dataflow>) cls;
181: }
182:
183: }
|