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

📄 findbugs.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003-2006 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.DataInputStream;import java.io.File;import java.io.FileFilter;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.Constructor;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Map;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 org.apache.bcel.util.ClassPath;import edu.umd.cs.findbugs.annotations.SuppressWarnings;import edu.umd.cs.findbugs.ba.AbstractClassMember;import edu.umd.cs.findbugs.ba.AnalysisContext;import edu.umd.cs.findbugs.ba.AnalysisException;import edu.umd.cs.findbugs.ba.AnalysisFeatures;import edu.umd.cs.findbugs.ba.ClassContext;import edu.umd.cs.findbugs.ba.URLClassPath;import edu.umd.cs.findbugs.ba.URLClassPathRepository;import edu.umd.cs.findbugs.classfile.ClassDescriptor;import edu.umd.cs.findbugs.classfile.IClassObserver;import edu.umd.cs.findbugs.config.AnalysisFeatureSetting;import edu.umd.cs.findbugs.config.CommandLine;import edu.umd.cs.findbugs.config.UserPreferences;import edu.umd.cs.findbugs.config.CommandLine.HelpRequestedException;import edu.umd.cs.findbugs.filter.Filter;import edu.umd.cs.findbugs.filter.FilterException;import edu.umd.cs.findbugs.plan.AnalysisPass;import edu.umd.cs.findbugs.plan.ExecutionPlan;import edu.umd.cs.findbugs.plan.OrderingConstraintException;import edu.umd.cs.findbugs.util.Archive;import edu.umd.cs.findbugs.util.ClassName;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 * command line interface. *  * Much of the active work has migrated to the FindBugs2 engine, and that should be used * instead of FindBugs if possible. * * @author Bill Pugh * @author David Hovemeyer *  */public class FindBugs implements Constants2, ExitCodes, IFindBugsEngine {	/* ----------------------------------------------------------------------	 * 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);		}		@Override		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();		/**		 * Return the latest creation/modification time of any of the class files scanned. 		 * @return the last modification time		 */		public long getLastModificationTime();		/**		 * Close any internal files or streams.		 */		public void close();	}	/**	 * ClassProducer for single class files.	 */	private class SingleClassProducer implements ClassProducer {		private URL url;		long time = 0;		/**		 * 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 {				URLConnection u = urlToParse.openConnection();				time = u.getLastModified();				return parseFromStream(u.getInputStream(), urlToParse.toString());			} catch (ClassFormatException e) {				throw new ClassFormatException("Invalid class file format for " +						urlToParse.toString() + ": " + e.getMessage());			}		}		public boolean containsSourceFiles() {			return false;		}		public void close() {			// Nothing to do here		}		/* (non-Javadoc)		 * @see edu.umd.cs.findbugs.FindBugs.ClassProducer#getLatestTimeOfClass()		 */		public long getLastModificationTime() {			return time;		}	}	/**	 * 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;		private long time = 0;		private long zipTime = 0;		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());			URLConnection u = url.openConnection();			this.zipTime = u.getLastModified();			this.zipInputStream = new ZipInputStream(u.getInputStream());			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 = URLClassPath.getFileExtension(entryName);					if (fileExtension != null) {						if (fileExtension.equals(".class")) {							long modTime = zipEntry.getTime();							if (modTime > time) time = modTime;							return parseClass(url.toString(), new NoCloseInputStream(zipInputStream), entryName);						} else if (Archive.ARCHIVE_EXTENSION_SET.contains(fileExtension)) {							// Add nested archive to archive work list							if (url.toString().indexOf("!/") < 0) {							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				}			}		}		static final long millisecondsInAYear = 31556926000L; 		/* (non-Javadoc)		 * @see edu.umd.cs.findbugs.FindBugs.ClassProducer#getLastModificationTime()		 */		public long getLastModificationTime() {			if (time + millisecondsInAYear > zipTime) return time;			return zipTime;		}	}	/**	 * 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;		private long time;		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 {				long modTime = new File(fileName).lastModified();				if (time < modTime) time = modTime;				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		}		/* (non-Javadoc)		 * @see edu.umd.cs.findbugs.FindBugs.ClassProducer#getLastModificationTime()		 */		public long getLastModificationTime() {			return time;		}	}	public static final AnalysisFeatureSetting[] MIN_EFFORT = new AnalysisFeatureSetting[]{			new AnalysisFeatureSetting(AnalysisFeatures.CONSERVE_SPACE, true),			new AnalysisFeatureSetting(AnalysisFeatures.ACCURATE_EXCEPTIONS, false),			new AnalysisFeatureSetting(AnalysisFeatures.MODEL_INSTANCEOF, false),			new AnalysisFeatureSetting(AnalysisFeatures.SKIP_HUGE_METHODS, true),			new AnalysisFeatureSetting(AnalysisFeatures.INTERATIVE_OPCODE_STACK_ANALYSIS, false),			new AnalysisFeatureSetting(AnalysisFeatures.TRACK_GUARANTEED_VALUE_DEREFS_IN_NULL_POINTER_ANALYSIS, false),			new AnalysisFeatureSetting(AnalysisFeatures.TRACK_VALUE_NUMBERS_IN_NULL_POINTER_ANALYSIS, false),

⌨️ 快捷键说明

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