📄 symlink.java
字号:
* Set overwrite mode. If set to false (default) * the task will not overwrite existing links, and may stop the build * if a link already exists depending on the setting of failonerror. * * @param owrite If true overwrite existing links. */ public void setOverwrite(boolean owrite) { this.overwrite = owrite; } /** * Set failonerror mode. If set to true (default) the entire build fails * upon error; otherwise the error is logged and the build will continue. * * @param foe If true throw BuildException on error, else log it. */ public void setFailOnError(boolean foe) { this.failonerror = foe; } /** * Set the action to be performed. May be "single", * "delete", "recreate" or "record". * * @param action The action to perform. */ public void setAction(String action) { super.setAction(action); } /** * Set the name of the link. Used when action = "single". * * @param lnk The name for the link. */ public void setLink(String lnk) { this.link = lnk; } /** * Set the name of the resource to which a link should be created. * Used when action = "single". * * @param src The resource to be linked. */ public void setResource(String src) { this.resource = src; } /** * Set the name of the file to which links will be written. * Used when action = "record". * * @param lf The name of the file to write links to. */ public void setLinkfilename(String lf) { this.linkFileName = lf; } /** * Add a fileset to this task. * * @param set The fileset to add. */ public void addFileset(FileSet set) { fileSets.addElement(set); } /** * Delete a symlink (without deleting the associated resource). * * <p>This is a convenience method that simply invokes * <code>deleteSymlink(java.io.File)</code>. * * @param path A string containing the path of the symlink to delete. * * @throws FileNotFoundException When the path results in a * <code>File</code> that doesn't exist. * @throws IOException If calls to <code>File.rename</code> * or <code>File.delete</code> fail. */ public static void deleteSymlink(String path) throws IOException, FileNotFoundException { deleteSymlink(new File(path)); } /** * Delete a symlink (without deleting the associated resource). * * <p>This is a utility method that removes a unix symlink without removing * the resource that the symlink points to. If it is accidentally invoked * on a real file, the real file will not be harmed, but an exception * will be thrown when the deletion is attempted. This method works by * getting the canonical path of the link, using the canonical path to * rename the resource (breaking the link) and then deleting the link. * The resource is then returned to its original name inside a finally * block to ensure that the resource is unharmed even in the event of * an exception. * * @param linkfil A <code>File</code> object of the symlink to delete. * * @throws FileNotFoundException When the path results in a * <code>File</code> that doesn't exist. * @throws IOException If calls to <code>File.rename</code>, * <code>File.delete</code> or * <code>File.getCanonicalPath</code> * fail. */ public static void deleteSymlink(File linkfil) throws IOException, FileNotFoundException { if (!linkfil.exists()) { throw new FileNotFoundException("No such symlink: " + linkfil); } // find the resource of the existing link: File canfil = linkfil.getCanonicalFile(); // rename the resource, thus breaking the link: File temp = FILE_UTILS.createTempFile("symlink", ".tmp", canfil.getParentFile(), false, true); try { try { FILE_UTILS.rename(canfil, temp); } catch (IOException e) { throw new IOException( "Couldn't rename resource when attempting to delete " + linkfil); } // delete the (now) broken link: if (!linkfil.delete()) { throw new IOException("Couldn't delete symlink: " + linkfil + " (was it a real file? is this not a UNIX system?)"); } } finally { // return the resource to its original name: try { FILE_UTILS.rename(temp, canfil); } catch (IOException e) { throw new IOException("Couldn't return resource " + temp + " to its original name: " + canfil.getAbsolutePath() + "\n THE RESOURCE'S NAME ON DISK HAS " + "BEEN CHANGED BY THIS ERROR!\n"); } } } /** * Write a properties file. This method uses <code>Properties.store</code> * and thus may throw exceptions that occur while writing the file. * * @param properties The properties object to be written. * @param dir The directory for which we are writing the links. */ private void writePropertyFile(Properties properties, File dir) throws BuildException { BufferedOutputStream bos = null; try { bos = new BufferedOutputStream( new FileOutputStream(new File(dir, linkFileName))); properties.store(bos, "Symlinks from " + dir); } catch (IOException ioe) { throw new BuildException(ioe, getLocation()); } finally { FileUtils.close(bos); } } /** * Handle errors based on the setting of failonerror. * * @param msg The message to log, or include in the * <code>BuildException</code>. */ private void handleError(String msg) { if (failonerror) { throw new BuildException(msg); } log(msg); } /** * Conduct the actual construction of a link. * * <p> The link is constructed by calling <code>Execute.runCommand</code>. * * @param res The path of the resource we are linking to. * @param lnk The name of the link we wish to make. */ private void doLink(String res, String lnk) throws BuildException { File linkfil = new File(lnk); if (overwrite && linkfil.exists()) { try { deleteSymlink(linkfil); } catch (FileNotFoundException fnfe) { handleError("Symlink disappeared before it was deleted: " + lnk); } catch (IOException ioe) { handleError("Unable to overwrite preexisting link: " + lnk); } } String[] cmd = new String[] {"ln", "-s", res, lnk}; log(Commandline.toString(cmd)); Execute.runCommand(this, cmd); } /** * Find all the links in all supplied filesets. * * <p> This method is invoked when the action attribute is * "record". This means that filesets are interpreted * as the directories in which links may be found. * * @param v The filesets specified by the user. * @return A HashSet of <code>File</code> objects containing the * links (with canonical parent directories). */ private HashSet findLinks(Vector v) { HashSet result = new HashSet(); for (int i = 0; i < v.size(); i++) { FileSet fs = (FileSet) v.get(i); DirectoryScanner ds = fs.getDirectoryScanner(getProject()); String[][] fnd = new String[][] {ds.getIncludedFiles(), ds.getIncludedDirectories()}; File dir = fs.getDir(getProject()); for (int j = 0; j < fnd.length; j++) { for (int k = 0; k < fnd[j].length; k++) { try { File f = new File(dir, fnd[j][k]); File pf = f.getParentFile(); String name = f.getName(); if (FILE_UTILS.isSymbolicLink(pf, name)) { result.add(new File(pf.getCanonicalFile(), name)); } } catch (IOException e) { handleError("IOException: " + fnd[j][k] + " omitted"); } } } } return result; } /** * Load links from properties files included in one or more FileSets. * * <p> This method is only invoked when the action attribute is set to * "recreate". The filesets passed in are assumed to specify the * names of the property files with the link information and the * subdirectories in which to look for them. * * @param v The <code>FileSet</code>s for this task. * @return The links to be made. */ private Properties loadLinks(Vector v) { Properties finalList = new Properties(); // loop through the supplied file sets: for (int i = 0; i < v.size(); i++) { FileSet fs = (FileSet) v.elementAt(i); DirectoryScanner ds = new DirectoryScanner(); fs.setupDirectoryScanner(ds, getProject()); ds.setFollowSymlinks(false); ds.scan(); String[] incs = ds.getIncludedFiles(); File dir = fs.getDir(getProject()); // load included files as properties files: for (int j = 0; j < incs.length; j++) { File inc = new File(dir, incs[j]); File pf = inc.getParentFile(); Properties lnks = new Properties(); try { lnks.load(new BufferedInputStream(new FileInputStream(inc))); pf = pf.getCanonicalFile(); } catch (FileNotFoundException fnfe) { handleError("Unable to find " + incs[j] + "; skipping it."); continue; } catch (IOException ioe) { handleError("Unable to open " + incs[j] + " or its parent dir; skipping it."); continue; } lnks.list(new PrintStream( new LogOutputStream(this, Project.MSG_INFO))); // Write the contents to our master list of links // This method assumes that all links are defined in // terms of absolute paths, or paths relative to the // working directory: for (Iterator kitr = lnks.keySet().iterator(); kitr.hasNext();) { String key = (String) kitr.next(); finalList.put(new File(pf, key).getAbsolutePath(), lnks.getProperty(key)); } } } return finalList; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -