📄 classpathbuilder.java
字号:
return; } StringTokenizer st = new StringTokenizer(path, File.pathSeparator); while (st.hasMoreTokens()) { String entry = st.nextToken(); if (DEBUG) { System.out.println("System classpath entry: " + entry); } addToWorkList(workList, new WorkListItem( classFactory.createFilesystemCodeBaseLocator(entry), false, ICodeBase.IN_SYSTEM_CLASSPATH)); } } /** * Add worklist items from given extensions directory. * * @param workList the worklist * @param extDir an extensions directory */ private void addWorkListItemsForExtDir(LinkedList<WorkListItem> workList, String extDir) { File dir = new File(extDir); File[] fileList = dir.listFiles(new FileFilter() { /* (non-Javadoc) * @see java.io.FileFilter#accept(java.io.File) */ public boolean accept(File pathname) { String path = pathname.getParent(); return Archive.isArchiveFileName(path); } }); if (fileList == null) { return; } for (File archive : fileList) { addToWorkList(workList, new WorkListItem( classFactory.createFilesystemCodeBaseLocator(archive.getPath()), false, ICodeBase.IN_SYSTEM_CLASSPATH)); } } /** * Process classpath worklist items. * We will attempt to find all nested archives and * Class-Path entries specified in Jar manifests. This should give us * as good an idea as possible of all of the classes available (and * which are part of the application). * * @param workList the worklist to process * @param progress IClassPathBuilderProgress callback * @throws InterruptedException * @throws IOException * @throws ResourceNotFoundException */ private void processWorkList( IClassPath classPath, LinkedList<WorkListItem> workList, IClassPathBuilderProgress progress) throws InterruptedException, IOException, ResourceNotFoundException { // Build the classpath, scanning codebases for nested archives // and referenced codebases. while (!workList.isEmpty()) { WorkListItem item = workList.removeFirst(); if (DEBUG) { System.out.println("Working: " + item.getCodeBaseLocator()); } DiscoveredCodeBase discoveredCodeBase; // See if we have encountered this codebase before discoveredCodeBase = discoveredCodeBaseMap.get(item.getCodeBaseLocator().toString()); if (discoveredCodeBase != null) { // If the codebase is not an app codebase and // the worklist item says that it is an app codebase, // change it. Otherwise, we have nothing to do. if (!discoveredCodeBase.getCodeBase().isApplicationCodeBase() && item.isAppCodeBase()) { discoveredCodeBase.getCodeBase().setApplicationCodeBase(true); } continue; } // If we are working on an application codebase, // then failing to open/scan it is a fatal error. // We issue warnings about problems with aux codebases, // but continue anyway. try { // Open the codebase and add it to the classpath discoveredCodeBase = new DiscoveredCodeBase(item.getCodeBaseLocator().openCodeBase()); discoveredCodeBase.getCodeBase().setApplicationCodeBase(item.isAppCodeBase()); discoveredCodeBase.getCodeBase().setHowDiscovered(item.getHowDiscovered()); // Note that this codebase has been visited discoveredCodeBaseMap.put(item.getCodeBaseLocator().toString(), discoveredCodeBase); discoveredCodeBaseList.addLast(discoveredCodeBase); // If it is a scannable codebase, check it for nested archives. // In addition, if it is an application codebase then // make a list of application classes. if (discoveredCodeBase.getCodeBase() instanceof IScannableCodeBase && discoveredCodeBase.codeBase.isApplicationCodeBase()) { scanCodebase(classPath, workList, discoveredCodeBase); } // Check for a Jar manifest for additional aux classpath entries. scanJarManifestForClassPathEntries(workList, discoveredCodeBase.getCodeBase()); } catch (IOException e) { if (item.isAppCodeBase()) { throw e; } else if (item.getHowDiscovered() == ICodeBase.SPECIFIED) { errorLogger.logError("Cannot open codebase " + item.getCodeBaseLocator(), e); } } catch (ResourceNotFoundException e) { if (item.isAppCodeBase()) { throw e; } else if (item.getHowDiscovered() == ICodeBase.SPECIFIED) { errorLogger.logError("Cannot open codebase " + item.getCodeBaseLocator(), e); } } if (item.getHowDiscovered() == ICodeBase.SPECIFIED) { progress.finishArchive(); } } } /** * Scan given codebase in order to * <ul> * <li> check the codebase for nested archives * (adding any found to the worklist) * <li> build a list of class resources found in the codebase * </ul> * * @param workList the worklist * @param discoveredCodeBase the codebase to scan * @throws InterruptedException */ private void scanCodebase(IClassPath classPath, LinkedList<WorkListItem> workList, DiscoveredCodeBase discoveredCodeBase) throws InterruptedException { if (DEBUG) { System.out.println("Scanning " + discoveredCodeBase.getCodeBase().getCodeBaseLocator()); } IScannableCodeBase codeBase = (IScannableCodeBase) discoveredCodeBase.getCodeBase(); ICodeBaseIterator i = codeBase.iterator(); while (i.hasNext()) { ICodeBaseEntry entry = i.next(); if (VERBOSE) { System.out.println("Entry: " + entry.getResourceName()); } if (!NO_PARSE_CLASS_NAMES && codeBase.isApplicationCodeBase() && ClassDescriptor.isClassResource(entry.getResourceName())) { parseClassName(entry); } // Note the resource exists in this codebase discoveredCodeBase.addCodeBaseEntry(entry); // If resource is a nested archive, add it to the worklist if (scanNestedArchives && codeBase.isApplicationCodeBase() && Archive.isArchiveFileName(entry.getResourceName())) { if (VERBOSE) { System.out.println("Entry is an archive!"); } ICodeBaseLocator nestedArchiveLocator = classFactory.createNestedArchiveCodeBaseLocator(codeBase, entry.getResourceName()); addToWorkList( workList, new WorkListItem(nestedArchiveLocator, codeBase.isApplicationCodeBase(), ICodeBase.NESTED)); } } } /** * Attempt to parse data of given resource in order * to divine the real name of the class contained in the * resource. * * @param entry the resource */ private void parseClassName(ICodeBaseEntry entry) { DataInputStream in = null; try { in = new DataInputStream(entry.openResource()); ClassParser parser = new ClassParser(in, null, entry); ClassNameAndSuperclassInfo classInfo = new ClassNameAndSuperclassInfo(); parser.parse(classInfo); entry.overrideResourceName(classInfo.getClassDescriptor().toResourceName()); } catch (IOException e) { errorLogger.logError("Invalid class resource " + entry.getResourceName() + " in " + entry, e); } catch (InvalidClassFileFormatException e) { errorLogger.logError("Invalid class resource " + entry.getResourceName() + " in " + entry, e); } finally { IO.close(in); } } /** * Check a codebase for a Jar manifest to examine for Class-Path entries. * * @param workList the worklist * @param codeBase the codebase for examine for a Jar manifest * @throws IOException */ private void scanJarManifestForClassPathEntries(LinkedList<WorkListItem> workList, ICodeBase codeBase) throws IOException { try { // See if this codebase has a jar manifest ICodeBaseEntry manifestEntry = codeBase.lookupResource("META-INF/MANIFEST.MF"); // Try to read the manifest InputStream in = null; try { in = manifestEntry.openResource(); Manifest manifest = new Manifest(in); Attributes mainAttrs = manifest.getMainAttributes(); String classPath = mainAttrs.getValue("Class-Path"); if (classPath != null) { String[] pathList = classPath.split("\\s+"); for (String path : pathList) { // Create a codebase locator for the classpath entry // relative to the codebase in which we discovered the Jar // manifest ICodeBaseLocator relativeCodeBaseLocator = codeBase.getCodeBaseLocator().createRelativeCodeBaseLocator(path); // Codebases found in Class-Path entries are always // added to the aux classpath, not the application. addToWorkList(workList, new WorkListItem(relativeCodeBaseLocator, false, ICodeBase.IN_JAR_MANIFEST)); } } } finally { if (in != null) { IO.close(in); } } } catch (ResourceNotFoundException e) { // Do nothing - no Jar manifest found } } /** * Add a worklist item to the worklist. * This method maintains the invariant that all of the worklist * items representing application codebases appear <em>before</em> * all of the worklist items representing auxiliary codebases. * * @param projectWorkList the worklist * @param itemToAdd the worklist item to add */ private void addToWorkList(LinkedList<WorkListItem> workList, WorkListItem itemToAdd) { if (DEBUG) { new RuntimeException("Adding work list item " + itemToAdd).printStackTrace(System.out); } if (!itemToAdd.isAppCodeBase()) { // Auxiliary codebases are always added at the end workList.addLast(itemToAdd); return; } // Adding an application codebase: position a ListIterator // just before first auxiliary codebase (or at the end of the list // if there are no auxiliary codebases) ListIterator<WorkListItem> i = workList.listIterator(); while (i.hasNext()) { WorkListItem listItem = i.next(); if (!listItem.isAppCodeBase()) { i.previous(); break; } } // Add the codebase to the worklist i.add(itemToAdd); } /* (non-Javadoc) * @see edu.umd.cs.findbugs.classfile.IClassPathBuilder#getAppClassList() */ public List<ClassDescriptor> getAppClassList() { return appClassList; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -