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> |