⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 findbugs.java

📁 一个查找java程序里bug的程序的源代码,该程序本身也是java写的,对提高java编程水平很有用
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003,2004 University of Maryland *  * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */package edu.umd.cs.findbugs;import java.io.BufferedOutputStream;import java.io.DataInputStream;import java.io.File;import java.io.FileFilter;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.PrintStream;import java.net.URL;import java.util.ArrayList;import java.util.Collection;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Set;import java.util.StringTokenizer;import java.util.zip.ZipEntry;import java.util.zip.ZipInputStream;import org.apache.bcel.Repository;import org.apache.bcel.classfile.ClassFormatException;import org.apache.bcel.classfile.ClassParser;import org.apache.bcel.classfile.JavaClass;import edu.umd.cs.findbugs.ba.AnalysisContext;import edu.umd.cs.findbugs.ba.AnalysisException;import edu.umd.cs.findbugs.ba.ClassContext;import edu.umd.cs.findbugs.ba.ClassObserver;import edu.umd.cs.findbugs.ba.InnerClassAccessMap;import edu.umd.cs.findbugs.visitclass.Constants2;/** * An instance of this class is used to apply the selected set of * analyses on some collection of Java classes.  It also implements the * comand line interface. * * @author Bill Pugh * @author David Hovemeyer */public class FindBugs implements Constants2, ExitCodes {	/* ----------------------------------------------------------------------	 * Helper classes	 * ---------------------------------------------------------------------- */	/**	 * Delegating InputStream wrapper that never closes the	 * underlying input stream.	 */	private static class NoCloseInputStream extends DataInputStream {		/**		 * Constructor.		 * @param in the real InputStream		 */		public NoCloseInputStream(InputStream in) {			super(in);		}		public void close() {		}	}	/**	 * Work list item specifying a file/directory/URL containing	 * class files to analyze.	 */	private static class ArchiveWorkListItem {		private String fileName;		private boolean explicit;		/**		 * Constructor.		 *		 * @param fileName file/directory/URL		 * @param explicit true if this source of classes appeared explicitly		 *                 in the project file, false if was found indirectly		 *                 (e.g., a nested jar file in a .war file)		 */		public ArchiveWorkListItem(String fileName, boolean explicit) {			this.fileName = fileName;			this.explicit = explicit;		}		/**		 * Get the file/directory/URL.		 */		public String getFileName() {			return fileName;		}		/**		 * Return whether this class source appeared explicitly in		 * the project file.		 */		public boolean isExplicit() {			return explicit;		}	}	/**	 * Interface for an object representing a source of class files to analyze.	 */	private interface ClassProducer {		/**		 * Get the next class to analyze.		 *		 * @return the class, or null of there are no more classes for this ClassProducer		 * @throws IOException          if an IOException occurs		 * @throws InterruptedException if the thread is interrupted		 */		public JavaClass getNextClass() throws IOException, InterruptedException;		/**		 * Did this class producer scan any Java source files?		 */		public boolean containsSourceFiles();		/**		 * Close any internal files or streams.		 */		public void close();	}	/**	 * ClassProducer for single class files.	 */	private class SingleClassProducer implements ClassProducer {		private URL url;		/**		 * Constructor.		 *		 * @param url the single class file to be analyzed		 */		public SingleClassProducer(URL url) {			this.url = url;		}		public JavaClass getNextClass() throws IOException, InterruptedException {			if (url == null)				return null;			if (Thread.interrupted())				throw new InterruptedException();			URL urlToParse = url;			url = null; // don't return it next time			// ClassScreener may veto this class.			if (!classScreener.matches(urlToParse.toString()))				return null;			try {				return parseClass(urlToParse);			} catch (ClassFormatException e) {				throw new ClassFormatException("Invalid class file format for " +				        url.toString() + ": " + e.getMessage());			}		}		public boolean containsSourceFiles() {			return false;		}		public void close() {			// Nothing to do here		}	}	/**	 * ClassProducer for zip/jar archives.	 */	private class ZipClassProducer implements ClassProducer {		private URL url;		private LinkedList<ArchiveWorkListItem> archiveWorkList;		private List<String> additionalAuxClasspathEntryList;		private ZipInputStream zipInputStream;		private boolean containsSourceFiles;		public ZipClassProducer(URL url, LinkedList<ArchiveWorkListItem> archiveWorkList,				List<String> additionalAuxClasspathEntryList)				throws IOException {			this.url = url;			this.archiveWorkList = archiveWorkList;			this.additionalAuxClasspathEntryList = additionalAuxClasspathEntryList;			if (DEBUG) System.out.println("Opening jar/zip input stream for " + url.toString());			this.zipInputStream = new ZipInputStream(url.openStream());			this.containsSourceFiles = false;		}		public JavaClass getNextClass() throws IOException, InterruptedException {			for (;;) {				if (Thread.interrupted())					throw new InterruptedException();				ZipEntry zipEntry = zipInputStream.getNextEntry();				if (zipEntry == null)					return null;				try {					String entryName = zipEntry.getName();					// ClassScreener may veto this class.					if (!classScreener.matches(entryName)) {						// Add archive URL to aux classpath						if (!additionalAuxClasspathEntryList.contains(url.toString())) {							//System.out.println("Adding additional aux classpath entry: " + url.toString());							additionalAuxClasspathEntryList.add(url.toString());						}						continue;					}					String fileExtension = getFileExtension(entryName);					if (fileExtension != null) {						if (fileExtension.equals(".class")) {							return parseClass(url.toString(), new NoCloseInputStream(zipInputStream), entryName);						} else if (archiveExtensionSet.contains(fileExtension)) {							// Add nested archive to archive work list							ArchiveWorkListItem nestedItem =								new ArchiveWorkListItem("jar:" + url.toString() + "!/" + entryName, false);							archiveWorkList.addFirst(nestedItem);						} else if (fileExtension.equals(".java")) {							containsSourceFiles = true;						}					}				} finally {					zipInputStream.closeEntry();				}			}		}		public boolean containsSourceFiles() {			return containsSourceFiles;		}		public void close() {			if (zipInputStream != null) {				try {					zipInputStream.close();				} catch (IOException ignore) {					// Ignore				}			}		}	}	/**	 * ClassProducer for directories.	 * The directory is scanned recursively for class files.	 */	private class DirectoryClassProducer implements ClassProducer {		private String dirName;		private List<String> additionalAuxClasspathEntryList;		private Iterator<String> rfsIter;		private boolean containsSourceFiles;		public DirectoryClassProducer(String dirName,				List<String> additionalAuxClasspathEntryList) throws InterruptedException {			this.dirName = dirName;			this.additionalAuxClasspathEntryList = additionalAuxClasspathEntryList;			FileFilter filter = new FileFilter() {				public boolean accept(File file) {					String fileName = file.getName();					if (file.isDirectory() || fileName.endsWith(".class"))						return true;					if (fileName.endsWith(".java"))						containsSourceFiles = true;					return false;				}			};			// This will throw InterruptedException if the thread is			// interrupted.			RecursiveFileSearch rfs = new RecursiveFileSearch(dirName, filter).search();			this.rfsIter = rfs.fileNameIterator();			this.containsSourceFiles = false;		}		public JavaClass getNextClass() throws IOException, InterruptedException {			String fileName;			for (;;) {				if (!rfsIter.hasNext())					return null;				fileName = rfsIter.next();				if (classScreener.matches(fileName)) {					break;				} else {					// Add directory URL to aux classpath					String dirURL= "file:" + dirName;					if (!additionalAuxClasspathEntryList.contains(dirURL)) {						//System.out.println("Adding additional aux classpath entry: " + dirURL);						additionalAuxClasspathEntryList.add(dirURL);					}				}			}			try {				return parseClass(new URL("file:" + fileName));			} catch (ClassFormatException e) {				throw new ClassFormatException("Invalid class file format for " +				        fileName + ": " + e.getMessage());			}		}		public boolean containsSourceFiles() {			return containsSourceFiles;		}		public void close() {			// Nothing to do here		}	}	/**	 * A delegating bug reporter which counts reported bug instances,	 * missing classes, and serious analysis errors.	 */	private static class ErrorCountingBugReporter extends DelegatingBugReporter {		private int bugCount;		private int missingClassCount;		private int errorCount;		private Set<String> missingClassSet = new HashSet<String>();		public ErrorCountingBugReporter(BugReporter realBugReporter) {			super(realBugReporter);			this.bugCount = 0;			this.missingClassCount = 0;			this.errorCount = 0;			// Add an observer to record when bugs make it through			// all priority and filter criteria, so our bug count is			// accurate.			realBugReporter.addObserver(new BugReporterObserver() {				public void reportBug(BugInstance bugInstance) {					++bugCount;				}			});		}		public int getBugCount() {			return bugCount;		}		public int getMissingClassCount() {			return missingClassCount;		}		public int getErrorCount() {			return errorCount;		}		public void logError(String message) {			++errorCount;			super.logError(message);		}		public void reportMissingClass(ClassNotFoundException ex) {			String missing = AbstractBugReporter.getMissingClassName(ex);			if (missingClassSet.add(missing))				++missingClassCount;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -