📄 project.java
字号:
URL url = workList.createURL(fileName); WorkListItem item = new WorkListItem(url); workList.add(item); } catch (MalformedURLException ignore) { // Ignore } } // Scan recursively. while (!workList.isEmpty()) { WorkListItem item = workList.getNextItem(); processComponentJar(item.getURL(), workList, implicitClasspath); } return implicitClasspath; } /** * Examine the manifest of a single zip/jar file for implicit * classapth entries. * * @param jarFileURL URL of the zip/jar file * @param workList worklist of zip/jar files to examine * @param implicitClasspath list of implicit classpath entries found */ private void processComponentJar(URL jarFileURL, WorkList workList, List<String> implicitClasspath) { if (DEBUG) System.out.println("Processing " + jarFileURL.toString()); if (!jarFileURL.toString().endsWith(".zip") && !jarFileURL.toString().endsWith(".jar")) return; try { URL manifestURL = new URL("jar:" + jarFileURL.toString() + "!/META-INF/MANIFEST.MF"); InputStream in = null; try { in = manifestURL.openStream(); Manifest manifest = new Manifest(in); Attributes mainAttrs = manifest.getMainAttributes(); String classPath = mainAttrs.getValue("Class-Path"); if (classPath != null) { String[] fileList = classPath.split("\\s+"); for (int i = 0; i < fileList.length; ++i) { String jarFile = fileList[i]; URL referencedURL = workList.createRelativeURL(jarFileURL, jarFile); if (workList.add(new WorkListItem(referencedURL))) { implicitClasspath.add(referencedURL.toString()); if (DEBUG) System.out.println("Implicit jar: " + referencedURL.toString()); } } } } finally { if (in != null) { in.close(); } } } catch (IOException ignore) { // Ignore } } private static final String OPTIONS_KEY = "[Options]"; private static final String JAR_FILES_KEY = "[Jar files]"; private static final String SRC_DIRS_KEY = "[Source dirs]"; private static final String AUX_CLASSPATH_ENTRIES_KEY = "[Aux classpath entries]"; // Option keys public static final String RELATIVE_PATHS = "relative_paths"; /** * Save the project to an output file. * * @param outputFile name of output file * @param useRelativePaths true if the project should be written * using only relative paths * @param relativeBase if useRelativePaths is true, * this file is taken as the base directory in terms of which * all files should be made relative * @throws IOException if an error occurs while writing */ public void write(String outputFile, boolean useRelativePaths, String relativeBase) throws IOException { PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(outputFile))); try { writer.println(JAR_FILES_KEY); for (Iterator<String> i = fileList.iterator(); i.hasNext();) { String jarFile = i.next(); if (useRelativePaths) jarFile = convertToRelative(jarFile, relativeBase); writer.println(jarFile); } writer.println(SRC_DIRS_KEY); for (Iterator<String> i = srcDirList.iterator(); i.hasNext();) { String srcDir = i.next(); if (useRelativePaths) srcDir = convertToRelative(srcDir, relativeBase); writer.println(srcDir); } writer.println(AUX_CLASSPATH_ENTRIES_KEY); for (Iterator<String> i = auxClasspathEntryList.iterator(); i.hasNext();) { String auxClasspathEntry = i.next(); if (useRelativePaths) auxClasspathEntry = convertToRelative(auxClasspathEntry, relativeBase); writer.println(auxClasspathEntry); } if (useRelativePaths) { writer.println(OPTIONS_KEY); writer.println(RELATIVE_PATHS + "=true"); } } finally { writer.close(); } // Project successfully saved isModified = false; } /** * Read the project from an input file. * This method should only be used on an empty Project * (created with the default constructor). * * @param inputFile name of the input file to read the project from * @throws IOException if an error occurs while reading */ public void read(String inputFile) throws IOException { if (isModified) throw new IllegalStateException("Reading into a modified Project!"); // Make the input file absolute, if necessary File file = new File(inputFile); if (!file.isAbsolute()) inputFile = file.getAbsolutePath(); // Store the project filename setProjectFileName(inputFile); BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(inputFile)); String line; line = getLine(reader); if (line == null || !line.equals(JAR_FILES_KEY)) throw new IOException("Bad format: missing jar files key"); while ((line = getLine(reader)) != null && !line.equals(SRC_DIRS_KEY)) { addToListInternal(fileList, line); } if (line == null) throw new IOException("Bad format: missing source dirs key"); while ((line = getLine(reader)) != null && !line.equals(AUX_CLASSPATH_ENTRIES_KEY)) { addToListInternal(srcDirList, line); } // The list of aux classpath entries is optional if (line != null) { while ((line = getLine(reader)) != null) { if (line.equals(OPTIONS_KEY)) break; addToListInternal(auxClasspathEntryList, line); } } // The Options section is also optional if (line != null && line.equals(OPTIONS_KEY)) { while ((line = getLine(reader)) != null && !line.equals(JAR_FILES_KEY)) parseOption(line); } // If this project has the relative paths option set, // resolve all internal relative paths into absolute // paths, using the absolute path of the project // file as a base directory. if (getOption(RELATIVE_PATHS)) { makeListAbsoluteProject(fileList); makeListAbsoluteProject(srcDirList); makeListAbsoluteProject(auxClasspathEntryList); } // Clear the modification flag set by the various "add" methods. isModified = false; } finally { if (reader != null) reader.close(); } } /** * Read a line from a BufferedReader, ignoring blank lines * and comments. */ private static String getLine(BufferedReader reader) throws IOException { String line; while ((line = reader.readLine()) != null) { line = line.trim(); if (!line.equals("") && !line.startsWith("#")) break; } return line; } /** * Convert to a string in a nice (displayable) format. */ public String toString() { String name = projectFileName; int lastSep = name.lastIndexOf(File.separatorChar); if (lastSep >= 0) name = name.substring(lastSep + 1); int dot = name.lastIndexOf('.'); if (dot >= 0) name = name.substring(0, dot); return name; } /** * Transform a user-entered filename into a proper filename, * by adding the ".fb" file extension if it isn't already present. */ public static String transformFilename(String fileName) { if (!fileName.endsWith(".fb")) fileName = fileName + ".fb"; return fileName; } private static final String JAR_ELEMENT_NAME = "Jar"; private static final String AUX_CLASSPATH_ENTRY_ELEMENT_NAME = "AuxClasspathEntry"; private static final String SRC_DIR_ELEMENT_NAME = "SrcDir"; private static final String FILENAME_ATTRIBUTE_NAME = "filename"; public void writeXML(XMLOutput xmlOutput) throws IOException { xmlOutput.openTag(BugCollection.PROJECT_ELEMENT_NAME); XMLOutputUtil.writeElementList(xmlOutput, JAR_ELEMENT_NAME, fileList); XMLOutputUtil.writeElementList(xmlOutput, AUX_CLASSPATH_ENTRY_ELEMENT_NAME, auxClasspathEntryList); XMLOutputUtil.writeElementList(xmlOutput, SRC_DIR_ELEMENT_NAME, srcDirList); xmlOutput.closeTag(BugCollection.PROJECT_ELEMENT_NAME); } /** * Parse one line in the [Options] section. * * @param option one line in the [Options] section */ private void parseOption(String option) throws IOException { int equalPos = option.indexOf("="); if (equalPos < 0) throw new IOException("Bad format: invalid option format"); String name = option.substring(0, equalPos); String value = option.substring(equalPos + 1); optionsMap.put(name, Boolean.valueOf(value)); } /** * Hack for whether files are case insensitive. * For now, we'll assume that Windows is the only * case insensitive OS. (OpenVMS users, * feel free to submit a patch :-) */ private static final boolean FILE_IGNORE_CASE = System.getProperty("os.name", "unknown").startsWith("Windows"); /** * Converts a full path to a relative path if possible * * @param srcFile path to convert * @return the converted filename */ private String convertToRelative(String srcFile, String base) { String slash = System.getProperty("file.separator"); if (FILE_IGNORE_CASE) { srcFile = srcFile.toLowerCase(); base = base.toLowerCase(); } if (base.equals(srcFile)) return "."; if (!base.endsWith(slash)) base = base + slash; if (base.length() <= srcFile.length()) { String root = srcFile.substring(0, base.length()); if (root.equals(base)) { // Strip off the base directory, make relative return "." + System.getProperty("file.separator") + srcFile.substring(base.length()); } } //See if we can build a relative path above the base using .. notation int slashPos = srcFile.indexOf(slash); int branchPoint; if (slashPos >= 0) { String subPath = srcFile.substring(0, slashPos); if ((subPath.length() == 0) || base.startsWith(subPath)) { branchPoint = slashPos + 1; slashPos = srcFile.indexOf(slash, branchPoint); while (slashPos >= 0) { subPath = srcFile.substring(0, slashPos); if (base.startsWith(subPath)) branchPoint = slashPos + 1; else break; slashPos = srcFile.indexOf(slash, branchPoint); } int slashCount = 0; slashPos = base.indexOf(slash, branchPoint); while (slashPos >= 0) { slashCount++; slashPos = base.indexOf(slash, slashPos + 1); } StringBuffer path = new StringBuffer(); String upDir = ".." + slash; for (int i = 0; i < slashCount; i++) path.append(upDir); path.append(srcFile.substring(branchPoint)); return path.toString(); } } return srcFile; } /** * Converts a relative path to an absolute path if possible. * * @param fileName path to convert * @return the converted filename */ private String convertToAbsolute(String fileName) throws IOException { // At present relative paths are only calculated if the fileName is // below the project file. This need not be the case, and we could use .. // syntax to move up the tree. (To Be Added) File file = new File(fileName); if (!file.isAbsolute()) { // Only try to make the relative path absolute // if the project file is absolute. File projectFile = new File(projectFileName); if (projectFile.isAbsolute()) { // Get base directory (parent of the project file) String base = new File(projectFileName).getParent(); // Make the file absolute in terms of the parent directory fileName = new File(base, fileName).getCanonicalPath(); } } return fileName; } /** * Make the given filename absolute relative to the * current working directory. */ private static String makeAbsoluteCWD(String fileName) { File file = new File(fileName); boolean hasProtocol = (FindBugs.getURLProtocol(fileName) != null); if (!hasProtocol && !file.isAbsolute()) fileName = file.getAbsolutePath(); return fileName; } /** * Add a value to given list, making the Project modified * if the value is not already present in the list. * * @param list the list * @param value the value to be added * @return true if the value was not already present in the list, * false otherwise */ private boolean addToListInternal(List<String> list, String value) { if (!list.contains(value)) { list.add(value); isModified = true; return true; } else return false; } /** * Make the given list of pathnames absolute relative * to the absolute path of the project file. */ private void makeListAbsoluteProject(List<String> list) throws IOException { List<String> replace = new LinkedList<String>(); for (Iterator<String> i = list.iterator(); i.hasNext();) { String fileName = i.next(); fileName = convertToAbsolute(fileName); replace.add(fileName); } list.clear(); list.addAll(replace); }}// vim:ts=4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -