Index: ImportTask.java =================================================================== --- ImportTask.java (revision 511767) +++ ImportTask.java (working copy) @@ -18,21 +18,25 @@ package org.apache.tools.ant.taskdefs; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.Vector; + import org.apache.tools.ant.BuildException; import org.apache.tools.ant.ProjectHelper; import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelper; import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.Ant.Reference; +import org.apache.tools.ant.types.Path; import org.apache.tools.ant.util.FileUtils; -import java.io.File; -import java.util.Vector; - /** * Task to import another build file into the current project. *
- * It must be 'top level'. On execution it will read another Ant file - * into the same Project. - *
+ * It must be 'top level'. On execution it will read another Ant file into the + * same Project. ** Important: we have not finalized how relative file references * will be resolved in deep/complex build hierarchies - such as what happens @@ -41,56 +45,81 @@ *
*Examples:
*- * <import file="../common-targets.xml"/> + * <import file="../common-targets.xml" /> *- *
Import targets from a file in a parent directory.
+ * + * Import targets from a file in a parent directory. + *+ * *
- * <import file="${deploy-platform}.xml"/> + * <import file="${deploy-platform}.xml" /> *- *
Import the project defined by the property deploy-platform
.
+ * <import resource="common-targets.xml" /> + *+ * + * Import targets from ant classpath. + *
+ * + *
+ * <import resource="common-targets.xml" classpath="example.jar" /> + *+ * + * Import targets from a specified classpath. + *
+ * * @since Ant1.6 * @ant.task category="control" */ public class ImportTask extends Task { - private String file; - private boolean optional; - private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); + private String file; + private boolean optional; + private static final FileUtils FILE_UTILS = FileUtils.newFileUtils(); - /** - * sets the optional attribute - * - * @param optional if true ignore files that are not present, - * default is false - */ - public void setOptional(boolean optional) { - this.optional = optional; - } + private String resource; - /** - * the name of the file to import. How relative paths are resolved is still - * in flux: use absolute paths for safety. - * @param file the name of the file - */ - public void setFile(String file) { - // I don't think we can use File - different rules - // for relative paths. - this.file = file; - } + protected Path classpath; - /** - * This relies on the task order model. - * - */ - public void execute() { - if (file == null) { - throw new BuildException("import requires file attribute"); - } - if (getOwningTarget() == null - || !"".equals(getOwningTarget().getName())) { - throw new BuildException("import only allowed as a top-level task"); - } + /** + * sets the optional attribute + * + * @param optional + * if true ignore files that are not present, default is false + */ + public void setOptional(boolean optional) { + this.optional = optional; + } + /** + * the name of the file to import. How relative paths are resolved is still + * in flux: use absolute paths for safety. + * + * @param file + * the name of the file + */ + public void setFile(String file) { + // I don't think we can use File - different rules + // for relative paths. + this.file = file; + } + + /** + * This relies on the task order model. + * + */ + public void execute() { + if (file == null && resource == null) { + throw new BuildException( + "import requires file or resource attributes"); + } + if (getOwningTarget() == null + || !"".equals(getOwningTarget().getName())) { + throw new BuildException("import only allowed as a top-level task"); + } + ProjectHelper helper = (ProjectHelper) getProject(). getReference(ProjectHelper.PROJECTHELPER_REFERENCE); @@ -100,54 +129,147 @@ throw new BuildException("import requires support in ProjectHelper"); } - Vector importStack = helper.getImportStack(); + Vector importStack = helper.getImportStack(); - if (importStack.size() == 0) { - // this happens if ant is used with a project - // helper that doesn't set the import. - throw new BuildException("import requires support in ProjectHelper"); - } + if (importStack.size() == 0) { + // this happens if ant is used with a project + // helper that doesn't set the import. + throw new BuildException("import requires support in ProjectHelper"); + } - if (getLocation() == null || getLocation().getFileName() == null) { - throw new BuildException("Unable to get location of import task"); - } + if (getLocation() == null || getLocation().getFileName() == null) { + throw new BuildException("Unable to get location of import task"); + } File buildFile = new File(getLocation().getFileName()).getAbsoluteFile(); - // Paths are relative to the build file they're imported from, - // *not* the current directory (same as entity includes). + if (file != null) + getProject().log( + "Importing file " + file + " from " + + buildFile.getAbsolutePath(), Project.MSG_VERBOSE); + if (resource != null) + getProject().log( + "Importing resource " + resource + " from " + + buildFile.getAbsolutePath(), Project.MSG_VERBOSE); - File buildFileParent = new File(buildFile.getParent()); - File importedFile = FILE_UTILS.resolveFile(buildFileParent, file); + // Paths are relative to the build file they're imported from, + // *not* the current directory (same as entity includes). - getProject().log("Importing file " + importedFile + " from " - + buildFile.getAbsolutePath(), Project.MSG_VERBOSE); + File buildFileParent = new File(buildFile.getParent()); + Object importedObject = null; - if (!importedFile.exists()) { - String message = - "Cannot find " + file + " imported from " - + buildFile.getAbsolutePath(); - if (optional) { - getProject().log(message, Project.MSG_VERBOSE); - return; - } else { - throw new BuildException(message); - } - } + if (file != null) { + File importedFile = FILE_UTILS.resolveFile(buildFileParent, file); + if (!importedFile.exists()) { + String message = "Cannot find " + file + " imported from " + + buildFile.getAbsolutePath(); + if (optional) { + getProject().log(message, Project.MSG_VERBOSE); + return; + } else { + throw new BuildException(message); + } + } - if (importStack.contains(importedFile)) { - getProject().log( - "Skipped already imported file:\n " - + importedFile + "\n", Project.MSG_VERBOSE); - return; - } + importedFile = new File(getPath(importedFile)); + importedObject = importedFile; + } else if (resource != null) { + log("Resource Loading " + resource, Project.MSG_VERBOSE); + URL importedURL = null; + ClassLoader cL = null; - try { - helper.parse(getProject(), importedFile); - } catch (BuildException ex) { - throw ProjectHelper.addLocationToBuildException( - ex, getLocation()); - } - } + if (classpath != null) { + cL = getProject().createClassLoader(classpath); + } else { + cL = this.getClass().getClassLoader(); + } + if (cL == null) { + importedURL = ClassLoader.getSystemResource(resource); + } else { + importedURL = cL.getResource(resource); + } + + if (importedURL == null) { + String message = "Cannot find " + resource + " imported from " + + buildFile.getAbsolutePath(); + if (optional) { + getProject().log(message, Project.MSG_VERBOSE); + return; + } else { + throw new BuildException(message); + } + } + importedObject = importedURL; + } + + if (importStack.contains(importedObject)) { + getProject().log( + "Skipped already imported file/resource:\n " + + importedObject + "\n", Project.MSG_WARN); + return; + } + + try { + helper.parse(getProject(), importedObject); + } catch (BuildException ex) { + throw ProjectHelper.addLocationToBuildException(ex, getLocation()); + } + } + + private static String getPath(File file) { + try { + return file.getCanonicalPath(); + } catch (IOException e) { + return file.getAbsolutePath(); + } + } + + /** + * @param resource + * The resource to set. + */ + public void setResource(String resource) { + this.resource = resource; + } + + /** + * The classpath to use when looking up a resource. + * + * @param classpath + * to add to any existing classpath + */ + public void setClasspath(Path classpath) { + if (this.classpath == null) { + this.classpath = classpath; + } else { + this.classpath.append(classpath); + } + } + + /** + * The classpath to use when looking up a resource. + */ + public Path createClasspath() { + if (this.classpath == null) { + this.classpath = new Path(getProject()); + } + return this.classpath.createPath(); + } + + /** + * the classpath to use when looking up a resource, given as reference to a + * <path> defined elsewhere + */ + public void setClasspathRef(Reference r) { + createClasspath().setRefid(r); + } + + /** + * @since Ant 1.5 + */ + public Path getClasspath() { + return classpath; + } + }