📄 classpathbuilder.java
字号:
/* * FindBugs - Find Bugs in Java programs * Copyright (C) 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.classfile.impl;import java.io.DataInputStream;import java.io.File;import java.io.FileFilter;import java.io.IOException;import java.io.InputStream;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.ListIterator;import java.util.Map;import java.util.Set;import java.util.StringTokenizer;import java.util.jar.Attributes;import java.util.jar.Manifest;import edu.umd.cs.findbugs.SystemProperties;import edu.umd.cs.findbugs.classfile.CheckedAnalysisException;import edu.umd.cs.findbugs.classfile.ClassDescriptor;import edu.umd.cs.findbugs.classfile.IClassFactory;import edu.umd.cs.findbugs.classfile.IClassPath;import edu.umd.cs.findbugs.classfile.IClassPathBuilder;import edu.umd.cs.findbugs.classfile.IClassPathBuilderProgress;import edu.umd.cs.findbugs.classfile.ICodeBase;import edu.umd.cs.findbugs.classfile.ICodeBaseEntry;import edu.umd.cs.findbugs.classfile.ICodeBaseIterator;import edu.umd.cs.findbugs.classfile.ICodeBaseLocator;import edu.umd.cs.findbugs.classfile.IErrorLogger;import edu.umd.cs.findbugs.classfile.IScannableCodeBase;import edu.umd.cs.findbugs.classfile.InvalidClassFileFormatException;import edu.umd.cs.findbugs.classfile.ResourceNotFoundException;import edu.umd.cs.findbugs.classfile.analysis.ClassInfo;import edu.umd.cs.findbugs.classfile.analysis.ClassNameAndSuperclassInfo;import edu.umd.cs.findbugs.classfile.engine.ClassParser;import edu.umd.cs.findbugs.io.IO;import edu.umd.cs.findbugs.util.Archive;/** * Implementation of IClassPathBuilder. * * @author David Hovemeyer */public class ClassPathBuilder implements IClassPathBuilder { private static final boolean VERBOSE = SystemProperties.getBoolean("findbugs2.builder.verbose"); private static final boolean DEBUG = VERBOSE || SystemProperties.getBoolean("findbugs2.builder.debug"); private static final boolean NO_PARSE_CLASS_NAMES = SystemProperties.getBoolean("findbugs2.builder.noparseclassnames"); /** * Worklist item. * Represents one codebase to be processed during the * classpath construction algorithm. */ static class WorkListItem { private ICodeBaseLocator codeBaseLocator; private boolean isAppCodeBase; private int howDiscovered; @Override public String toString() { return "WorkListItem(" + codeBaseLocator +", " + isAppCodeBase + ", " + howDiscovered +")"; } public WorkListItem(ICodeBaseLocator codeBaseLocator, boolean isApplication, int howDiscovered) { this.codeBaseLocator = codeBaseLocator; this.isAppCodeBase = isApplication; this.howDiscovered = howDiscovered; } public ICodeBaseLocator getCodeBaseLocator() { return codeBaseLocator; } public boolean isAppCodeBase() { return isAppCodeBase; } /** * @return Returns the howDiscovered. */ public int getHowDiscovered() { return howDiscovered; } } /** * A codebase discovered during classpath building. */ static class DiscoveredCodeBase { ICodeBase codeBase; LinkedList<ICodeBaseEntry> resourceList; public DiscoveredCodeBase(ICodeBase codeBase) { this.codeBase= codeBase; this.resourceList = new LinkedList<ICodeBaseEntry>(); } public ICodeBase getCodeBase() { return codeBase; } public LinkedList<ICodeBaseEntry> getResourceList() { return resourceList; } public void addCodeBaseEntry(ICodeBaseEntry entry) { resourceList.add(entry); } public ICodeBaseIterator iterator() throws InterruptedException { if (codeBase instanceof IScannableCodeBase) { return ((IScannableCodeBase) codeBase).iterator(); } else { return new ICodeBaseIterator() { public boolean hasNext() throws InterruptedException { return false; } public ICodeBaseEntry next() throws InterruptedException { throw new UnsupportedOperationException(); } }; } } } // Fields private IClassFactory classFactory; private IErrorLogger errorLogger; private LinkedList<WorkListItem> projectWorkList; private LinkedList<DiscoveredCodeBase> discoveredCodeBaseList; private Map<String, DiscoveredCodeBase> discoveredCodeBaseMap; private LinkedList<ClassDescriptor> appClassList; private boolean scanNestedArchives; /** * Constructor. * * @param classFactory the class factory * @param errorLogger the error logger */ ClassPathBuilder(IClassFactory classFactory, IErrorLogger errorLogger) { this.classFactory = classFactory; this.errorLogger = errorLogger; this.projectWorkList = new LinkedList<WorkListItem>(); this.discoveredCodeBaseList = new LinkedList<DiscoveredCodeBase>(); this.discoveredCodeBaseMap = new HashMap<String, DiscoveredCodeBase>(); this.appClassList = new LinkedList<ClassDescriptor>(); } /* (non-Javadoc) * @see edu.umd.cs.findbugs.classfile.IClassPathBuilder#addCodeBase(edu.umd.cs.findbugs.classfile.ICodeBaseLocator, boolean) */ public void addCodeBase(ICodeBaseLocator locator, boolean isApplication) { addToWorkList(projectWorkList, new WorkListItem(locator, isApplication, ICodeBase.SPECIFIED)); } /* (non-Javadoc) * @see edu.umd.cs.findbugs.classfile.IClassPathBuilder#scanNestedArchives(boolean) */ public void scanNestedArchives(boolean scanNestedArchives) { this.scanNestedArchives = scanNestedArchives; } /* (non-Javadoc) * @see edu.umd.cs.findbugs.classfile.IClassPathBuilder#build(edu.umd.cs.findbugs.classfile.IClassPath, edu.umd.cs.findbugs.classfile.IClassPathBuilderProgress) */ public void build(IClassPath classPath, IClassPathBuilderProgress progress) throws CheckedAnalysisException, IOException, InterruptedException { // Discover all directly and indirectly referenced codebases processWorkList(classPath, projectWorkList, progress); boolean foundJavaLangObject = false; for (DiscoveredCodeBase discoveredCodeBase : discoveredCodeBaseList) { try { ICodeBaseEntry entry = discoveredCodeBase.getCodeBase().lookupResource("java/lang/Object.class"); foundJavaLangObject = true; } catch (ResourceNotFoundException e) { assert true; } } if (!foundJavaLangObject) processWorkList(classPath, buildSystemCodebaseList(), progress); // Add all discovered codebases to the classpath for (DiscoveredCodeBase discoveredCodeBase : discoveredCodeBaseList) { classPath.addCodeBase(discoveredCodeBase.getCodeBase()); } Set<ClassDescriptor> appClassSet = new HashSet<ClassDescriptor>(); // Build collection of all application classes. // Also, add resource name -> codebase entry mappings for application classes. for (DiscoveredCodeBase discoveredCodeBase : discoveredCodeBaseList) { if (!discoveredCodeBase.getCodeBase().isApplicationCodeBase()) { continue; } codeBaseEntryLoop: for (ICodeBaseIterator i = discoveredCodeBase.iterator(); i.hasNext(); ) { ICodeBaseEntry entry = i.next(); if (!ClassDescriptor.isClassResource(entry.getResourceName())) { continue; } ClassDescriptor classDescriptor = entry.getClassDescriptor(); if (classDescriptor == null) throw new IllegalStateException(); if (appClassSet.contains(classDescriptor)) { // An earlier entry takes precedence over this class continue codeBaseEntryLoop; } appClassSet.add(classDescriptor); appClassList.add(classDescriptor); classPath.mapResourceNameToCodeBaseEntry(entry.getResourceName(), entry); } } if (DEBUG) { System.out.println("Classpath:"); dumpCodeBaseList(classPath.appCodeBaseIterator(), "Application codebases"); dumpCodeBaseList(classPath.auxCodeBaseIterator(), "Auxiliary codebases"); } } private void dumpCodeBaseList(Iterator<? extends ICodeBase> i, String desc) throws InterruptedException { System.out.println(" " + desc + ":"); while (i.hasNext()) { ICodeBase codeBase = i.next(); System.out.println(" " + codeBase.getCodeBaseLocator().toString()); if (codeBase.containsSourceFiles()) { System.out.println(" * contains source files"); } } } private LinkedList<WorkListItem> buildSystemCodebaseList() { // This method is based on the // org.apache.bcel.util.ClassPath.getClassPath() // method. LinkedList<WorkListItem> workList = new LinkedList<WorkListItem>(); String bootClassPath = SystemProperties.getProperty("sun.boot.class.path"); // Seed worklist with system codebases. // addWorkListItemsForClasspath(workList, SystemProperties.getProperty("java.class.path")); addWorkListItemsForClasspath(workList, bootClassPath); String extPath = SystemProperties.getProperty("java.ext.dirs"); if (extPath != null) { StringTokenizer st = new StringTokenizer(extPath, File.pathSeparator); while (st.hasMoreTokens()) { String extDir = st.nextToken(); addWorkListItemsForExtDir(workList, extDir); } } return workList; } /** * Add worklist items from given system classpath. * * @param workList the worklist * @param path a system classpath */ private void addWorkListItemsForClasspath(LinkedList<WorkListItem> workList, String path) { if (path == null) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -