Browse Source

PR 47830 : implementation of the ProjectHelperRepository to make Ant able to choose a ProjectHelper, and some doc about it

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@819284 13f79535-47bb-0310-9956-ffa450edef68
master
Nicolas Lalevee 15 years ago
parent
commit
df121a6cf5
10 changed files with 451 additions and 138 deletions
  1. +5
    -0
      WHATSNEW
  2. +1
    -0
      docs/manual/developlist.html
  3. +131
    -0
      docs/manual/projecthelper.html
  4. +10
    -4
      docs/manual/running.html
  5. +38
    -14
      src/main/org/apache/tools/ant/Main.java
  6. +34
    -117
      src/main/org/apache/tools/ant/ProjectHelper.java
  7. +203
    -0
      src/main/org/apache/tools/ant/ProjectHelperRepository.java
  8. +14
    -1
      src/main/org/apache/tools/ant/taskdefs/Ant.java
  9. +14
    -1
      src/main/org/apache/tools/ant/taskdefs/SubAnt.java
  10. +1
    -1
      src/main/org/apache/tools/ant/types/Description.java

+ 5
- 0
WHATSNEW View File

@@ -174,6 +174,11 @@ Changes that could break older environments:
(i.e. in a very unlikely event) then the new syntax would yield a
different result (an expanded property) than Ant 1.7.1 did.

* A ProjectHelper implementation can now provide the default build file
name it is expecting, and can specify if they can support a specific build
file. So Ant is now capable of supporting several ProjectHelper
implementations, deciding on which to use depending of the input build file.

Fixed bugs:
-----------



+ 1
- 0
docs/manual/developlist.html View File

@@ -37,6 +37,7 @@
<a href="develop.html#integration">Source-code Integration</a><br/>
<a href="inputhandler.html">InputHandler</a><br/>
<a href="antexternal.html">Using Ant Tasks Outside of Ant</a><br/>
<a href="projecthelper.html">The Ant frontend: ProjectHelper</a><br/>

<br/>Tutorials<br/>
<a href="tutorial-HelloWorldWithAnt.html">Hello World with Ant</a><br/>


+ 131
- 0
docs/manual/projecthelper.html View File

@@ -0,0 +1,131 @@
<!--
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.
-->
<html>

<head>
<meta http-equiv="Content-Language" content="en-us">
<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
<title>The Ant frontend: ProjectHelper</title>
</head>

<body>
<h1>The Ant frontend: ProjectHelper</h1>

<h2><a name="definition">What is a ProjectHelper?</a></h2>

<p>
The <code>ProjectHelper</code> in Ant is responsible to parse the build file
and create java instances representing the build workflow. It also declares which
kind of file it can parse, and which file name it expects as default input file.
</p>
<p>
So in Ant there is a default <code>ProjectHelper</code>
(<code>org.apache.tools.ant.helper.ProjectHelper2</code>) which will parse the
usual build.xml files. And if no build file is specified on the command line, it
will expect to find a build.xml file.
</p>

<p>
The immediate benefit of a such abstraction it that it is possible to make Ant
understand other kind of descriptive language than XML. Some experiment have
been done around a pure java frontend, and a groovy one too (ask the dev mailing
list for further info about these).
</p>

<h2><a name="repository">How is Ant is selecting the proper ProjectHelper</a></h2>

<p>
Ant can now know about several implementations of <code>ProjectHelper</code>
and have to decide which to use for each build file.
</p>

<p>So Ant at startup will list the found implementations and will keep it
ordered as it finds them in an internal 'repository':
<ul>
<li>the first to be searched for is the one declared by the system property
<code>org.apache.tools.ant.ProjectHelper</code> (see
<a href="running.html#sysprops">Java System Properties</a>);</li>
<li>then it searches with its class loader for a <code>ProjectHelper</code>
service declarations in the META-INF: it searches in the classpath for a
file <code>META-INF/services/org.apache.tools.ant.ProjectHelper</code>.
This file will just contain the fully qualified name of the
implementation of <code>ProjectHelper</code> to instanciate;</li>
<li>it will also search with the system class loader for
<code>ProjectHelper</code> service declarations in the META-INF;</li>
<li>last but not least it will add its default <code>ProjectHelper</code>
that can parse classical build.xml files.</li>
</ul>
In case of error while trying to instanciate a <code>ProjectHelper</code>, Ant
will log an error but still won't stop. If you want further debugging
info about the <code>ProjectHelper</code> internal 'repository', use the system
property <code>ant.project-helper-repo.debug</code> and set it to
<code>true</code>; the full stack trace will then also be printed.
</p>

