Browse Source

Some javadoc and lots of spelling corrections.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277529 13f79535-47bb-0310-9956-ffa450edef68
master
Matthew Jason Benson 20 years ago
parent
commit
1063983a41
1 changed files with 53 additions and 93 deletions
  1. +53
    -93
      src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java

+ 53
- 93
src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java View File

@@ -16,7 +16,7 @@
*/ */


/* /*
* Since the initial version of this file was deveolped on the clock on
* Since the initial version of this file was developed on the clock on
* an NSF grant I should say the following boilerplate: * an NSF grant I should say the following boilerplate:
* *
* This material is based upon work supported by the National Science * This material is based upon work supported by the National Science
@@ -52,10 +52,10 @@ import org.apache.tools.ant.taskdefs.Execute;
/** /**
* Creates, Records and Restores Symlinks. * Creates, Records and Restores Symlinks.
* *
* <p> This task performs several related operations. In the most trivial,
* and default usage, it creates a link specified in the link atribute to
* a resource specified in the resource atribute. The second usage of this
* task is to traverses a directory structure specified by a fileset,
* <p> This task performs several related operations. In the most trivial
* and default usage, it creates a link specified in the link attribute to
* a resource specified in the resource attribute. The second usage of this
* task is to traverse a directory structure specified by a fileset,
* and write a properties file in each included directory describing the * and write a properties file in each included directory describing the
* links found in that directory. The third usage is to traverse a * links found in that directory. The third usage is to traverse a
* directory structure specified by a fileset, looking for properties files * directory structure specified by a fileset, looking for properties files
@@ -92,10 +92,10 @@ import org.apache.tools.ant.taskdefs.Execute;
* </pre> * </pre>
* *
* <p><strong>LIMITATIONS:</strong> Because Java has no direct support for * <p><strong>LIMITATIONS:</strong> Because Java has no direct support for
* handling symlinks this task divines them by comparing canoniacal and
* handling symlinks this task divines them by comparing canonical and
* absolute paths. On non-unix systems this may cause false positives. * absolute paths. On non-unix systems this may cause false positives.
* Furthermore, any operating system on which the command * Furthermore, any operating system on which the command
* <code>ln -s link resource</code> is not a valid command on the comandline
* <code>ln -s link resource</code> is not a valid command on the command line
* will not be able to use action= "delete", action="single" or * will not be able to use action= "delete", action="single" or
* action="recreate", but action="record" should still work. Finally, the * action="recreate", but action="record" should still work. Finally, the
* lack of support for symlinks in Java means that all links are recorded * lack of support for symlinks in Java means that all links are recorded
@@ -109,7 +109,7 @@ import org.apache.tools.ant.taskdefs.Execute;


public class Symlink extends Task { public class Symlink extends Task {


// Atributes with setter methods
// Attributes with setter methods:
private String resource; private String resource;
private String link; private String link;
private String action; private String action;
@@ -119,19 +119,21 @@ public class Symlink extends Task {
private boolean failonerror; private boolean failonerror;


private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
/** Initialize the task. */ /** Initialize the task. */


public void init() throws BuildException { public void init() throws BuildException {
super.init(); super.init();
failonerror = true; // default behavior is to fail on an error failonerror = true; // default behavior is to fail on an error
overwrite = false; // devault behavior is to not overwrite
overwrite = false; // default behavior is to not overwrite
action = "single"; // default behavior is make a single link action = "single"; // default behavior is make a single link
fileSets = new Vector(); fileSets = new Vector();
} }


/** The standard method for executing any task. */

/**
* The standard method for executing any task.
* @throws BuildException on error.
*/
public void execute() throws BuildException { public void execute() throws BuildException {
try { try {
if (action.equals("single")) { if (action.equals("single")) {
@@ -154,7 +156,6 @@ public class Symlink extends Task {
+ "required for action recreate"); + "required for action recreate");
return; return;
} }

listOfLinks = loadLinks(fileSets); listOfLinks = loadLinks(fileSets);


keys = listOfLinks.keys(); keys = listOfLinks.keys();
@@ -188,17 +189,15 @@ public class Symlink extends Task {
Enumeration links, dirs; Enumeration links, dirs;


if (fileSets.size() == 0) { if (fileSets.size() == 0) {
handleError("File set identifying links to "
handleError("Fileset identifying links to "
+ "record required"); + "record required");
return; return;
} }

if (linkFileName == null) { if (linkFileName == null) {
handleError("Name of file to record links in " handleError("Name of file to record links in "
+ "required"); + "required");
return; return;
} }

// fill our vector with file objects representing // fill our vector with file objects representing
// links (canonical) // links (canonical)
vectOfLinks = findLinks(fileSets); vectOfLinks = findLinks(fileSets);
@@ -215,7 +214,6 @@ public class Symlink extends Task {
((Vector) byDir.get(parent)).addElement(thisLink); ((Vector) byDir.get(parent)).addElement(thisLink);
} }
} }

// write a Properties file in each directory // write a Properties file in each directory
dirs = byDir.keys(); dirs = byDir.keys();
while (dirs.hasMoreElements()) { while (dirs.hasMoreElements()) {
@@ -237,8 +235,6 @@ public class Symlink extends Task {
+ "name of a parent link"); + "name of a parent link");
} }
} }


