git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@713373 13f79535-47bb-0310-9956-ffa450edef68master
@@ -516,8 +516,9 @@ Other changes: | |||
STARTTLS. | |||
Bugzilla Report 46063. | |||
* <import> has a new attribute "as" that can be used to control the | |||
prefix prepended to the imported target's names. | |||
* <import> has new attributes "as" and "prefixSeparator" that can be | |||
used to control the prefix prepended to the imported target's | |||
names. | |||
* a new task <include> provides an alternative to <import> that | |||
should be preferred when you don't want to override any targets. | |||
@@ -175,6 +175,16 @@ project).</p> | |||
</td> | |||
<td valign="top" align="center">No</td> | |||
</tr> | |||
<tr> | |||
<td valign="top"> | |||
prefixSeparator | |||
</td> | |||
<td valign="top"> | |||
Specifies the separator to be used between the prefix and the | |||
target name. Defaults to ".". | |||
</td> | |||
<td valign="top" align="center">No</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
@@ -69,6 +69,11 @@ that are not possible with entity includes: | |||
all target names are prefixed as well. This makes the included file | |||
self-contained.</p> | |||
<p>Note that prefixes nest, so if a build file includes a file with | |||
prefix "a" and the included file includes another file with prefix | |||
"b", then the targets of that last build file will be prefixed by | |||
"a.b.".</p> | |||
<h4>Special Properties</h4> | |||
<p>Included files are treated as they are present in the main | |||
@@ -171,6 +176,16 @@ project).</p> | |||
<td valign="top" align="center">Yes, if the included file's | |||
project tag doesn't specify a name attribute.</td> | |||
</tr> | |||
<tr> | |||
<td valign="top"> | |||
prefixSeparator | |||
</td> | |||
<td valign="top"> | |||
Specifies the separator to be used between the prefix and the | |||
target name. Defaults to ".". | |||
</td> | |||
<td valign="top" align="center">No</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
@@ -143,6 +143,32 @@ public class ProjectHelper { | |||
targetPrefix.set(prefix); | |||
} | |||
private final static ThreadLocal prefixSeparator = new ThreadLocal() { | |||
protected Object initialValue() { | |||
return "."; | |||
} | |||
}; | |||
/** | |||
* The separator between the prefix and the target name. | |||
* | |||
* <p>May be set by <import>'s prefixSeperator attribute.</p> | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
public static String getCurrentPrefixSeparator() { | |||
return (String) prefixSeparator.get(); | |||
} | |||
/** | |||
* Sets the separator between the prefix and the target name. | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
public static void setCurrentPrefixSeparator(String sep) { | |||
prefixSeparator.set(sep); | |||
} | |||
private final static ThreadLocal inIncludeMode = new ThreadLocal() { | |||
protected Object initialValue() { | |||
return Boolean.FALSE; | |||
@@ -849,6 +849,8 @@ public class ProjectHelper2 extends ProjectHelper { | |||
String prefix = null; | |||
boolean isInIncludeMode = | |||
context.isIgnoringProjectTag() && isInIncludeMode(); | |||
String sep = getCurrentPrefixSeparator(); | |||
if (isInIncludeMode) { | |||
prefix = getTargetPrefix(context); | |||
if (prefix == null) { | |||
@@ -858,7 +860,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||
+ " and the project tag doesn't" | |||
+ " specify a name attribute"); | |||
} | |||
name = prefix + "." + name; | |||
name = prefix + sep + name; | |||
} | |||
// Check if this target is in the current build file | |||
@@ -878,6 +880,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||
project.addOrReplaceTarget(name, target); | |||
usedTarget = true; | |||
} | |||
if (depends.length() > 0) { | |||
if (!isInIncludeMode) { | |||
target.setDepends(depends); | |||
@@ -885,7 +888,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||
for (Iterator iter = | |||
Target.parseDepends(depends, name).iterator(); | |||
iter.hasNext(); ) { | |||
target.addDependency(prefix + "." + iter.next()); | |||
target.addDependency(prefix + sep + iter.next()); | |||
} | |||
} | |||
} | |||
@@ -893,7 +896,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||
&& (prefix = getTargetPrefix(context)) != null) { | |||
// In an imported file (and not completely | |||
// ignoring the project tag or having a preconfigured prefix) | |||
String newName = prefix + "." + name; | |||
String newName = prefix + sep + name; | |||
Target newTarget = usedTarget ? new Target(target) : target; | |||
newTarget.setName(newName); | |||
context.getCurrentTargets().put(newName, newTarget); | |||
@@ -909,10 +912,17 @@ public class ProjectHelper2 extends ProjectHelper { | |||
if (configuredValue != null) { | |||
return configuredValue; | |||
} | |||
String projectName = context.getCurrentProjectName(); | |||
if (projectName != null && projectName.length() == 0) { | |||
if ("".equals(projectName)) { | |||
projectName = null; | |||
} | |||
// help nested include tasks | |||
if (projectName != null) { | |||
setCurrentTargetPrefix(projectName); | |||
} | |||
return projectName; | |||
} | |||
@@ -56,6 +56,7 @@ public class ImportTask extends Task { | |||
private String file; | |||
private boolean optional; | |||
private String targetPrefix; | |||
private String prefixSeparator = "."; | |||
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||
/** | |||
@@ -89,9 +90,15 @@ public class ImportTask extends Task { | |||
} | |||
/** | |||
* This relies on the task order model. | |||
* The separator to use between prefix and target name, default is | |||
* ".". | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
public void setPrefixSeparator(String s) { | |||
prefixSeparator = s; | |||
} | |||
public void execute() { | |||
if (file == null) { | |||
throw new BuildException("import requires file attribute"); | |||
@@ -156,16 +163,22 @@ public class ImportTask extends Task { | |||
// importing another one | |||
String oldPrefix = ProjectHelper.getCurrentTargetPrefix(); | |||
boolean oldIncludeMode = ProjectHelper.isInIncludeMode(); | |||
String oldSep = ProjectHelper.getCurrentPrefixSeparator(); | |||
try { | |||
ProjectHelper.setCurrentTargetPrefix(targetPrefix); | |||
ProjectHelper.setInIncludeMode(isInIncludeMode()); | |||
String prefix = targetPrefix; | |||
if (isInIncludeMode() && oldPrefix != null | |||
&& targetPrefix != null) { | |||
prefix = oldPrefix + oldSep + targetPrefix; | |||
} | |||
setProjectHelperProps(prefix, prefixSeparator, | |||
isInIncludeMode()); | |||
helper.parse(getProject(), importedFile); | |||
} catch (BuildException ex) { | |||
throw ProjectHelper.addLocationToBuildException( | |||
ex, getLocation()); | |||
} finally { | |||
ProjectHelper.setCurrentTargetPrefix(oldPrefix); | |||
ProjectHelper.setInIncludeMode(oldIncludeMode); | |||
setProjectHelperProps(oldPrefix, oldSep, oldIncludeMode); | |||
} | |||
} | |||
@@ -187,4 +200,16 @@ public class ImportTask extends Task { | |||
return "include".equals(getTaskType()); | |||
} | |||
/** | |||
* Sets a bunch of Thread-local ProjectHelper properties. | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
private static void setProjectHelperProps(String prefix, | |||
String prefixSep, | |||
boolean inIncludeMode) { | |||
ProjectHelper.setCurrentTargetPrefix(prefix); | |||
ProjectHelper.setCurrentPrefixSeparator(prefixSep); | |||
ProjectHelper.setInIncludeMode(inIncludeMode); | |||
} | |||
} |
@@ -0,0 +1,21 @@ | |||
<?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> | |||
<include file="b.xml" as="b" prefixSeparator="::"/> | |||
<include file="a.xml" as="a" prefixSeparator=""/> | |||
</project> |
@@ -38,4 +38,10 @@ | |||
<target name="testNoOverride" depends="override.dummy"> | |||
<au:assertEquals expected="in included/imported" actual="${prop}"/> | |||
</target> | |||
<include file="importtests/nested.xml" as="nested"/> | |||
<!-- really only tests that the targets have the expected names by | |||
forcing an exception if the dependencies don't exist --> | |||
<target name="testNesting" depends="nested.b::b, nested.aa"/> | |||
</project> |