<p>
Then when Ant is expected to parse a file, it will ask the
<code>ProjectHelper</code> repository to found an implementation that will be
able to parse the input file. Actually it will just iterate on the ordered list
and the first implementation that returns <code>true</code> to
<code>supportsBuildFile(File buildFile)</code> will be selected.
</p>

<p>
And when Ant is launching and there is no input file specified, it will search for
a default input file. It will iterate on the list of <code>ProjectHelper</code>
and will select the first one that expects a default file that actually exist.
</p>

<h2><a name="writing">Writing your own ProjectHelper</a></h2>

<p>
The class <code>org.apache.tools.ant.ProjectHelper</code> is the API expected to
be implemented. So write your own <code>ProjectHelper</code> by extending that
abstract class. You are then expected to implement at least the function
<code>parse(Project project, Object source)</code>. Note also that your
implementation will be instanciated by Ant, and it is expecting a default
constructor with no arguments.
</p>

<p>
Then there are some functions that will help you define what your helper is
capable of and what is is expecting:
<ul>
<li><code>getDefaultBuildFile()</code>: defines which file name is expected if
none provided</li>
<li><code>supportsBuildFile(File buildFile)</code>: defines if your parser
can parse the input file</li>
</ul>
</p>

<p>
Now that you have your implementation ready, you have to declare it to Ant. Two
solutions here:
<ul>
<li>use the system property <code>org.apache.tools.ant.ProjectHelper</code>
(see also the <a href="running.html#sysprops">Java System Properties</a>);</li>
<li>use the service file in META-INF: in the jar you will build with your
implementation, add a file
<code>META-INF/services/org.apache.tools.ant.ProjectHelper</code>.
And then in this file just put the fully qualified name of your
implementation</li>
</ul>
</p>

</body>
</html>


+ 10
- 4
docs/manual/running.html View File

@@ -415,7 +415,6 @@ org.apache.tools.ant.Executor implementation specified here.
<td>see <a href="sysclasspath.html">its dedicated page</a>, no
default value</td>
<td>see <a href="sysclasspath.html">its dedicated page</a></td>
</td>
</tr>
<tr>
<td><code>file.encoding</code></td>
@@ -455,18 +454,25 @@ org.apache.tools.ant.Executor implementation specified here.
</td>
</tr>
<tr>
<td><code>websphere.home
<td><code>websphere.home</code></td>
<td>path</td>
<td>Points to home directory of websphere.
see <a href="OptionalTasks/ejb.html#ejbjar_websphere">EJB Tasks</a>
</td>
</tr>
<tr>
<td><code>XmlLogger.file
<td><code>XmlLogger.file</code></td>
<td>filename (default 'log.xml')</td>
<td>Name for the logfile for <a href="listeners.html#MailLogger">MailLogger</a>.
</td>
</tr>
<tr>
<td><code>ant.project-helper-repo.debug</code></td>
<td>boolean (default 'false')</td>
<td>Set it to true to enable debuging with Ant's
<a href="projecthelper.html#repository">ProjectHelper internal repository</a>.
</td>
</tr>
</table>

<p>
@@ -529,7 +535,7 @@ have some documentation inside.</p>
Unix(-like) systems</a></h2>

<p>If you start Ant as a background process (like in <code>ant
&</code>) and the build process creates another process, Ant will
&amp;</code>) and the build process creates another process, Ant will
immediately try to read from standard input, which in turn will
most likely suspend the process. In order to avoid this, you must
redirect Ant's standard input or explicitly provide input to each


+ 38
- 14
src/main/org/apache/tools/ant/Main.java View File