// Get a place to record what we are about to write // Get a place to record what we are about to write
writeTo = new File(dir + File.separator writeTo = new File(dir + File.separator
+ linkFileName); + linkFileName);
@@ -263,11 +259,11 @@ public class Symlink extends Task {
} }


/* ********************************************************** * /* ********************************************************** *
* Begin Atribute Setter Methods *
* Begin Attribute Setter Methods *
* ********************************************************** */ * ********************************************************** */


/** /**
* The setter for the overwrite atribute. If set to false (default)
* The setter for the overwrite attribute. If set to false (default)
* the task will not overwrite existing links, and may stop the build * the task will not overwrite existing links, and may stop the build
* if a link already exists depending on the setting of failonerror. * if a link already exists depending on the setting of failonerror.
* *
@@ -278,22 +274,21 @@ public class Symlink extends Task {
} }


/** /**
* The setter for the failonerror atribute. If set to true (default)
* The setter for the failonerror attribute. If set to true (default)
* the entire build fails upon error. If set to false, the error is * the entire build fails upon error. If set to false, the error is
* logged and the build will continue. * logged and the build will continue.
* *
* @param foe If true throw build exception on error else log it.
* @param foe If true throw BuildException on error else log it.
*/ */
public void setFailOnError(boolean foe) { public void setFailOnError(boolean foe) {
this.failonerror = foe; this.failonerror = foe;
} }



