git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@836334 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -1022,6 +1022,15 @@ Other changes: | |||
| contained provide URLs) and can get multiple resources in a single | |||
| task. | |||
| * <import> can now import non-File resources if they provide an URL | |||
| - as the <url> and <javaresource> resources do. | |||
| Bugzilla Report 29251 | |||
| * <import> can now import multiple resources specified as resource | |||
| collections. | |||
| Bugzilla Report 22269. | |||
| Changes from Ant 1.7.0 TO Ant 1.7.1 | |||
| ============================================= | |||
| @@ -95,6 +95,14 @@ present in the imported project tag.</p> | |||
| property will not be set. | |||
| </p> | |||
| <p>Since Ant 1.8.0 the task can also import resources from URLs or | |||
| classpath resources (which are URLs, really). If you need to know | |||
| whether the current build file's source has been a file or an URL | |||
| you can consult the | |||
| property <b>ant.file.type.<em>projectname</em></b> (using the same | |||
| example as above <b>ant.file.type.builddocs</b>) which either have | |||
| the value "file" or "url".</p> | |||
| <h4>Resolving files against the imported file</h4> | |||
| <p>Suppose your main build file called <code>importing.xml</code> | |||
| @@ -135,6 +143,19 @@ directory. This technique also allows <code>imported.xml</code> to be | |||
| used as a standalone file (without being imported in other | |||
| project).</p> | |||
| <p>The above description only works for imported files that actually | |||
| are imported from files and not from URLs. For files imported from | |||
| URLs using resources relative to the imported file requires you to | |||
| use tasks that can work on non-file resources in the first place. | |||
| To create a relative resource you'd use something like:</p> | |||
| <pre> | |||
| <url id="imported.basedir" url="${ant.file.imported}/."/> | |||
| <loadproperties> | |||
| <url url="${toString:imported.basedir}/imported.properties"/> | |||
| </loadproperties> | |||
| </pre> | |||
| <h3>Parameters</h3> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tbody> | |||
| @@ -152,7 +173,7 @@ project).</p> | |||
| relative to the <i>importing</i> file. <b>Note</b>, this is unlike most other | |||
| ant file attributes, where relative files are resolved relative to ${basedir}. | |||
| </td> | |||
| <td valign="top" align="center">Yes</td> | |||
| <td valign="top" align="center">Yes or a nested resource collection</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top"> | |||
| @@ -188,6 +209,14 @@ project).</p> | |||
| </tbody> | |||
| </table> | |||
| <h3>Parameters specified as nested elements</h3> | |||
| <h4>any <a href="../CoreTypes/resources.html">resource</a> or resource | |||
| collection</h4> | |||
| <p>The specified resources will be imported. <em>Since Ant | |||
| 1.8.0</em></p> | |||
| <h3>Examples</h3> | |||
| <pre> <import file="../common-targets.xml"/> | |||
| </pre> | |||
| @@ -200,6 +229,17 @@ directory.</p> | |||
| <p>Imports the project defined by the property deploy-platform</p> | |||
| <pre> | |||
| <import> | |||
| <javaresource name="common/targets.xml"> | |||
| <classpath location="common.jar"/> | |||
| </javaresource> | |||
| </import> | |||
| </pre> | |||
| <p>Imports targets from the targets.xml file that is inside the | |||
| directory common inside the jar file common.jar.</p> | |||
| <h3>How is <import> different | |||
| from <a href="include.html"><include></a>?</h3> | |||
| @@ -28,6 +28,8 @@ | |||
| Include another build file into the current project. | |||
| </p> | |||
| <p><em>since Ant 1.8.0</em></p> | |||
| <p> | |||
| <b>Note</b> this task heavily relies on the ProjectHelper | |||
| implementation and doesn't really perform any work of its own. If | |||
| @@ -98,6 +100,12 @@ present in the included project tag.</p> | |||
| property will not be set. | |||
| </p> | |||
| <p>If you need to know whether the current build file's source has | |||
| been a file or an URL you can consult the | |||
| property <b>ant.file.type.<em>projectname</em></b> (using the same | |||
| example as above <b>ant.file.type.builddocs</b>) which either have | |||
| the value "file" or "url".</p> | |||
| <h4>Resolving files against the included file</h4> | |||
| <p>Suppose your main build file called <code>including.xml</code> | |||
| @@ -138,6 +146,19 @@ directory. This technique also allows <code>included.xml</code> to be | |||
| used as a standalone file (without being included in other | |||
| project).</p> | |||
| <p>The above description only works for included files that actually | |||
| are included from files and not from URLs. For files included from | |||
| URLs using resources relative to the included file requires you to | |||
| use tasks that can work on non-file resources in the first place. | |||
| To create a relative resource you'd use something like:</p> | |||
| <pre> | |||
| <url id="included.basedir" url="${ant.file.included}/."/> | |||
| <loadproperties> | |||
| <url url="${toString:included.basedir}/included.properties"/> | |||
| </loadproperties> | |||
| </pre> | |||
| <h3>Parameters</h3> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tbody> | |||
| @@ -155,7 +176,7 @@ project).</p> | |||
| relative to the <i>including</i> file. <b>Note</b>, this is unlike most other | |||
| ant file attributes, where relative files are resolved relative to ${basedir}. | |||
| </td> | |||
| <td valign="top" align="center">Yes</td> | |||
| <td valign="top" align="center">Yes or a nested resource collection</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top"> | |||
| @@ -174,7 +195,7 @@ project).</p> | |||
| <td valign="top"> | |||
| Specifies the prefix prepended to the target names. If | |||
| ommitted, the name attribute of the project tag of the | |||
| imported file will be used. | |||
| included file will be used. | |||
| </td> | |||
| <td valign="top" align="center">Yes, if the included file's | |||
| project tag doesn't specify a name attribute.</td> | |||
| @@ -192,6 +213,13 @@ project).</p> | |||
| </tbody> | |||
| </table> | |||
| <h3>Parameters specified as nested elements</h3> | |||
| <h4>any <a href="../CoreTypes/resources.html">resource</a> or resource | |||
| collection</h4> | |||
| <p>The specified resources will be included.</p> | |||
| <h3>Examples</h3> | |||
| <pre> <include file="../common-targets.xml"/> | |||
| </pre> | |||
| @@ -204,6 +232,17 @@ directory.</p> | |||
| <p>Includes the project defined by the property deploy-platform</p> | |||
| <pre> | |||
| <include> | |||
| <javaresource name="common/targets.xml"> | |||
| <classpath location="common.jar"/> | |||
| </javaresource> | |||
| </include> | |||
| </pre> | |||
| <p>Includes targets from the targets.xml file that is inside the | |||
| directory common inside the jar file common.jar.</p> | |||
| <h3>How is <a href="import.html"><import></a> different | |||
| from <include>?</h3> | |||
| @@ -113,6 +113,27 @@ public final class MagicNames { | |||
| */ | |||
| public static final String ANT_FILE = "ant.file"; | |||
| /** | |||
| * property for type of ant build file (either file or url) | |||
| * Value: {@value} | |||
| * @since Ant 1.8.0 | |||
| */ | |||
| public static final String ANT_FILE_TYPE = "ant.file.type"; | |||
| /** | |||
| * ant build file of type file | |||
| * Value: {@value} | |||
| * @since Ant 1.8.0 | |||
| */ | |||
| public static final String ANT_FILE_TYPE_FILE = "file"; | |||
| /** | |||
| * ant build file of type url | |||
| * Value: {@value} | |||
| * @since Ant 1.8.0 | |||
| */ | |||
| public static final String ANT_FILE_TYPE_URL = "url"; | |||
| /** | |||
| * Property used to store the java version ant is running in. | |||
| * Value: {@value} | |||
| @@ -773,6 +773,8 @@ public class Main implements AntMain { | |||
| project.setUserProperty(MagicNames.ANT_FILE, | |||
| buildFile.getAbsolutePath()); | |||
| project.setUserProperty(MagicNames.ANT_FILE_TYPE, | |||
| MagicNames.ANT_FILE_TYPE_FILE); | |||
| project.setKeepGoingMode(keepGoingMode); | |||
| if (proxy) { | |||
| @@ -18,6 +18,8 @@ | |||
| package org.apache.tools.ant.helper; | |||
| import java.io.File; | |||
| import java.net.MalformedURLException; | |||
| import java.net.URL; | |||
| import java.util.ArrayList; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| @@ -27,12 +29,12 @@ import java.util.Vector; | |||
| import org.xml.sax.Locator; | |||
| import org.xml.sax.Attributes; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.Target; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Location; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.RuntimeConfigurable; | |||
| import org.apache.tools.ant.Target; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| /** | |||
| * Context information for the ant processing. | |||
| @@ -45,6 +47,9 @@ public class AntXMLContext { | |||
| /** The configuration file to parse. */ | |||
| private File buildFile; | |||
| /** The configuration file to parse. */ | |||
| private URL buildFileURL; | |||
| /** Vector with all the targets, in the order they are | |||
| * defined. Project maintains a Hashtable, which is not ordered. | |||
| * This will allow description to know the original order. | |||
| @@ -57,6 +62,12 @@ public class AntXMLContext { | |||
| */ | |||
| private File buildFileParent; | |||
| /** | |||
| * Parent directory of the build file. Used for resolving entities | |||
| * and setting the project's base directory. | |||
| */ | |||
| private URL buildFileParentURL; | |||
| /** Name of the current project */ | |||
| private String currentProjectName; | |||
| @@ -115,6 +126,24 @@ public class AntXMLContext { | |||
| this.buildFile = buildFile; | |||
| this.buildFileParent = new File(buildFile.getParent()); | |||
| implicitTarget.setLocation(new Location(buildFile.getAbsolutePath())); | |||
| try { | |||
| setBuildFile(FileUtils.getFileUtils().getFileURL(buildFile)); | |||
| } catch (MalformedURLException ex) { | |||
| throw new BuildException(ex); | |||
| } | |||
| } | |||
| /** | |||
| * sets the build file to which the XML context belongs | |||
| * @param buildFile ant build file | |||
| * @since Ant 1.8.0 | |||
| */ | |||
| public void setBuildFile(URL buildFile) throws MalformedURLException { | |||
| this.buildFileURL = buildFile; | |||
| this.buildFileParentURL = new URL(buildFile, "."); | |||
| if (implicitTarget.getLocation() == null) { | |||
| implicitTarget.setLocation(new Location(buildFile.toString())); | |||
| } | |||
| } | |||
| /** | |||
| @@ -133,6 +162,24 @@ public class AntXMLContext { | |||
| return buildFileParent; | |||
| } | |||
| /** | |||
| * find out the build file | |||
| * @return the build file to which the xml context belongs | |||
| * @since Ant 1.8.0 | |||
| */ | |||
| public URL getBuildFileURL() { | |||
| return buildFileURL; | |||
| } | |||
| /** | |||
| * find out the parent build file of this build file | |||
| * @return the parent build file of this build file | |||
| * @since Ant 1.8.0 | |||
| */ | |||
| public URL getBuildFileParentURL() { | |||
| return buildFileParentURL; | |||
| } | |||
| /** | |||
| * find out the project to which this antxml context belongs | |||
| * @return project | |||
| @@ -218,6 +218,11 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| context.setBuildFile(buildFile); | |||
| buildFileName = buildFile.toString(); | |||
| } else if (url != null) { | |||
| try { | |||
| context.setBuildFile(url); | |||
| } catch (java.net.MalformedURLException ex) { | |||
| throw new BuildException(ex); | |||
| } | |||
| buildFileName = url.toString(); | |||
| } else { | |||
| throw new BuildException("Source " + source.getClass().getName() | |||
| @@ -738,7 +743,8 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| } | |||
| // XXX Move to Project ( so it is shared by all helpers ) | |||
| String antFileProp = "ant.file." + context.getCurrentProjectName(); | |||
| String antFileProp = | |||
| MagicNames.ANT_FILE + "." + context.getCurrentProjectName(); | |||
| String dup = project.getProperty(antFileProp); | |||
| if (dup != null && nameAttributeSet) { | |||
| File dupFile = new File(dup); | |||
| @@ -748,10 +754,20 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| + " and again in " + context.getBuildFile(), Project.MSG_WARN); | |||
| } | |||
| } | |||
| if (context.getBuildFile() != null && nameAttributeSet) { | |||
| project.setUserProperty( | |||
| MagicNames.ANT_FILE + "." + context.getCurrentProjectName(), context | |||
| .getBuildFile().toString()); | |||
| if (nameAttributeSet) { | |||
| String typeProp = MagicNames.ANT_FILE_TYPE + "." | |||
| + context.getCurrentProjectName(); | |||
| if (context.getBuildFile() != null) { | |||
| project.setUserProperty(antFileProp, | |||
| context.getBuildFile().toString()); | |||
| project.setUserProperty(typeProp, | |||
| MagicNames.ANT_FILE_TYPE_FILE); | |||
| } else if (context.getBuildFileURL() != null) { | |||
| project.setUserProperty(antFileProp, | |||
| context.getBuildFileURL().toString()); | |||
| project.setUserProperty(typeProp, | |||
| MagicNames.ANT_FILE_TYPE_URL); | |||
| } | |||
| } | |||
| if (context.isIgnoringProjectTag()) { | |||
| // no further processing | |||
| @@ -26,10 +26,13 @@ import org.apache.tools.ant.types.Resource; | |||
| import org.apache.tools.ant.types.ResourceCollection; | |||
| import org.apache.tools.ant.types.resources.FileProvider; | |||
| import org.apache.tools.ant.types.resources.FileResource; | |||
| import org.apache.tools.ant.types.resources.URLResource; | |||
| import org.apache.tools.ant.types.resources.Union; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| import java.io.File; | |||
| import java.net.MalformedURLException; | |||
| import java.net.URL; | |||
| import java.util.Iterator; | |||
| import java.util.Vector; | |||
| @@ -151,17 +154,9 @@ public class ImportTask extends Task { | |||
| } | |||
| Union resourcesToImport = new Union(getProject(), resources); | |||
| if (file != null) { | |||
| 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). | |||
| File buildFileParent = new File(buildFile.getParent()); | |||
| File importedFile = FILE_UTILS.resolveFile(buildFileParent, file); | |||
| resources.add(new FileResource(importedFile)); | |||
| Resource fromFileAttribute = getFileAttributeResource(); | |||
| if (fromFileAttribute != null) { | |||
| resources.add(fromFileAttribute); | |||
| } | |||
| for (Iterator i = resourcesToImport.iterator(); i.hasNext(); ) { | |||
| importResource(helper, (Resource) i.next()); | |||
| @@ -227,6 +222,34 @@ public class ImportTask extends Task { | |||
| } | |||
| } | |||
| private Resource getFileAttributeResource() { | |||
| // Paths are relative to the build file they're imported from, | |||
| // *not* the current directory (same as entity includes). | |||
| if (file != null) { | |||
| File buildFile = | |||
| new File(getLocation().getFileName()).getAbsoluteFile(); | |||
| if (buildFile.exists()) { | |||
| File buildFileParent = new File(buildFile.getParent()); | |||
| File importedFile = | |||
| FILE_UTILS.resolveFile(buildFileParent, file); | |||
| return new FileResource(importedFile); | |||
| } | |||
| // maybe this import tasks is inside an imported URL? | |||
| try { | |||
| URL buildFileURL = new URL(getLocation().getFileName()); | |||
| URL importedFile = new URL(buildFileURL, file); | |||
| return new URLResource(importedFile); | |||
| } catch (MalformedURLException ex) { | |||
| log(ex.toString(), Project.MSG_VERBOSE); | |||
| } | |||
| throw new BuildException("failed to resolve " + file | |||
| + " relative to " | |||
| + getLocation().getFileName()); | |||
| } | |||
| return null; | |||
| } | |||
| /** | |||
| * Whether the task is in include (as opposed to import) mode. | |||
| * | |||
| @@ -0,0 +1,49 @@ | |||
| <?xml version="1.0"?> | |||
| <!-- | |||
| 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. | |||
| --> | |||
| <project default="antunit" xmlns:au="antlib:org.apache.ant.antunit"> | |||
| <import file="../antunit-base.xml" /> | |||
| <mkdir dir="${input}/a/b"/> | |||
| <mkdir dir="${input}/a/c"/> | |||
| <echo file="${input}/a/b/outer.xml"><![CDATA[ | |||
| <project> | |||
| <import file="../c/inner.xml"/> | |||
| </project> | |||
| ]]></echo> | |||
| <echo file="${input}/a/c/inner.xml"><![CDATA[ | |||
| <project> | |||
| <target name="foo"> | |||
| <echo>In inner</echo> | |||
| </target> | |||
| </project>]]></echo> | |||
| <mkdir dir="${output}"/> | |||
| <jar destfile="${output}/test.jar"> | |||
| <fileset dir="${input}"/> | |||
| </jar> | |||
| <delete dir="${input}"/> | |||
| <import> | |||
| <javaresource name="a/b/outer.xml"> | |||
| <classpath location="${output}/test.jar"/> | |||
| </javaresource> | |||
| </import> | |||
| <target name="testImportOfNestedFile" depends="foo"> | |||
| <au:assertLogContains text="In inner"/> | |||
| </target> | |||
| </project> | |||