in the current project, or any referenced project. * <ant1.ant> now works by executing AntTask. * Fixed minor bug in DefaultClassloaderManager which was causing NPEs in URLClassLoader. * DefaultTaskContext now removes properties when they are set to null. (rather than throwing a NPE inside HashMap). git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272067 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -63,6 +63,8 @@ | |||||
| <exclude name="${ant1.package}/ant/Main.class"/> | <exclude name="${ant1.package}/ant/Main.class"/> | ||||
| <exclude name="${ant1.package}/ant/Task.class"/> | <exclude name="${ant1.package}/ant/Task.class"/> | ||||
| <exclude name="${ant1.package}/ant/BuildException.class"/> | <exclude name="${ant1.package}/ant/BuildException.class"/> | ||||
| <exclude name="${ant1.package}/ant/taskdefs/Ant.class"/> | |||||
| <exclude name="${ant1.package}/ant/taskdefs/CallTarget.class"/> | |||||
| <exclude name="${ant1.package}/ant/types/Path.class"/> | <exclude name="${ant1.package}/ant/types/Path.class"/> | ||||
| </patternset> | </patternset> | ||||
| @@ -12,13 +12,15 @@ | |||||
| <!-- TaskAdapter tasks --> | <!-- TaskAdapter tasks --> | ||||
| <task name="ant1.condition" | <task name="ant1.condition" | ||||
| classname="org.apache.tools.ant.Ant1CompatTaskAdapter" /> | classname="org.apache.tools.ant.Ant1CompatTaskAdapter" /> | ||||
| <!-- Tasks specialised for myrmidon --> | |||||
| <task name="ant1.ant" | |||||
| classname="org.apache.tools.ant.taskdefs.Ant" /> | |||||
| <!-- Tasks not currently supported. | <!-- Tasks not currently supported. | ||||
| <task name="ant1.antcall" | <task name="ant1.antcall" | ||||
| classname="org.apache.tools.ant.taskdefs.CallTarget" /> | classname="org.apache.tools.ant.taskdefs.CallTarget" /> | ||||
| <task name="ant1.ant" | |||||
| classname="org.apache.tools.ant.taskdefs.Ant" /> | |||||
| --> | --> | ||||
| <!-- standard ant tasks --> | <!-- standard ant tasks --> | ||||
| @@ -0,0 +1,300 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2000-2002 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs; | |||||
| import org.apache.tools.ant.Task; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.util.FileUtils; | |||||
| import org.apache.avalon.framework.configuration.DefaultConfiguration; | |||||
| import org.apache.avalon.framework.configuration.Configuration; | |||||
| import org.apache.myrmidon.interfaces.executor.Executor; | |||||
| import org.apache.myrmidon.interfaces.executor.ExecutionFrame; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import java.io.File; | |||||
| import java.util.Vector; | |||||
| import java.util.Iterator; | |||||
| /** | |||||
| * Call Ant in a sub-project. | |||||
| * | |||||
| * <pre> | |||||
| * <target name="foo" depends="init"> | |||||
| * <ant antfile="build.xml" target="bar" > | |||||
| * <property name="property1" value="aaaaa" /> | |||||
| * <property name="foo" value="baz" /> | |||||
| * </ant></SPAN> | |||||
| * </target></SPAN> | |||||
| * | |||||
| * <target name="bar" depends="init"> | |||||
| * <echo message="prop is ${property1} ${foo}" /> | |||||
| * </target> | |||||
| * </pre> | |||||
| * | |||||
| * | |||||
| * @author costin@dnt.ro | |||||
| * @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | |||||
| */ | |||||
| public class Ant extends Task { | |||||
| /** the basedir where is executed the build file */ | |||||
| private File dir = null; | |||||
| /** the build.xml file (can be absolute) in this case dir will be ignored */ | |||||
| private String antFile = null; | |||||
| /** the target to call if any */ | |||||
| private String target = null; | |||||
| /** the output */ | |||||
| private String output = null; | |||||
| /** should we inherit properties from the parent ? */ | |||||
| private boolean inheritAll = true; | |||||
| /** should we inherit references from the parent ? */ | |||||
| private boolean inheritRefs = false; | |||||
| /** the properties to pass to the new project */ | |||||
| private Vector properties = new Vector(); | |||||
| /** the references to pass to the new project */ | |||||
| private Vector references = new Vector(); | |||||
| /** | |||||
| * If true, inherit all properties from parent Project | |||||
| * If false, inherit only userProperties and those defined | |||||
| * inside the ant call itself | |||||
| */ | |||||
| public void setInheritAll(boolean value) { | |||||
| inheritAll = value; | |||||
| } | |||||
| /** | |||||
| * If true, inherit all references from parent Project | |||||
| * If false, inherit only those defined | |||||
| * inside the ant call itself | |||||
| */ | |||||
| public void setInheritRefs(boolean value) { | |||||
| inheritRefs = value; | |||||
| } | |||||
| /** | |||||
| * ... | |||||
| */ | |||||
| public void setDir(File d) { | |||||
| this.dir = d; | |||||
| } | |||||
| /** | |||||
| * set the build file, it can be either absolute or relative. | |||||
| * If it is absolute, <tt>dir</tt> will be ignored, if it is | |||||
| * relative it will be resolved relative to <tt>dir</tt>. | |||||
| */ | |||||
| public void setAntfile(String s) { | |||||
| // @note: it is a string and not a file to handle relative/absolute | |||||
| // otherwise a relative file will be resolved based on the current | |||||
| // basedir. | |||||
| this.antFile = s; | |||||
| } | |||||
| /** | |||||
| * set the target to execute. If none is defined it will | |||||
| * execute the default target of the build file | |||||
| */ | |||||
| public void setTarget(String s) { | |||||
| this.target = s; | |||||
| } | |||||
| public void setOutput(String s) { | |||||
| this.output = s; | |||||
| } | |||||
| /** create a property to pass to the new project as a 'user property' */ | |||||
| public Property createProperty() { | |||||
| Property p = new Property(true); | |||||
| properties.addElement( p ); | |||||
| return p; | |||||
| } | |||||
| /** | |||||
| * create a reference element that identifies a data type that | |||||
| * should be carried over to the new project. | |||||
| */ | |||||
| public void addReference(Reference r) { | |||||
| references.addElement(r); | |||||
| } | |||||
| /** | |||||
| * Helper class that implements the nested <reference> | |||||
| * element of <ant> and <antcall>. | |||||
| */ | |||||
| public static class Reference | |||||
| extends org.apache.tools.ant.types.Reference { | |||||
| public Reference() {super();} | |||||
| private String targetid=null; | |||||
| public void setToRefid(String targetid) { this.targetid=targetid; } | |||||
| public String getToRefid() { return targetid; } | |||||
| } | |||||
| /** | |||||
| * Called by the project to let the task do its work. This method may be | |||||
| * called more than once, if the task is invoked more than once. | |||||
| * For example, | |||||
| * if target1 and target2 both depend on target3, then running | |||||
| * "ant target1 target2" will run all tasks in target3 twice. | |||||
| * | |||||
| * @exception BuildException if something goes wrong with the build | |||||
| */ | |||||
| public void execute() throws BuildException | |||||
| { | |||||
| Object ant1project = unsetProject(); | |||||
| try | |||||
| { | |||||
| Configuration antConfig = buildAntTaskConfiguration(); | |||||
| executeTask( antConfig ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| resetProject( ant1project ); | |||||
| } | |||||
| } | |||||
| private void executeTask( Configuration antConfig ) | |||||
| { | |||||
| try | |||||
| { | |||||
| Executor executor = (Executor) m_context.getService( Executor.class ); | |||||
| ExecutionFrame frame = | |||||
| (ExecutionFrame) m_context.getService( ExecutionFrame.class ); | |||||
| executor.execute( antConfig, frame ); | |||||
| } | |||||
| catch( TaskException e ) | |||||
| { | |||||
| throw new BuildException( e ); | |||||
| } | |||||
| } | |||||
| private Configuration buildAntTaskConfiguration() | |||||
| { | |||||
| DefaultConfiguration antConfig = new DefaultConfiguration( "ant", "" ); | |||||
| antConfig.setAttribute( "inherit-all", String.valueOf( inheritAll ) ); | |||||
| // Ignore inheritRefs for now ( inheritAll == inheritRefs ) | |||||
| if ( target != null ) | |||||
| { | |||||
| antConfig.setAttribute( "target", target ); | |||||
| } | |||||
| // Get the "file" value. | |||||
| if (antFile == null) { | |||||
| antFile = "build.xml"; | |||||
| } | |||||
| if ( dir == null ) | |||||
| { | |||||
| dir = project.getBaseDir(); | |||||
| } | |||||
| File file = FileUtils.newFileUtils().resolveFile(dir, antFile); | |||||
| antFile = file.getAbsolutePath(); | |||||
| antConfig.setAttribute( "file", antFile ); | |||||
| // Add all of the properties. | |||||
| Iterator iter = properties.iterator(); | |||||
| while( iter.hasNext() ) | |||||
| { | |||||
| DefaultConfiguration param = new DefaultConfiguration( "param", "" ); | |||||
| Property property = (Property)iter.next(); | |||||
| param.setAttribute( "name", property.getName() ); | |||||
| param.setAttribute( "value", property.getValue() ); | |||||
| antConfig.addChild( param ); | |||||
| } | |||||
| return antConfig; | |||||
| } | |||||
| private void resetProject( Object ant1project ) throws BuildException | |||||
| { | |||||
| try | |||||
| { | |||||
| m_context.setProperty( "ant1.project", ant1project ); | |||||
| } | |||||
| catch( TaskException e ) | |||||
| { | |||||
| throw new BuildException( e ); | |||||
| } | |||||
| } | |||||
| private Object unsetProject() throws BuildException | |||||
| { | |||||
| Object ant1project = null; | |||||
| try | |||||
| { | |||||
| ant1project = m_context.getProperty( "ant1.project" ); | |||||
| m_context.setProperty( "ant1.project", null ); | |||||
| } | |||||
| catch( TaskException e ) | |||||
| { | |||||
| throw new BuildException( e ); | |||||
| } | |||||
| return ant1project; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,179 @@ | |||||
| /* | |||||
| * Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
| * | |||||
| * This software is published under the terms of the Apache Software License | |||||
| * version 1.1, a copy of which has been included with this distribution in | |||||
| * the LICENSE.txt file. | |||||
| */ | |||||
| package org.apache.antlib.core; | |||||
| import org.apache.myrmidon.api.AbstractTask; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.apache.myrmidon.interfaces.model.Project; | |||||
| import org.apache.myrmidon.interfaces.workspace.Workspace; | |||||
| import org.apache.myrmidon.interfaces.embeddor.Embeddor; | |||||
| import org.apache.avalon.framework.parameters.Parameters; | |||||
| import java.util.Map; | |||||
| import java.util.Iterator; | |||||
| import java.util.ArrayList; | |||||
| /** | |||||
| * Abstract base class for Tasks which execute targets. | |||||
| * | |||||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||||
| * @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | |||||
| * @version $Revision$ $Date$ | |||||
| */ | |||||
| public abstract class AbstractAntTask extends AbstractTask | |||||
| { | |||||
| /** | |||||
| * If true, inherit all properties from parent Project | |||||
| * If false, inherit only userProperties and those defined | |||||
| * inside the ant call itself | |||||
| */ | |||||
| private boolean m_inheritAll; | |||||
| /** | |||||
| * The target to process in build file. If not specified | |||||
| * will use default in specified build file. | |||||
| */ | |||||
| private String m_target; | |||||
| private final ArrayList m_parameters = new ArrayList(); | |||||
| /** | |||||
| * Specify whether should inherit properties in sub-build. | |||||
| * | |||||
| * @param inheritAll true to inherit else false | |||||
| */ | |||||
| public void setInheritAll( final boolean inheritAll ) | |||||
| { | |||||
| m_inheritAll = inheritAll; | |||||
| } | |||||
| /** | |||||
| * set the target to process. If none is defined it will | |||||
| * execute the default target of the build file | |||||
| */ | |||||
| public void setTarget( final String target ) | |||||
| { | |||||
| m_target = target; | |||||
| } | |||||
| /** | |||||
| * Add a parameter to processing of build file. | |||||
| * | |||||
| * @param param the parameter | |||||
| */ | |||||
| public void addParam( final AntParam param ) | |||||
| { | |||||
| m_parameters.add( param ); | |||||
| } | |||||
| /** | |||||
| * Execute the specified build, with specified parameters. | |||||
| * | |||||
| * @throws TaskException if an error occurs. | |||||
| */ | |||||
| public void execute() | |||||
| throws TaskException | |||||
| { | |||||
| try | |||||
| { | |||||
| Project project = getProject(); | |||||
| Embeddor embeddor = getEmbeddor(); | |||||
| final Workspace workspace = | |||||
| embeddor.createWorkspace( buildParameters() ); | |||||
| workspace.addProjectListener( embeddor.createListener("default")); | |||||
| if( null == m_target ) | |||||
| { | |||||
| m_target = project.getDefaultTargetName(); | |||||
| } | |||||
| workspace.executeProject( project, m_target ); | |||||
| } | |||||
| catch( final Exception e ) | |||||
| { | |||||
| throw new TaskException( e.toString(), e ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A convenience method for obtaining the Embeddor from the | |||||
| * TaskContext. | |||||
| * @return The Embeddor contained in the TaskContext | |||||
| * @throws TaskException if the Embeddor could not be obtained. | |||||
| */ | |||||
| protected Embeddor getEmbeddor() throws TaskException | |||||
| { | |||||
| final Embeddor embeddor = | |||||
| (Embeddor)getContext().getService( Embeddor.class ); | |||||
| return embeddor; | |||||
| } | |||||
| /** | |||||
| * Get/create/build the project containing the target to be executed. | |||||
| * Subclasses will override this method to provide different means | |||||
| * of obtaining a project to execute. | |||||
| * @return The project containing the target to execute. | |||||
| * @throws Exception If a problem occurred building the project. | |||||
| */ | |||||
| protected abstract Project getProject() throws Exception; | |||||
| /** | |||||
| * Build the parameters to pass to sub-project. | |||||
| * These include the current tasks properties | |||||
| * (if inheritall=true) and any supplied by the user. | |||||
| * | |||||
| * @return the created parameters | |||||
| */ | |||||
| private Parameters buildParameters() | |||||
| throws TaskException | |||||
| { | |||||
| final Parameters parameters = new Parameters(); | |||||
| if( m_inheritAll ) | |||||
| { | |||||
| final Map properties = getContext().getProperties(); | |||||
| final Iterator keys = properties.keySet().iterator(); | |||||
| while( keys.hasNext() ) | |||||
| { | |||||
| final String key = (String)keys.next(); | |||||
| final Object value = properties.get( key ); | |||||
| setProperty( parameters, key, value ); | |||||
| } | |||||
| } | |||||
| final int size = m_parameters.size(); | |||||
| for( int i = 0; i < size; i++ ) | |||||
| { | |||||
| final AntParam param = (AntParam)m_parameters.get( i ); | |||||
| param.validate(); | |||||
| final String name = param.getName(); | |||||
| final String value = param.getValue().toString(); | |||||
| setProperty( parameters, name, value ); | |||||
| } | |||||
| return parameters; | |||||
| } | |||||
| /** | |||||
| * Utility method to add the property into parameters object. | |||||
| * | |||||
| * @param parameters where to put property | |||||
| * @param name the property | |||||
| * @param value the value of property | |||||
| * @todo allow non-string params to be passed down | |||||
| */ | |||||
| private void setProperty( final Parameters parameters, | |||||
| final String name, | |||||
| final Object value ) | |||||
| { | |||||
| if( !name.startsWith( "myrmidon." ) ) | |||||
| { | |||||
| parameters.setParameter( name, value.toString() ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,68 @@ | |||||
| /* | |||||
| * Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
| * | |||||
| * This software is published under the terms of the Apache Software License | |||||
| * version 1.1, a copy of which has been included with this distribution in | |||||
| * the LICENSE.txt file. | |||||
| */ | |||||
| package org.apache.antlib.core; | |||||
| import org.apache.avalon.excalibur.i18n.ResourceManager; | |||||
| import org.apache.avalon.excalibur.i18n.Resources; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.apache.myrmidon.interfaces.model.Project; | |||||
| /** | |||||
| * A task which executes a target in the current project, | |||||
| * or a referenced project. | |||||
| * | |||||
| * @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | |||||
| * @version $Revision$ $Date$ | |||||
| * @ant.task name="ant-call" | |||||
| */ | |||||
| public class AntCallTask extends AbstractAntTask | |||||
| { | |||||
| private final static Resources REZ = | |||||
| ResourceManager.getPackageResources( AntCallTask.class ); | |||||
| private String m_project; | |||||
| /** | |||||
| * Specifies the project to execute. If not specified, the current | |||||
| * project is used. | |||||
| * @param project the name of the Project to execute. | |||||
| */ | |||||
| public void setProject( String project ) | |||||
| { | |||||
| m_project = project; | |||||
| } | |||||
| /** | |||||
| * Get/create/build the project which will be executed. | |||||
| * Subclasses will override this method to provide different means | |||||
| * of obtaining a project to execute. | |||||
| * @return The project containing the target to execute. | |||||
| * @throws Exception If a problem occurred building the project. | |||||
| */ | |||||
| protected Project getProject() throws Exception | |||||
| { | |||||
| Project currentProject = | |||||
| (Project)getContext().getService( Project.class ); | |||||
| // By default, use the current project. | |||||
| Project referencedProject = currentProject; | |||||
| if( m_project != null ) | |||||
| { | |||||
| referencedProject = currentProject.getProject( m_project ); | |||||
| if( referencedProject == null ) | |||||
| { | |||||
| final String message = | |||||
| REZ.getString( "antcall.invalid-project.error" ); | |||||
| throw new TaskException( message ); | |||||
| } | |||||
| } | |||||
| return referencedProject; | |||||
| } | |||||
| } | |||||
| @@ -8,66 +8,35 @@ | |||||
| package org.apache.antlib.core; | package org.apache.antlib.core; | ||||
| import java.io.File; | import java.io.File; | ||||
| import java.util.ArrayList; | |||||
| import java.util.Iterator; | |||||
| import java.util.Map; | |||||
| import org.apache.avalon.framework.parameters.Parameters; | import org.apache.avalon.framework.parameters.Parameters; | ||||
| import org.apache.myrmidon.api.AbstractTask; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.apache.myrmidon.interfaces.embeddor.Embeddor; | |||||
| import org.apache.myrmidon.interfaces.model.Project; | import org.apache.myrmidon.interfaces.model.Project; | ||||
| import org.apache.myrmidon.interfaces.workspace.Workspace; | |||||
| /** | /** | ||||
| * Create a new Workspace and process a build in | |||||
| * that new workspace. | |||||
| * Executes a target in a named build file. | |||||
| * | * | ||||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | * @author <a href="mailto:peter@apache.org">Peter Donald</a> | ||||
| * @ant.task name="ant" | * @ant.task name="ant" | ||||
| */ | */ | ||||
| public class AntTask | public class AntTask | ||||
| extends AbstractTask | |||||
| extends AbstractAntTask | |||||
| { | { | ||||
| /** | /** | ||||
| * Default build file. | * Default build file. | ||||
| */ | */ | ||||
| private static final String DEFAULT_BUILD_FILE = "build.ant"; | private static final String DEFAULT_BUILD_FILE = "build.ant"; | ||||
| /** | |||||
| * If true, inherit all properties from parent Project | |||||
| * If false, inherit only userProperties and those defined | |||||
| * inside the ant call itself | |||||
| */ | |||||
| private boolean m_inheritAll; | |||||
| /** | /** | ||||
| * The build file which to execute. If not set defaults to | * The build file which to execute. If not set defaults to | ||||
| * using "build.ant" in the basedir of current project. | * using "build.ant" in the basedir of current project. | ||||
| */ | */ | ||||
| private File m_file; | private File m_file; | ||||
| /** | |||||
| * The target to process in build file. If not specified | |||||
| * will use default in specified build file. | |||||
| */ | |||||
| private String m_target; | |||||
| /** | /** | ||||
| * The "type" of the build file. By default this is null which | * The "type" of the build file. By default this is null which | ||||
| * means the type will be determined by the build file extension. | * means the type will be determined by the build file extension. | ||||
| */ | */ | ||||
| private String m_type; | private String m_type; | ||||
| private final ArrayList m_parameters = new ArrayList(); | |||||
| /** | |||||
| * Specify whether should inherit properties in sub-build. | |||||
| * | |||||
| * @param inheritAll true to inherit else false | |||||
| */ | |||||
| public void setInheritAll( final boolean inheritAll ) | |||||
| { | |||||
| m_inheritAll = inheritAll; | |||||
| } | |||||
| /** | /** | ||||
| * set the build file to process. | * set the build file to process. | ||||
| @@ -90,114 +59,21 @@ public class AntTask | |||||
| } | } | ||||
| /** | /** | ||||
| * set the target to process. If none is defined it will | |||||
| * execute the default target of the build file | |||||
| * @return The project containing the target to execute. | |||||
| * @throws Exception If a problem occurred building the project. | |||||
| */ | */ | ||||
| public void setTarget( final String target ) | |||||
| { | |||||
| m_target = target; | |||||
| } | |||||
| /** | |||||
| * Add a parameter to processing of build file. | |||||
| * | |||||
| * @param param the parameter | |||||
| */ | |||||
| public void addParam( final AntParam param ) | |||||
| { | |||||
| m_parameters.add( param ); | |||||
| } | |||||
| /** | |||||
| * Execute the specified build, with specified parameters. | |||||
| * | |||||
| * @throws TaskException if an error occurs. | |||||
| */ | |||||
| public void execute() | |||||
| throws TaskException | |||||
| protected Project getProject() throws Exception | |||||
| { | { | ||||
| if( null == m_file ) | if( null == m_file ) | ||||
| { | { | ||||
| m_file = getContext().resolveFile( DEFAULT_BUILD_FILE ); | m_file = getContext().resolveFile( DEFAULT_BUILD_FILE ); | ||||
| } | } | ||||
| final Embeddor embeddor = | |||||
| (Embeddor)getContext().getService( Embeddor.class ); | |||||
| try | |||||
| { | |||||
| final Project project = | |||||
| embeddor.createProject( m_file.toString(), | |||||
| m_type, | |||||
| new Parameters() ); | |||||
| final Workspace workspace = | |||||
| embeddor.createWorkspace( buildParameters() ); | |||||
| if( null == m_target ) | |||||
| { | |||||
| m_target = project.getDefaultTargetName(); | |||||
| } | |||||
| workspace.executeProject( project, m_target ); | |||||
| } | |||||
| catch( final Exception e ) | |||||
| { | |||||
| throw new TaskException( e.toString(), e ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Build the parameters to pass to sub-project. | |||||
| * These include the current tasks properties | |||||
| * (if inheritall=true) and any supplied by the user. | |||||
| * | |||||
| * @return the created parameters | |||||
| */ | |||||
| private Parameters buildParameters() | |||||
| throws TaskException | |||||
| { | |||||
| final Parameters parameters = new Parameters(); | |||||
| if( m_inheritAll ) | |||||
| { | |||||
| final Map properties = getContext().getProperties(); | |||||
| final Iterator keys = properties.keySet().iterator(); | |||||
| while( keys.hasNext() ) | |||||
| { | |||||
| final String key = (String)keys.next(); | |||||
| final Object value = properties.get( key ); | |||||
| setProperty( parameters, key, value ); | |||||
| } | |||||
| } | |||||
| final int size = m_parameters.size(); | |||||
| for( int i = 0; i < size; i++ ) | |||||
| { | |||||
| final AntParam param = (AntParam)m_parameters.get( i ); | |||||
| param.validate(); | |||||
| final String name = param.getName(); | |||||
| final String value = param.getValue().toString(); | |||||
| setProperty( parameters, name, value ); | |||||
| } | |||||
| return parameters; | |||||
| final Project project = | |||||
| getEmbeddor().createProject( m_file.toString(), | |||||
| m_type, | |||||
| new Parameters() ); | |||||
| return project; | |||||
| } | } | ||||
| /** | |||||
| * Utility method to add the property into parameters object. | |||||
| * | |||||
| * @param parameters where to put property | |||||
| * @param name the property | |||||
| * @param value the value of property | |||||
| * @todo allow non-string params to be passed down | |||||
| */ | |||||
| private void setProperty( final Parameters parameters, | |||||
| final String name, | |||||
| final Object value ) | |||||
| { | |||||
| if( !name.startsWith( "myrmidon." ) ) | |||||
| { | |||||
| parameters.setParameter( name, value.toString() ); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -34,4 +34,6 @@ filetokenset.not-a-file.error=File {0} does not exist, or is not a file. | |||||
| filetokenset.read-tokens.error=Could not read tokens from {0}. | filetokenset.read-tokens.error=Could not read tokens from {0}. | ||||
| param.noname.error=Missing name from parameter. | param.noname.error=Missing name from parameter. | ||||
| param.novalue.error=Missing value from parameter "{0}". | |||||
| param.novalue.error=Missing value from parameter "{0}". | |||||
| antcall.invalid-project.error=Project-reference "{0}" not found. | |||||
| @@ -155,7 +155,7 @@ public class DefaultClassLoaderManager | |||||
| private URL[] buildClasspath( final ArrayList files ) | private URL[] buildClasspath( final ArrayList files ) | ||||
| throws MalformedURLException | throws MalformedURLException | ||||
| { | { | ||||
| final URL[] urls = new URL[ files.size() + 1 ]; | |||||
| final URL[] urls = new URL[ files.size() ]; | |||||
| final int count = files.size(); | final int count = files.size(); | ||||
| for( int i = 0; i < count; i++ ) | for( int i = 0; i < count; i++ ) | ||||
| { | { | ||||
| @@ -214,7 +214,15 @@ public class DefaultTaskContext | |||||
| { | { | ||||
| checkPropertyName( name ); | checkPropertyName( name ); | ||||
| checkPropertyValid( name, value ); | checkPropertyValid( name, value ); | ||||
| m_contextData.put( name, value ); | |||||
| if ( value == null ) | |||||
| { | |||||
| m_contextData.remove( name ); | |||||
| } | |||||
| else | |||||
| { | |||||
| m_contextData.put( name, value ); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -279,6 +279,32 @@ Legal: | |||||
| <ant/> | <ant/> | ||||
| </target> | </target> | ||||
| <target name="antcall-test"> | |||||
| <log message="Testing antcall task..."/> | |||||
| <ant-call target="if-test"/> | |||||
| <log message="Using params..."/> | |||||
| <ant-call target="prop-print"> | |||||
| <param name="meep.meep" value="Meep!"/> | |||||
| </ant-call> | |||||
| <log message="Using params value-ref..."/> | |||||
| <pattern id="meep.data" name="*.java" if="..." /> | |||||
| <ant-call target="prop-print"> | |||||
| <param name="meep.meep" value-ref="meep.data"/> | |||||
| </ant-call> | |||||
| <log message="Using inheritall..."/> | |||||
| <pattern id="meep.meep" name="*.java" if="..." /> | |||||
| <ant-call target="prop-print" inherit-all="true"/> | |||||
| <log message="Calling referenced project, default target..."/> | |||||
| <ant-call project="prim"/> | |||||
| <log message="Calling referenced project, named target..."/> | |||||
| <ant-call project="prim" target="extensions-test"/> | |||||
| </target> | |||||
| <target name="prop-print"> | <target name="prop-print"> | ||||
| <log message="Give me a property ... ${meep.meep}"/> | <log message="Give me a property ... ${meep.meep}"/> | ||||
| </target> | </target> | ||||