/** /**
* The setter for the "action" attribute. May be "single" "multi"
* The setter for the "action" attribute. May be "single", "multi"
* or "record" * or "record"
* *
* @param typ The action of action to perform
* @param typ The action of action to perform.
*/ */
public void setAction(String typ) { public void setAction(String typ) {
this.action = typ; this.action = typ;
@@ -302,7 +297,7 @@ public class Symlink extends Task {
/** /**
* The setter for the "link" attribute. Only used for action = single. * The setter for the "link" attribute. Only used for action = single.
* *
* @param lnk The name for the link
* @param lnk The name for the link.
*/ */
public void setLink(String lnk) { public void setLink(String lnk) {
this.link = lnk; this.link = lnk;
@@ -336,32 +331,29 @@ public class Symlink extends Task {
} }


/* ********************************************************** * /* ********************************************************** *
* Begin Public Utility Methods *
* Begin Public Utility Methods *
* ********************************************************** */ * ********************************************************** */


/** /**
* Deletes a symlink without deleteing the resource it points to. * Deletes a symlink without deleteing the resource it points to.
* *
* <p>This is a convenience method that simply invokes * <p>This is a convenience method that simply invokes
* <code>deleteSymlink(java.io.File)</code>
* <code>deleteSymlink(java.io.File)</code>.
* *
* @param path A string containing the path of the symlink to delete
* @param path A string containing the path of the symlink to delete.
* *
* @throws FileNotFoundException When the path results in a * @throws FileNotFoundException When the path results in a
* <code>File</code> that doesn't exist. * <code>File</code> that doesn't exist.
* @throws IOException If calls to <code>File.rename</code> * @throws IOException If calls to <code>File.rename</code>
* or <code>File.delete</code> fail. * or <code>File.delete</code> fail.
*/ */

public static void deleteSymlink(String path) public static void deleteSymlink(String path)
throws IOException, FileNotFoundException { throws IOException, FileNotFoundException {

File linkfil = new File(path);
deleteSymlink(linkfil);
deleteSymlink(new File(path));
} }


/** /**
* Deletes a symlink without deleteing the resource it points to.
* Deletes a symlink without deleting the resource it points to.
* *
* <p>This is a utility method that removes a unix symlink without removing * <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 * the resource that the symlink points to. If it is accidentally invoked
@@ -369,11 +361,11 @@ public class Symlink extends Task {
* will be thrown when the deletion is attempted. This method works by * will be thrown when the deletion is attempted. This method works by
* getting the canonical path of the link, using the canonical path to * getting the canonical path of the link, using the canonical path to
* rename the resource (breaking the link) and then deleting the link. * rename the resource (breaking the link) and then deleting the link.
* The resource is then returned to it's original name inside a finally
* 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 * block to ensure that the resource is unharmed even in the event of
* an exception. * an exception.
* *
* @param linkfil A <code>File</code> object of the symlink to delete
* @param linkfil A <code>File</code> object of the symlink to delete.
* *
* @throws FileNotFoundException When the path results in a * @throws FileNotFoundException When the path results in a
* <code>File</code> that doesn't exist. * <code>File</code> that doesn't exist.
@@ -389,12 +381,11 @@ public class Symlink extends Task {
if (!linkfil.exists()) { if (!linkfil.exists()) {
throw new FileNotFoundException("No such symlink: " + linkfil); throw new FileNotFoundException("No such symlink: " + linkfil);
} }

// find the resource of the existing link
// find the resource of the existing link:
String canstr = linkfil.getCanonicalPath(); String canstr = linkfil.getCanonicalPath();
File canfil = new File(canstr); File canfil = new File(canstr);


// rename the resource, thus breaking the link
// rename the resource, thus breaking the link:
String parentStr = canfil.getParent(); String parentStr = canfil.getParent();
File parentDir = new File(parentStr); File parentDir = new File(parentStr);


@@ -407,15 +398,14 @@ public class Symlink extends Task {
throw new IOException("Couldn't rename resource when " throw new IOException("Couldn't rename resource when "
+ "attempting to delete " + linkfil); + "attempting to delete " + linkfil);
} }

// delete the (now) broken link
// delete the (now) broken link:
if (!linkfil.delete()) { if (!linkfil.delete()) {
throw new IOException("Couldn't delete symlink: " + linkfil throw new IOException("Couldn't delete symlink: " + linkfil
+ " (was it a real file? is this not a " + " (was it a real file? is this not a "
+ "UNIX system?)"); + "UNIX system?)");
} }
} finally { } finally {
// return the resource to its original name.
// return the resource to its original name:
try { try {
FILE_UTILS.rename(temp, canfil); FILE_UTILS.rename(temp, canfil);
} catch (IOException e) { } catch (IOException e) {
@@ -427,9 +417,8 @@ public class Symlink extends Task {
} }
} }



/* ********************************************************** * /* ********************************************************** *
* Begin Private Methods *
* Begin Private Methods *
* ********************************************************** */ * ********************************************************** */


/** /**
@@ -438,7 +427,7 @@ public class Symlink extends Task {
* This method use <code>Properties.store</code> * This method use <code>Properties.store</code>
* and thus report exceptions that occur while writing the file. * and thus report exceptions that occur while writing the file.
* *
* This is not jdk 1.1 compatible, but ant 1.6 is not anymore.
* This is not jdk 1.1 compatible, but Ant 1.6 is not anymore.
* *
* @param properties The properties object to be written. * @param properties The properties object to be written.
* @param propertyfile The File to write to. * @param propertyfile The File to write to.
@@ -458,13 +447,7 @@ public class Symlink extends Task {
} catch (IOException ioe) { } catch (IOException ioe) {
throw new BuildException(ioe, getLocation()); throw new BuildException(ioe, getLocation());
} finally { } finally {
if (fos != null) {
try {
fos.close();
} catch (IOException ioex) {
log("Failed to close output stream");
}
}
FILE_UTILS.close(fos);
} }
} }


@@ -472,25 +455,22 @@ public class Symlink extends Task {
* Handles errors correctly based on the setting of failonerror. * Handles errors correctly based on the setting of failonerror.
* *
* @param msg The message to log, or include in the * @param msg The message to log, or include in the
* <code>BuildException</code>
* <code>BuildException</code>.
*/ */

private void handleError(String msg) { private void handleError(String msg) {
if (failonerror) { if (failonerror) {
throw new BuildException(msg); throw new BuildException(msg);
} else {
log(msg);
} }
log(msg);
} }



/** /**
* Conducts the actual construction of a link. * Conducts the actual construction of a link.
* *
* <p> The link is constructed by calling <code>Execute.runCommand</code>. * <p> The link is constructed by calling <code>Execute.runCommand</code>.
* *
* @param resource The path of the resource we are linking to. * @param resource The path of the resource we are linking to.
* @param link The name of the link we wish to make
* @param link The name of the link we wish to make.
*/ */


private void doLink(String resource, String link) throws BuildException { private void doLink(String resource, String link) throws BuildException {
@@ -500,34 +480,26 @@ public class Symlink extends Task {
return; return;
} }
if (link == null) { if (link == null) {
handleError("Must define the link "
+ "name for symlink!");
handleError("Must define the link name for symlink!");
return; return;
} }

File linkfil = new File(link); File linkfil = new File(link);


String[] cmd = new String[4];
cmd[0] = "ln";
cmd[1] = "-s";
cmd[2] = resource;
cmd[3] = link;
String[] cmd = new String[] {"ln", "-s", resource, link};


try { try {
if (overwrite && linkfil.exists()) { if (overwrite && linkfil.exists()) {
deleteSymlink(linkfil); deleteSymlink(linkfil);
} }
} catch (FileNotFoundException fnfe) { } catch (FileNotFoundException fnfe) {
handleError("Symlink dissapeared before it was deleted:" + link);
handleError("Symlink disappeared before it was deleted: " + link);
} catch (IOException ioe) { } catch (IOException ioe) {
handleError("Unable to overwrite preexisting link " + link);
handleError("Unable to overwrite preexisting link: " + link);
} }

log(cmd[0] + " " + cmd[1] + " " + cmd[2] + " " + cmd[3]); log(cmd[0] + " " + cmd[1] + " " + cmd[2] + " " + cmd[3]);
Execute.runCommand(this, cmd); Execute.runCommand(this, cmd);
} }



/** /**
* Simultaneously get included directories and included files. * Simultaneously get included directories and included files.
* *
@@ -535,7 +507,6 @@ public class Symlink extends Task {
* @return A vector of <code>String</code> objects containing the * @return A vector of <code>String</code> objects containing the
* included file names and directory names. * included file names and directory names.
*/ */

private Vector scanDirsAndFiles(DirectoryScanner ds) { private Vector scanDirsAndFiles(DirectoryScanner ds) {
String[] files, dirs; String[] files, dirs;
Vector list = new Vector(); Vector list = new Vector();
@@ -551,14 +522,13 @@ public class Symlink extends Task {
for (int i = 0; i < dirs.length; i++) { for (int i = 0; i < dirs.length; i++) {
list.addElement(dirs[i]); list.addElement(dirs[i]);
} }

return list; return list;
} }


/** /**
* Finds all the links in all supplied filesets. * Finds all the links in all supplied filesets.
* *
* <p> This method is invoked when the action atribute is is "record".
* <p> This method is invoked when the action attribute is is "record".
* This means that filesets are interpreted as the directories in * This means that filesets are interpreted as the directories in
* which links may be found. * which links may be found.
* *
@@ -576,13 +546,13 @@ public class Symlink extends Task {
* *
* @param fileSets The filesets specified by the user. * @param fileSets The filesets specified by the user.
* @return A vector of <code>File</code> objects containing the * @return A vector of <code>File</code> objects containing the
* links (with canonical parent directories)
* links (with canonical parent directories).
*/ */


private Vector findLinks(Vector fileSets) { private Vector findLinks(Vector fileSets) {
Vector result = new Vector(); Vector result = new Vector();


// loop through the supplied file sets
// loop through the supplied file sets:
FSLoop: for (int i = 0; i < fileSets.size(); i++) { FSLoop: for (int i = 0; i < fileSets.size(); i++) {
FileSet fsTemp = (FileSet) fileSets.elementAt(i); FileSet fsTemp = (FileSet) fileSets.elementAt(i);
String workingDir = null; String workingDir = null;
@@ -604,14 +574,12 @@ public class Symlink extends Task {
+ "fileset skipped"); + "fileset skipped");
continue FSLoop; continue FSLoop;
} }

// Get a vector of String with file names that match
// the pattern
// Get a vector of String with file names that match the pattern:
ds = fsTemp.getDirectoryScanner(this.getProject()); ds = fsTemp.getDirectoryScanner(this.getProject());
links = scanDirsAndFiles(ds); links = scanDirsAndFiles(ds);


// Now convert the strings to File Objects // Now convert the strings to File Objects
// using the canonical version of the working dir
// using the canonical version of the working dir:
enumLinks = links.elements(); enumLinks = links.elements();


while (enumLinks.hasMoreElements()) { while (enumLinks.hasMoreElements()) {
@@ -620,8 +588,7 @@ public class Symlink extends Task {
+ (String) enumLinks + (String) enumLinks
.nextElement())); .nextElement()));
} }

// Now loop through and remove the non-links
// Now loop through and remove the non-links:


enumLinks = linksFiles.elements(); enumLinks = linksFiles.elements();


@@ -645,13 +612,11 @@ public class Symlink extends Task {
// if failonerror = false, hence the warn and skip. // if failonerror = false, hence the warn and skip.
} }
} }

