diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix')
4 files changed, 878 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/AbstractAccessTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/AbstractAccessTask.java new file mode 100644 index 00000000..d3385e6c --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/AbstractAccessTask.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* + * Since the initial version of this file was deveolped on the clock on + * an NSF grant I should say the following boilerplate: + * + * This material is based upon work supported by the National Science + * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and + * conclusions or recommendations expressed in this material are those + * of the author and do not necessarily reflect the views of the + * National Science Foundation. + */ + +package org.apache.tools.ant.taskdefs.optional.unix; + +import java.io.File; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.taskdefs.condition.Os; +import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.FileSet; + +/** + * @since Ant 1.6 + * + * @ant.task category="filesystem" + */ + +public abstract class AbstractAccessTask + extends org.apache.tools.ant.taskdefs.ExecuteOn { + + /** + * Chmod task for setting file and directory permissions. + */ + public AbstractAccessTask() { + super.setParallel(true); + super.setSkipEmptyFilesets(true); + } + + /** + * Set the file which should have its access attributes modified. + * @param src the file to modify + */ + public void setFile(File src) { + FileSet fs = new FileSet(); + fs.setFile(src); + addFileset(fs); + } + + /** + * Prevent the user from specifying a different command. + * + * @ant.attribute ignore="true" + * @param cmdl A user supplied command line that we won't accept. + */ + public void setCommand(Commandline cmdl) { + throw new BuildException(getTaskType() + + " doesn\'t support the command attribute", + getLocation()); + } + + /** + * Prevent the skipping of empty filesets + * + * @ant.attribute ignore="true" + * @param skip A user supplied boolean we won't accept. + */ + public void setSkipEmptyFilesets(boolean skip) { + throw new BuildException(getTaskType() + " doesn\'t support the " + + "skipemptyfileset attribute", + getLocation()); + } + + /** + * Prevent the use of the addsourcefile attribute. + * + * @ant.attribute ignore="true" + * @param b A user supplied boolean we won't accept. + */ + public void setAddsourcefile(boolean b) { + throw new BuildException(getTaskType() + + " doesn\'t support the addsourcefile attribute", getLocation()); + } + + /** + * Automatically approve Unix OS's. + * @return true if a valid OS, for unix this is always true, otherwise + * use the superclasses' test (user set). + */ + protected boolean isValidOs() { + return getOs() == null && getOsFamily() == null + ? Os.isFamily(Os.FAMILY_UNIX) : super.isValidOs(); + } +} diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chgrp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chgrp.java new file mode 100644 index 00000000..1279a2c8 --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chgrp.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* + * Since the initial version of this file was deveolped on the clock on + * an NSF grant I should say the following boilerplate: + * + * This material is based upon work supported by the National Science + * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and + * conclusions or recommendations expressed in this material are those + * of the author and do not necessarily reflect the views of the + * National Science Foundation. + */ + +package org.apache.tools.ant.taskdefs.optional.unix; + +import org.apache.tools.ant.BuildException; + +/** + * Chgrp equivalent for unix-like environments. + * + * @since Ant 1.6 + * + * @ant.task category="filesystem" + */ +public class Chgrp extends AbstractAccessTask { + + private boolean haveGroup = false; + + /** + * Chgrp task for setting unix group of a file. + */ + public Chgrp() { + super.setExecutable("chgrp"); + } + + /** + * Set the group attribute. + * + * @param group The new group for the file(s) or directory(ies) + */ + public void setGroup(String group) { + createArg().setValue(group); + haveGroup = true; + } + + /** + * Ensure that all the required arguments and other conditions have + * been set. + */ + protected void checkConfiguration() { + if (!haveGroup) { + throw new BuildException("Required attribute group not set in " + + "chgrp", getLocation()); + } + super.checkConfiguration(); + } + + /** + * We don't want to expose the executable attribute, so override it. + * + * @param e User supplied executable that we won't accept. + */ + public void setExecutable(String e) { + throw new BuildException(getTaskType() + + " doesn\'t support the executable" + + " attribute", getLocation()); + } +} diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chown.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chown.java new file mode 100644 index 00000000..53f72536 --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chown.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* + * Since the initial version of this file was deveolped on the clock on + * an NSF grant I should say the following boilerplate: + * + * This material is based upon work supported by the National Science + * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and + * conclusions or recommendations expressed in this material are those + * of the author and do not necessarily reflect the views of the + * National Science Foundation. + */ + +package org.apache.tools.ant.taskdefs.optional.unix; + +import org.apache.tools.ant.BuildException; + +/** + * Chown equivalent for unix-like environments. + * + * @since Ant 1.6 + * + * @ant.task category="filesystem" + */ +public class Chown extends AbstractAccessTask { + + private boolean haveOwner = false; + + /** + * Chown task for setting file and directory permissions. + */ + public Chown() { + super.setExecutable("chown"); + } + + /** + * Set the owner attribute. + * + * @param owner The new owner for the file(s) or directory(ies) + */ + public void setOwner(String owner) { + createArg().setValue(owner); + haveOwner = true; + } + + /** + * Ensure that all the required arguments and other conditions have + * been set. + */ + protected void checkConfiguration() { + if (!haveOwner) { + throw new BuildException("Required attribute owner not set in" + + " chown", getLocation()); + } + super.checkConfiguration(); + } + + /** + * We don't want to expose the executable attribute, so override it. + * + * @param e User supplied executable that we won't accept. + */ + public void setExecutable(String e) { + throw new BuildException(getTaskType() + + " doesn\'t support the executable" + + " attribute", getLocation()); + } +} diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java new file mode 100644 index 00000000..ad9aee8b --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java @@ -0,0 +1,600 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* + * Since the initial version of this file was developed on the clock on + * an NSF grant I should say the following boilerplate: + * + * This material is based upon work supported by the National Science + * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and + * conclusions or recommendations expressed in this material are those + * of the author and do not necessarily reflect the views of the + * National Science Foundation. + */ + +package org.apache.tools.ant.taskdefs.optional.unix; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Properties; +import java.util.Vector; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.dispatch.DispatchTask; +import org.apache.tools.ant.dispatch.DispatchUtils; +import org.apache.tools.ant.taskdefs.Execute; +import org.apache.tools.ant.taskdefs.LogOutputStream; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.util.FileUtils; +import org.apache.tools.ant.util.SymbolicLinkUtils; + +/** + * Creates, Deletes, 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 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 + * links found in that directory. The third usage is to traverse a + * directory structure specified by a fileset, looking for properties files + * (also specified as included in the fileset) and recreate the links + * that have been previously recorded for each directory. Finally, it can be + * used to remove a symlink without deleting the associated resource. + * + * <p> Usage examples: + * + * <p> Make a link named "foo" to a resource named + * "bar.foo" in subdir: + * <pre> + * <symlink link="${dir.top}/foo" resource="${dir.top}/subdir/bar.foo"/> + * </pre> + * + * <p> Record all links in subdir and its descendants in files named + * "dir.links": + * <pre> + * <symlink action="record" linkfilename="dir.links"> + * <fileset dir="${dir.top}" includes="subdir/**" /> + * </symlink> + * </pre> + * + * <p> Recreate the links recorded in the previous example: + * <pre> + * <symlink action="recreate"> + * <fileset dir="${dir.top}" includes="subdir/**/dir.links" /> + * </symlink> + * </pre> + * + * <p> Delete a link named "foo" to a resource named + * "bar.foo" in subdir: + * <pre> + * <symlink action="delete" link="${dir.top}/foo"/> + * </pre> + * + * <p><strong>LIMITATIONS:</strong> Because Java has no direct support for + * handling symlinks this task divines them by comparing canonical and + * absolute paths. On non-unix systems this may cause false positives. + * Furthermore, any operating system on which the command + * <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 action="recreate", but action="record" should still + * work. Finally, the lack of support for symlinks in Java means that all links + * are recorded as links to the <strong>canonical</strong> resource name. + * Therefore the link: <code>link --> subdir/dir/../foo.bar</code> will be + * recorded as <code>link=subdir/foo.bar</code> and restored as + * <code>link --> subdir/foo.bar</code>. + * + */ +public class Symlink extends DispatchTask { + private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); + private static final SymbolicLinkUtils SYMLINK_UTILS = + SymbolicLinkUtils.getSymbolicLinkUtils(); + + private String resource; + private String link; + private Vector fileSets = new Vector(); + private String linkFileName; + private boolean overwrite; + private boolean failonerror; + private boolean executing = false; + + /** + * Initialize the task. + * @throws BuildException on error. + */ + @Override + public void init() throws BuildException { + super.init(); + setDefaults(); + } + + /** + * The standard method for executing any task. + * @throws BuildException on error. + */ + @Override + public synchronized void execute() throws BuildException { + if (executing) { + throw new BuildException( + "Infinite recursion detected in Symlink.execute()"); + } + try { + executing = true; + DispatchUtils.execute(this); + } finally { + executing = false; + } + } + + /** + * Create a symlink. + * @throws BuildException on error. + * @since Ant 1.7 + */ + public void single() throws BuildException { + try { + if (resource == null) { + handleError("Must define the resource to symlink to!"); + return; + } + if (link == null) { + handleError("Must define the link name for symlink!"); + return; + } + doLink(resource, link); + } finally { + setDefaults(); + } + } + + /** + * Delete a symlink. + * @throws BuildException on error. + * @since Ant 1.7 + */ + public void delete() throws BuildException { + try { + if (link == null) { + handleError("Must define the link name for symlink!"); + return; + } + log("Removing symlink: " + link); + SYMLINK_UTILS.deleteSymbolicLink(FILE_UTILS + .resolveFile(new File("."), link), + this); + } catch (FileNotFoundException fnfe) { + handleError(fnfe.toString()); + } catch (IOException ioe) { + handleError(ioe.toString()); + } finally { + setDefaults(); + } + } + + /** + * Restore symlinks. + * @throws BuildException on error. + * @since Ant 1.7 + */ + public void recreate() throws BuildException { + try { + if (fileSets.isEmpty()) { + handleError("File set identifying link file(s) " + + "required for action recreate"); + return; + } + Properties links = loadLinks(fileSets); + + for (Iterator kitr = links.keySet().iterator(); kitr.hasNext();) { + String lnk = (String) kitr.next(); + String res = links.getProperty(lnk); + // handle the case where lnk points to a directory (bug 25181) + try { + File test = new File(lnk); + if (!SYMLINK_UTILS.isSymbolicLink(lnk)) { + doLink(res, lnk); + } else if (!test.getCanonicalPath().equals( + new File(res).getCanonicalPath())) { + SYMLINK_UTILS.deleteSymbolicLink(test, this); + doLink(res, lnk); + } // else lnk exists, do nothing + } catch (IOException ioe) { + handleError("IO exception while creating link"); + } + } + } finally { + setDefaults(); + } + } + + /** + * Record symlinks. + * @throws BuildException on error. + * @since Ant 1.7 + */ + public void record() throws BuildException { + try { + if (fileSets.isEmpty()) { + handleError("Fileset identifying links to record required"); + return; + } + if (linkFileName == null) { + handleError("Name of file to record links in required"); + return; + } + // create a hashtable to group them by parent directory: + Hashtable byDir = new Hashtable(); + + // get an Iterator of file objects representing links (canonical): + for (Iterator litr = findLinks(fileSets).iterator(); + litr.hasNext();) { + File thisLink = (File) litr.next(); + File parent = thisLink.getParentFile(); + Vector v = (Vector) byDir.get(parent); + if (v == null) { + v = new Vector(); + byDir.put(parent, v); + } + v.addElement(thisLink); + } + // write a Properties file in each directory: + for (Iterator dirs = byDir.keySet().iterator(); dirs.hasNext();) { + File dir = (File) dirs.next(); + Vector linksInDir = (Vector) byDir.get(dir); + Properties linksToStore = new Properties(); + + // fill up a Properties object with link and resource names: + for (Iterator dlnk = linksInDir.iterator(); dlnk.hasNext();) { + File lnk = (File) dlnk.next(); + try { + linksToStore.put(lnk.getName(), lnk.getCanonicalPath()); + } catch (IOException ioe) { + handleError("Couldn't get canonical name of parent link"); + } + } + writePropertyFile(linksToStore, dir); + } + } finally { + setDefaults(); + } + } + + /** + * Return all variables to their default state for the next invocation. + * @since Ant 1.7 + */ + private void setDefaults() { + resource = null; + link = null; + linkFileName = null; + failonerror = true; // default behavior is to fail on an error + overwrite = false; // default behavior is to not overwrite + setAction("single"); // default behavior is make a single link + fileSets.clear(); + } + + /** + * 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. + */ + @Override + 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. + * @deprecated use + * org.apache.tools.ant.util.SymbolicLinkUtils#deleteSymbolicLink + * instead + */ + @Deprecated + public static void deleteSymlink(String path) + throws IOException, FileNotFoundException { + SYMLINK_UTILS.deleteSymbolicLink(new File(path), null); + } + + /** + * 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.</p> + * + * <p>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.</p> + * + * <p>Since Ant 1.8.0 this method will try to delete the File object if + * it reports it wouldn't exist (as symlinks pointing nowhere usually do). + * Prior version would throw a FileNotFoundException in that case.</p> + * + * @param linkfil A <code>File</code> object of the symlink to delete. + * + * @throws IOException If calls to <code>File.rename</code>, + * <code>File.delete</code> or + * <code>File.getCanonicalPath</code> + * fail. + * @deprecated use + * org.apache.tools.ant.util.SymbolicLinkUtils#deleteSymbolicLink + * instead + */ + @Deprecated + public static void deleteSymlink(File linkfil) + throws IOException { + SYMLINK_UTILS.deleteSymbolicLink(linkfil, null); + } + + /** + * 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. + * @throws BuildException if the property file could not be written + */ + 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>. + * @throws BuildException with the message if failonerror=true + */ + 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. + * @throws BuildException when things go wrong + */ + private void doLink(String res, String lnk) throws BuildException { + File linkfil = new File(lnk); + String options = "-s"; + if (overwrite) { + options += "f"; + if (linkfil.exists()) { + try { + SYMLINK_UTILS.deleteSymbolicLink(linkfil, this); + } catch (FileNotFoundException fnfe) { + log("Symlink disappeared before it was deleted: " + lnk); + } catch (IOException ioe) { + log("Unable to overwrite preexisting link or file: " + lnk, + ioe, Project.MSG_INFO); + } + } + } + String[] cmd = new String[] {"ln", options, res, lnk}; + try { + Execute.runCommand(this, cmd); + } catch (BuildException failedToExecute) { + if (failonerror) { + throw failedToExecute; + } else { + //log at the info level, and keep going. + log(failedToExecute.getMessage(), failedToExecute, Project.MSG_INFO); + } + } + } + + /** + * 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(); + final int size = v.size(); + for (int i = 0; i < 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 (SYMLINK_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: + final int size = v.size(); + for (int i = 0; i < 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(); + InputStream is = null; + try { + is = new BufferedInputStream(new FileInputStream(inc)); + lnks.load(is); + 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; + } finally { + FileUtils.close(is); + } + 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; + } +} |