@@ -20,6 +20,7 @@ package org.apache.tools.ant;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -301,6 +302,7 @@ public class Main implements AntMain {
*/
private void processArgs(String[] args) {
String searchForThis = null;
boolean searchForFile = false;
PrintStream logTo = null;

// cycle through given args
@@ -359,11 +361,10 @@ public class Main implements AntMain {
// set the flag to display the targets and quit
projectHelp = true;
} else if (arg.equals("-find") || arg.equals("-s")) {
searchForFile = true;
// eat up next arg if present, default to build.xml
if (i < args.length - 1) {
searchForThis = args[++i];
} else {
searchForThis = DEFAULT_BUILD_FILENAME;
}
} else if (arg.startsWith("-propertyfile")) {
i = handleArgPropertyFile(args, i);
@@ -411,11 +412,37 @@ public class Main implements AntMain {
// if buildFile was not specified on the command line,
if (buildFile == null) {
// but -find then search for it
if (searchForThis != null) {
buildFile = findBuildFile(System.getProperty("user.dir"),
searchForThis);
if (searchForFile) {
if (searchForThis != null) {
buildFile = findBuildFile(System.getProperty("user.dir"), searchForThis);
if (buildFile == null) {
throw new BuildException("Could not locate a build file!");
}
} else {
// no search file specified: so search an existing default file
Iterator it = ProjectHelperRepository.getInstance().getHelpers();
do {
ProjectHelper helper = (ProjectHelper) it.next();
searchForThis = helper.getDefaultBuildFile();
if (msgOutputLevel >= Project.MSG_VERBOSE) {
System.out.println("Searching the default build file: " + searchForThis);
}
buildFile = findBuildFile(System.getProperty("user.dir"), searchForThis);
} while (buildFile == null && it.hasNext());
if (buildFile == null) {
throw new BuildException("Could not locate a build file!");
}
}
} else {
buildFile = new File(DEFAULT_BUILD_FILENAME);
// no build file specified: so search an existing default file
Iterator it = ProjectHelperRepository.getInstance().getHelpers();
do {
ProjectHelper helper = (ProjectHelper) it.next();
buildFile = new File(helper.getDefaultBuildFile());
if (msgOutputLevel >= Project.MSG_VERBOSE) {
System.out.println("Trying the default build file: " + buildFile);
}
} while (!buildFile.exists() && it.hasNext());
}
}

@@ -633,20 +660,17 @@ public class Main implements AntMain {
* <p>
* Takes the given target as a suffix to append to each
* parent directory in search of a build file. Once the
* root of the file-system has been reached an exception
* is thrown.
* root of the file-system has been reached <code>null</code>
* is returned.
*
* @param start Leaf directory of search.
* Must not be <code>null</code>.
* @param suffix Suffix filename to look for in parents.
* Must not be <code>null</code>.
*
* @return A handle to the build file if one is found
*
* @exception BuildException if no build file is found
* @return A handle to the build file if one is found, <code>null</code> if not
*/
private File findBuildFile(String start, String suffix)
throws BuildException {
private File findBuildFile(String start, String suffix) {
if (msgOutputLevel >= Project.MSG_INFO) {
System.out.println("Searching for " + suffix + " ...");
}
@@ -662,7 +686,7 @@ public class Main implements AntMain {
// if parent is null, then we are at the root of the fs,
// complain that we can't find the build file.
if (parent == null) {
throw new BuildException("Could not locate a build file!");
return null;
}

// refresh our file handle


+ 34
- 117
src/main/org/apache/tools/ant/ProjectHelper.java View File

@@ -17,37 +17,21 @@
*/
package org.apache.tools.ant;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Vector;

import org.xml.sax.AttributeList;

import org.apache.tools.ant.helper.ProjectHelper2;
import org.apache.tools.ant.util.LoaderUtils;
import org.xml.sax.AttributeList;

/**
* Configures a Project (complete with Targets and Tasks) based on
* a XML build file. It'll rely on a plugin to do the actual processing
* of the xml file.
*
* a build file. It'll rely on a plugin to do the actual processing
* of the file.
* <p>
* This class also provide static wrappers for common introspection.
*
* All helper plugins must provide backward compatibility with the
* original ant patterns, unless a different behavior is explicitly
* specified. For example, if namespace is used on the &lt;project&gt; tag
* the helper can expect the entire build file to be namespace-enabled.
* Namespaces or helper-specific tags can provide meta-information to
* the helper, allowing it to use new ( or different policies ).
*
* However, if no namespace is used the behavior should be exactly
* identical with the default helper.
*
*/
public class ProjectHelper {
/** The URI for ant name space */
@@ -89,7 +73,7 @@ public class ProjectHelper {
* @exception BuildException if the configuration is invalid or cannot be read
*/
public static void configureProject(Project project, File buildFile) throws BuildException {
ProjectHelper helper = ProjectHelper.getProjectHelper();
ProjectHelper helper = ProjectHelperRepository.getInstance().getProjectHelper(buildFile);
project.addReference(PROJECTHELPER_REFERENCE, helper);
helper.parse(project, buildFile);
}
@@ -224,103 +208,13 @@ public class ProjectHelper {
}

/**
* Discovers a project helper instance. Uses the same patterns
* as JAXP, commons-logging, etc: a system property, a JDK1.3
* service discovery, default.
*
* @return a ProjectHelper, either a custom implementation
* if one is available and configured, or the default implementation
* otherwise.
*
* @exception BuildException if a specified helper class cannot
* be loaded/instantiated.
*/
public static ProjectHelper getProjectHelper() throws BuildException {
// Identify the class loader we will be using. Ant may be
// in a webapp or embedded in a different app
ProjectHelper helper = null;

// First, try the system property
String helperClass = System.getProperty(HELPER_PROPERTY);
try {
if (helperClass != null) {
helper = newHelper(helperClass);
}
} catch (SecurityException e) {
System.out.println("Unable to load ProjectHelper class \""
+ helperClass + " specified in system property "
+ HELPER_PROPERTY);
}

// A JDK1.3 'service' ( like in JAXP ). That will plug a helper
// automatically if in CLASSPATH, with the right META-INF/services.
if (helper == null) {
try {
ClassLoader classLoader = LoaderUtils.getContextClassLoader();
InputStream is = null;
if (classLoader != null) {
is = classLoader.getResourceAsStream(SERVICE_ID);
}
if (is == null) {
is = ClassLoader.getSystemResourceAsStream(SERVICE_ID);
}
if (is != null) {
// This code is needed by EBCDIC and other strange systems.
// It's a fix for bugs reported in xerces
InputStreamReader isr;
try {
isr = new InputStreamReader(is, "UTF-8");
} catch (java.io.UnsupportedEncodingException e) {
isr = new InputStreamReader(is);
}
BufferedReader rd = new BufferedReader(isr);

String helperClassName = rd.readLine();
rd.close();

if (helperClassName != null && !"".equals(helperClassName)) {
helper = newHelper(helperClassName);
}
}
} catch (Exception ex) {
System.out.println("Unable to load ProjectHelper from service " + SERVICE_ID);
}
}
return helper == null ? new ProjectHelper2() : helper;
}

/**
* Creates a new helper instance from the name of the class.
* It'll first try the thread class loader, then Class.forName()
* will load from the same loader that loaded this class.
*
* @param helperClass The name of the class to create an instance
* of. Must not be <code>null</code>.
*
* @return a new instance of the specified class.
*
* @exception BuildException if the class cannot be found or
* cannot be appropriate instantiated.
* Get the first project helper found in the classpath
*
* @return an project helper, never <code>null</code>
* @see #getHelpers()
*/
private static ProjectHelper newHelper(String helperClass)
throws BuildException {
ClassLoader classLoader = LoaderUtils.getContextClassLoader();
try {
Class clazz = null;
if (classLoader != null) {
try {
clazz = classLoader.loadClass(helperClass);
} catch (ClassNotFoundException ex) {
// try next method
}
}
if (clazz == null) {
clazz = Class.forName(helperClass);
}
return ((ProjectHelper) clazz.newInstance());
} catch (Exception e) {
throw new BuildException(e);
}
public static ProjectHelper getProjectHelper() {
return (ProjectHelper) ProjectHelperRepository.getInstance().getHelpers().next();
}

/**
@@ -618,4 +512,27 @@ public class ProjectHelper {
URL source) {
throw new BuildException("can't parse antlib descriptors");
}

/**
* Check if the helper supports the kind of file. Some basic check on the
* extension's file should be done here.
*
* @param buildFile
* the file expected to be parsed (never <code>null</code>)
* @return true if the helper supports it
* @since Ant 1.8.0
*/
public boolean supportsBuildFile(File buildFile) {
return true;
}

/**
* The file name of the build script to be parsed if none specified on the command line
*
* @return the name of the default file (never <code>null</code>)
* @since Ant 1.8.0
*/
public String getDefaultBuildFile() {
return Main.DEFAULT_BUILD_FILENAME;
}
}

+ 203
- 0
src/main/org/apache/tools/ant/ProjectHelperRepository.java View File

@@ -0,0 +1,203 @@
package org.apache.tools.ant;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

import org.apache.tools.ant.helper.ProjectHelper2;
import org.apache.tools.ant.util.LoaderUtils;

/**
* Repository of {@link ProjectHelper} found in the classpath or via some System
* properties.
* <p>
* See the ProjectHelper documentation in the manual.
*
* @since Ant 1.8.0
*/
public class ProjectHelperRepository {

private static final String DEBUG_PROJECT_HELPER_REPOSITORY = "ant.project-helper-repo.debug";

// The message log level is not accessible here because everything is instanciated statically
private static final boolean DEBUG = "true".equals(System.getProperty(DEBUG_PROJECT_HELPER_REPOSITORY));

private static ProjectHelperRepository instance = new ProjectHelperRepository();

private List/* <ProjectHelper> */helpers = new ArrayList();

public static ProjectHelperRepository getInstance() {
return instance;
}

private ProjectHelperRepository() {
collectProjectHelpers();
}

private void collectProjectHelpers() {
// First, try the system property
ProjectHelper projectHelper = getProjectHelperBySystemProperty();
registerProjectHelper(projectHelper);

// A JDK1.3 'service' ( like in JAXP ). That will plug a helper
// automatically if in CLASSPATH, with the right META-INF/services.
try {
ClassLoader classLoader = LoaderUtils.getContextClassLoader();
if (classLoader != null) {
Enumeration resources = classLoader.getResources(ProjectHelper.SERVICE_ID);
while (resources.hasMoreElements()) {
URL resource = (URL) resources.nextElement();
projectHelper = getProjectHelperBySerice(resource.openStream());
registerProjectHelper(projectHelper);
}
}

InputStream systemResource = ClassLoader.getSystemResourceAsStream(ProjectHelper.SERVICE_ID);
if (systemResource != null) {
projectHelper = getProjectHelperBySerice(systemResource);
registerProjectHelper(projectHelper);
}
} catch (Exception e) {
System.err.println("Unable to load ProjectHelper from service "
+ ProjectHelper.SERVICE_ID + " (" + e.getClass().getName() + ": "
+ e.getMessage() + ")");
if (DEBUG) {
e.printStackTrace(System.err);
}
}

// last but not least, ant default project helper
projectHelper = new ProjectHelper2();
registerProjectHelper(projectHelper);
}

private void registerProjectHelper(ProjectHelper projectHelper) {
if (projectHelper == null) {
return;
}
if (DEBUG) {
System.out.println("ProjectHelper " +
projectHelper.getClass().getName() + " registered.");
}
helpers.add(projectHelper);
}

private ProjectHelper getProjectHelperBySystemProperty() {
String helperClass = System.getProperty(ProjectHelper.HELPER_PROPERTY);
try {
if (helperClass != null) {
return newHelper(helperClass);
}
} catch (SecurityException e) {
System.err.println("Unable to load ProjectHelper class \""
+ helperClass + " specified in system property "
+ ProjectHelper.HELPER_PROPERTY + " (" + e.getMessage() + ")");
if (DEBUG) {
e.printStackTrace(System.err);
}
}
return null;
}

private ProjectHelper getProjectHelperBySerice(InputStream is) {
try {
// This code is needed by EBCDIC and other strange systems.
// It's a fix for bugs reported in xerces
InputStreamReader isr;
try {
isr = new InputStreamReader(is, "UTF-8");
} catch (java.io.UnsupportedEncodingException e) {
isr = new InputStreamReader(is);
}
BufferedReader rd = new BufferedReader(isr);

String helperClassName = rd.readLine();
rd.close();

if (helperClassName != null && !"".equals(helperClassName)) {
return newHelper(helperClassName);
}
} catch (Exception e) {
System.out.println("Unable to load ProjectHelper from service "
+ ProjectHelper.SERVICE_ID + " (" + e.getMessage() + ")");
if (DEBUG) {
e.printStackTrace(System.err);
}
}
return null;
}

/**
* Creates a new helper instance from the name of the class. It'll first try
* the thread class loader, then Class.forName() will load from the same
* loader that loaded this class.
*
* @param helperClass
* The name of the class to create an instance of. Must not be
* <code>null</code>.
*
* @return a new instance of the specified class.
*
* @exception BuildException
* if the class cannot be found or cannot be appropriate
* instantiated.
*/
private ProjectHelper newHelper(String helperClass) throws BuildException {
ClassLoader classLoader = LoaderUtils.getContextClassLoader();
try {
Class clazz = null;
if (classLoader != null) {
try {
clazz = classLoader.loadClass(helperClass);
} catch (ClassNotFoundException ex) {
// try next method
}
}
if (clazz == null) {
clazz = Class.forName(helperClass);
}
return ((ProjectHelper) clazz.newInstance());
} catch (Exception e) {
throw new BuildException(e);
}
}

/**
* Get the helper that will be able to parse the specified file. The helper
* will be chosen among the ones found in the classpath
*
* @return the first ProjectHelper that fit the requirement (never <code>null</code>).
*/
public ProjectHelper getProjectHelper(File buildFile) throws BuildException {
Iterator it = helpers.iterator();
while (it.hasNext()) {
ProjectHelper helper = (ProjectHelper) it.next();
if (helper.supportsBuildFile(buildFile)) {
if (DEBUG) {
System.out.println("ProjectHelper "
+ helper.getClass().getName() + " selected for the file "
+ buildFile);
}
return helper;
}
}
throw new RuntimeException("BUG: at least the ProjectHelper2 should have supported the file " + buildFile);
}

/**
* Get an iterator on the list of project helpers configured. The iterator
* will always return at least one element as there will always be the
* default project helper configured.
*
* @return an iterator of {@link ProjectHelper}
*/
public Iterator getHelpers() {
return helpers.iterator();
}
}

+ 14
- 1
src/main/org/apache/tools/ant/taskdefs/Ant.java View File

@@ -359,7 +359,7 @@ public class Ant extends Task {
overrideProperties();

if (antFile == null) {
antFile = Main.DEFAULT_BUILD_FILENAME;
antFile = getDefaultBuildFile();
}

File file = FILE_UTILS.resolveFile(dir, antFile);
@@ -469,6 +469,19 @@ public class Ant extends Task {
}
}

/**
* Get the default build file name to use when launching the task.
* <p>
* This function may be overrided by providers of custom ProjectHelper so they can implement easily their sub
* launcher.
*
* @return the name of the default file
* @since Ant 1.8.0
*/
protected String getDefaultBuildFile() {
return Main.DEFAULT_BUILD_FILENAME;
}

/**
* Override the properties in the new project with the one
* explicitly defined as nested elements here.


+ 14
- 1
src/main/org/apache/tools/ant/taskdefs/SubAnt.java View File

@@ -67,7 +67,7 @@ public class SubAnt extends Task {

private Ant ant = null;
private String subTarget = null;
private String antfile = Main.DEFAULT_BUILD_FILENAME;
private String antfile = getDefaultBuildFile();
private File genericantfile = null;
private boolean verbose = false;
private boolean inheritAll = false;
@@ -82,6 +82,19 @@ public class SubAnt extends Task {
/** the targets to call on the new project */
private Vector/*<TargetElement>*/ targets = new Vector();

/**
* Get the default build file name to use when launching the task.
* <p>
* This function may be overrided by providers of custom ProjectHelper so they can implement easily their sub
* launcher.
*
* @return the name of the default file
* @since Ant 1.8.0
*/
protected String getDefaultBuildFile() {
return Main.DEFAULT_BUILD_FILENAME;
}

/**
* Pass output sent to System.out to the new project.
*


+ 1
- 1
src/main/org/apache/tools/ant/types/Description.java View File

@@ -50,7 +50,7 @@ public class Description extends DataType {
*/
public void addText(String text) {

ProjectHelper ph = ProjectHelper.getProjectHelper();
ProjectHelper ph = (ProjectHelper) getProject().getReference(ProjectHelper.PROJECTHELPER_REFERENCE);
if (!(ph instanceof ProjectHelperImpl)) {
// New behavior for delayed task creation. Description
// will be evaluated in Project.getDescription()


Loading…
Cancel
Save