enumLinks = removals.elements(); enumLinks = removals.elements();


while (enumLinks.hasMoreElements()) { while (enumLinks.hasMoreElements()) {
linksFiles.removeElement(enumLinks.nextElement()); linksFiles.removeElement(enumLinks.nextElement());
} }

// Now we have what we want so add it to results, ensuring that // Now we have what we want so add it to results, ensuring that
// no link is returned twice and we have a canonical reference // no link is returned twice and we have a canonical reference
// to the link. (no symlinks in the parent dir) // to the link. (no symlinks in the parent dir)
@@ -671,11 +636,9 @@ public class Symlink extends Task {
handleError("IOException: " + next + " omitted"); handleError("IOException: " + next + " omitted");
} }
} }

// Note that these links are now specified with a full // Note that these links are now specified with a full
// canonical path irrespective of the working dir of the // canonical path irrespective of the working dir of the
// file set so it is ok to mix them in the same vector. // file set so it is ok to mix them in the same vector.

} }
return result; return result;
} }
@@ -683,14 +646,14 @@ public class Symlink extends Task {
/** /**
* Load the links from a properties file. * Load the links from a properties file.
* *
* <p> This method is only invoked when the action atribute is set to
* <p> This method is only invoked when the action attribute is set to
* "multi". The filesets passed in are assumed to specify the names * "multi". The filesets passed in are assumed to specify the names
* of the property files with the link information and the * of the property files with the link information and the
* subdirectories in which to look for them. * subdirectories in which to look for them.
* *
* <p> The basic method follwed here is, for each file set: * <p> The basic method follwed here is, for each file set:
* <ol> * <ol>
* <li> Get the canonical version of the dir atribute </li>
* <li> Get the canonical version of the dir attribute </li>
* <li> Scan for properties files </li> * <li> Scan for properties files </li>
* <li> load the contents of each properties file found. </li> * <li> load the contents of each properties file found. </li>
* </ol> * </ol>
@@ -698,14 +661,13 @@ public class Symlink extends Task {
* @param fileSets The <code>FileSet</code>s for this task * @param fileSets The <code>FileSet</code>s for this task
* @return The links to be made. * @return The links to be made.
*/ */

private Properties loadLinks(Vector fileSets) { private Properties loadLinks(Vector fileSets) {
Properties finalList = new Properties(); Properties finalList = new Properties();
Enumeration keys; Enumeration keys;
String key, value; String key, value;
String[] includedFiles; String[] includedFiles;


// loop through the supplied file sets
// loop through the supplied file sets:
FSLoop: for (int i = 0; i < fileSets.size(); i++) { FSLoop: for (int i = 0; i < fileSets.size(); i++) {
String workingDir; String workingDir;
FileSet fsTemp = (FileSet) fileSets.elementAt(i); FileSet fsTemp = (FileSet) fileSets.elementAt(i);
@@ -722,7 +684,6 @@ public class Symlink extends Task {
+ "task. FileSet skipped."); + "task. FileSet skipped.");
continue FSLoop; continue FSLoop;
} }

ds = fsTemp.getDirectoryScanner(this.getProject()); ds = fsTemp.getDirectoryScanner(this.getProject());
ds.setFollowSymlinks(false); ds.setFollowSymlinks(false);
ds.scan(); ds.scan();
@@ -746,11 +707,10 @@ public class Symlink extends Task {
continue FSLoop; continue FSLoop;
} catch (IOException ioe) { } catch (IOException ioe) {
handleError("Unable to open " + includedFiles[j] handleError("Unable to open " + includedFiles[j]
+ " or it's parent dir"
+ " or its parent dir"
+ "FileSet skipped."); + "FileSet skipped.");
continue FSLoop; continue FSLoop;
} }

keys = propTemp.keys(); keys = propTemp.keys();
propTemp.list(System.out); propTemp.list(System.out);
// Write the contents to our master list of links // Write the contents to our master list of links


Loading…
Cancel
Save