git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270165 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -1,551 +0,0 @@ | |||
| /* | |||
| * 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 file. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import java.io.File; | |||
| import java.io.FileOutputStream; | |||
| import java.io.IOException; | |||
| import java.io.PrintStream; | |||
| import java.lang.reflect.Method; | |||
| import java.util.Enumeration; | |||
| import java.util.Hashtable; | |||
| import java.util.Vector; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.BuildListener; | |||
| import org.apache.tools.ant.DefaultLogger; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.ProjectComponent; | |||
| import org.apache.tools.ant.ProjectHelper; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| /** | |||
| * 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 | |||
| */ | |||
| 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(); | |||
| /** | |||
| * the temporary project created to run the build file | |||
| */ | |||
| private Project newProject; | |||
| /** | |||
| * 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> . | |||
| * | |||
| * @param s The new Antfile value | |||
| */ | |||
| 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; | |||
| } | |||
| /** | |||
| * ... | |||
| * | |||
| * @param d The new Dir value | |||
| */ | |||
| public void setDir( File d ) | |||
| { | |||
| this.dir = d; | |||
| } | |||
| /** | |||
| * If true, inherit all properties from parent Project If false, inherit | |||
| * only userProperties and those defined inside the ant call itself | |||
| * | |||
| * @param value The new InheritAll value | |||
| */ | |||
| 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 | |||
| * | |||
| * @param value The new InheritRefs value | |||
| */ | |||
| public void setInheritRefs( boolean value ) | |||
| { | |||
| inheritRefs = value; | |||
| } | |||
| public void setOutput( String s ) | |||
| { | |||
| this.output = s; | |||
| } | |||
| /** | |||
| * set the target to execute. If none is defined it will execute the default | |||
| * target of the build file | |||
| * | |||
| * @param s The new Target value | |||
| */ | |||
| public void setTarget( String s ) | |||
| { | |||
| this.target = s; | |||
| } | |||
| /** | |||
| * create a reference element that identifies a data type that should be | |||
| * carried over to the new project. | |||
| * | |||
| * @param r The feature to be added to the Reference attribute | |||
| */ | |||
| public void addReference( Reference r ) | |||
| { | |||
| references.addElement( r ); | |||
| } | |||
| /** | |||
| * create a property to pass to the new project as a 'user property' | |||
| * | |||
| * @return Description of the Returned Value | |||
| */ | |||
| public Property createProperty() | |||
| { | |||
| if( newProject == null ) | |||
| { | |||
| reinit(); | |||
| } | |||
| Property p = new Property( true ); | |||
| p.setProject( newProject ); | |||
| p.setTaskName( "property" ); | |||
| properties.addElement( p ); | |||
| return p; | |||
| } | |||
| /** | |||
| * Do the execution. | |||
| * | |||
| * @exception TaskException Description of Exception | |||
| */ | |||
| public void execute() | |||
| throws TaskException | |||
| { | |||
| try | |||
| { | |||
| if( newProject == null ) | |||
| { | |||
| reinit(); | |||
| } | |||
| if( ( dir == null ) && ( inheritAll == true ) ) | |||
| { | |||
| dir = project.getBaseDir(); | |||
| } | |||
| initializeProject(); | |||
| if( dir != null ) | |||
| { | |||
| newProject.setBaseDir( dir ); | |||
| newProject.setUserProperty( "basedir", dir.getAbsolutePath() ); | |||
| } | |||
| else | |||
| { | |||
| dir = project.getBaseDir(); | |||
| } | |||
| overrideProperties(); | |||
| if( antFile == null ) | |||
| { | |||
| antFile = "build.xml"; | |||
| } | |||
| File file = FileUtils.newFileUtils().resolveFile( dir, antFile ); | |||
| antFile = file.getAbsolutePath(); | |||
| newProject.setUserProperty( "ant.file", antFile ); | |||
| ProjectHelper.configureProject( newProject, new File( antFile ) ); | |||
| if( target == null ) | |||
| { | |||
| target = newProject.getDefaultTarget(); | |||
| } | |||
| addReferences(); | |||
| // Are we trying to call the target in which we are defined? | |||
| if( newProject.getBaseDir().equals( project.getBaseDir() ) && | |||
| newProject.getProperty( "ant.file" ).equals( project.getProperty( "ant.file" ) ) && | |||
| getOwningTarget() != null && | |||
| target.equals( this.getOwningTarget().getName() ) ) | |||
| { | |||
| throw new TaskException( "ant task calling its own parent target" ); | |||
| } | |||
| newProject.executeTarget( target ); | |||
| } | |||
| finally | |||
| { | |||
| // help the gc | |||
| newProject = null; | |||
| } | |||
| } | |||
| public void init() | |||
| { | |||
| newProject = new Project(); | |||
| newProject.setJavaVersionProperty(); | |||
| newProject.addTaskDefinition( "property", | |||
| ( Class )project.getTaskDefinitions().get( "property" ) ); | |||
| } | |||
| protected void handleErrorOutput( String line ) | |||
| { | |||
| if( newProject != null ) | |||
| { | |||
| newProject.demuxOutput( line, true ); | |||
| } | |||
| else | |||
| { | |||
| super.handleErrorOutput( line ); | |||
| } | |||
| } | |||
| protected void handleOutput( String line ) | |||
| { | |||
| if( newProject != null ) | |||
| { | |||
| newProject.demuxOutput( line, false ); | |||
| } | |||
| else | |||
| { | |||
| super.handleOutput( line ); | |||
| } | |||
| } | |||
| /** | |||
| * Add the references explicitly defined as nested elements to the new | |||
| * project. Also copy over all references that don't override existing | |||
| * references in the new project if inheritall has been requested. | |||
| * | |||
| * @exception TaskException Description of Exception | |||
| */ | |||
| private void addReferences() | |||
| throws TaskException | |||
| { | |||
| Hashtable thisReferences = ( Hashtable )project.getReferences().clone(); | |||
| Hashtable newReferences = newProject.getReferences(); | |||
| Enumeration e; | |||
| if( references.size() > 0 ) | |||
| { | |||
| for( e = references.elements(); e.hasMoreElements(); ) | |||
| { | |||
| Reference ref = ( Reference )e.nextElement(); | |||
| String refid = ref.getRefId(); | |||
| if( refid == null ) | |||
| { | |||
| throw new TaskException( "the refid attribute is required for reference elements" ); | |||
| } | |||
| if( !thisReferences.containsKey( refid ) ) | |||
| { | |||
| log( "Parent project doesn't contain any reference '" | |||
| + refid + "'", | |||
| Project.MSG_WARN ); | |||
| continue; | |||
| } | |||
| Object o = thisReferences.remove( refid ); | |||
| String toRefid = ref.getToRefid(); | |||
| if( toRefid == null ) | |||
| { | |||
| toRefid = refid; | |||
| } | |||
| copyReference( refid, toRefid ); | |||
| } | |||
| } | |||
| // Now add all references that are not defined in the | |||
| // subproject, if inheritRefs is true | |||
| if( inheritRefs ) | |||
| { | |||
| for( e = thisReferences.keys(); e.hasMoreElements(); ) | |||
| { | |||
| String key = ( String )e.nextElement(); | |||
| if( newReferences.containsKey( key ) ) | |||
| { | |||
| continue; | |||
| } | |||
| copyReference( key, key ); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Try to clone and reconfigure the object referenced by oldkey in the | |||
| * parent project and add it to the new project with the key newkey. <p> | |||
| * | |||
| * If we cannot clone it, copy the referenced object itself and keep our | |||
| * fingers crossed.</p> | |||
| * | |||
| * @param oldKey Description of Parameter | |||
| * @param newKey Description of Parameter | |||
| */ | |||
| private void copyReference( String oldKey, String newKey ) | |||
| { | |||
| Object orig = project.getReference( oldKey ); | |||
| Class c = orig.getClass(); | |||
| Object copy = orig; | |||
| try | |||
| { | |||
| Method cloneM = c.getMethod( "clone", new Class[0] ); | |||
| if( cloneM != null ) | |||
| { | |||
| copy = cloneM.invoke( orig, new Object[0] ); | |||
| } | |||
| } | |||
| catch( Exception e ) | |||
| { | |||
| // not Clonable | |||
| } | |||
| if( copy instanceof ProjectComponent ) | |||
| { | |||
| ( ( ProjectComponent )copy ).setProject( newProject ); | |||
| } | |||
| else | |||
| { | |||
| try | |||
| { | |||
| Method setProjectM = | |||
| c.getMethod( "setProject", new Class[]{Project.class} ); | |||
| if( setProjectM != null ) | |||
| { | |||
| setProjectM.invoke( copy, new Object[]{newProject} ); | |||
| } | |||
| } | |||
| catch( NoSuchMethodException e ) | |||
| { | |||
| // ignore this if the class being referenced does not have | |||
| // a set project method. | |||
| } | |||
| catch( Exception e2 ) | |||
| { | |||
| String msg = "Error setting new project instance for reference with id " | |||
| + oldKey; | |||
| throw new TaskException( msg, e2, location ); | |||
| } | |||
| } | |||
| newProject.addReference( newKey, copy ); | |||
| } | |||
| private void initializeProject() | |||
| { | |||
| Vector listeners = project.getBuildListeners(); | |||
| for( int i = 0; i < listeners.size(); i++ ) | |||
| { | |||
| newProject.addBuildListener( ( BuildListener )listeners.elementAt( i ) ); | |||
| } | |||
| if( output != null ) | |||
| { | |||
| try | |||
| { | |||
| PrintStream out = new PrintStream( new FileOutputStream( output ) ); | |||
| DefaultLogger logger = new DefaultLogger(); | |||
| logger.setMessageOutputLevel( Project.MSG_INFO ); | |||
| logger.setOutputPrintStream( out ); | |||
| logger.setErrorPrintStream( out ); | |||
| newProject.addBuildListener( logger ); | |||
| } | |||
| catch( IOException ex ) | |||
| { | |||
| log( "Ant: Can't set output to " + output ); | |||
| } | |||
| } | |||
| Hashtable taskdefs = project.getTaskDefinitions(); | |||
| Enumeration et = taskdefs.keys(); | |||
| while( et.hasMoreElements() ) | |||
| { | |||
| String taskName = ( String )et.nextElement(); | |||
| if( taskName.equals( "property" ) ) | |||
| { | |||
| // we have already added this taskdef in #init | |||
| continue; | |||
| } | |||
| Class taskClass = ( Class )taskdefs.get( taskName ); | |||
| newProject.addTaskDefinition( taskName, taskClass ); | |||
| } | |||
| Hashtable typedefs = project.getDataTypeDefinitions(); | |||
| Enumeration e = typedefs.keys(); | |||
| while( e.hasMoreElements() ) | |||
| { | |||
| String typeName = ( String )e.nextElement(); | |||
| Class typeClass = ( Class )typedefs.get( typeName ); | |||
| newProject.addDataTypeDefinition( typeName, typeClass ); | |||
| } | |||
| // set user-defined or all properties from calling project | |||
| Hashtable prop1; | |||
| if( inheritAll == true ) | |||
| { | |||
| prop1 = project.getProperties(); | |||
| } | |||
| else | |||
| { | |||
| prop1 = project.getUserProperties(); | |||
| // set Java built-in properties separately, | |||
| // b/c we won't inherit them. | |||
| newProject.setSystemProperties(); | |||
| } | |||
| e = prop1.keys(); | |||
| while( e.hasMoreElements() ) | |||
| { | |||
| String arg = ( String )e.nextElement(); | |||
| if( "basedir".equals( arg ) || "ant.file".equals( arg ) ) | |||
| { | |||
| // basedir and ant.file get special treatment in execute() | |||
| continue; | |||
| } | |||
| String value = ( String )prop1.get( arg ); | |||
| if( inheritAll == true ) | |||
| { | |||
| newProject.setProperty( arg, value ); | |||
| } | |||
| else | |||
| { | |||
| newProject.setUserProperty( arg, value ); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Override the properties in the new project with the one explicitly | |||
| * defined as nested elements here. | |||
| * | |||
| * @exception TaskException Description of Exception | |||
| */ | |||
| private void overrideProperties() | |||
| throws TaskException | |||
| { | |||
| Enumeration e = properties.elements(); | |||
| while( e.hasMoreElements() ) | |||
| { | |||
| Property p = ( Property )e.nextElement(); | |||
| p.setProject( newProject ); | |||
| p.execute(); | |||
| } | |||
| } | |||
| private void reinit() | |||
| { | |||
| init(); | |||
| for( int i = 0; i < properties.size(); i++ ) | |||
| { | |||
| Property p = ( Property )properties.elementAt( i ); | |||
| Property newP = ( Property )newProject.createTask( "property" ); | |||
| newP.setName( p.getName() ); | |||
| if( p.getValue() != null ) | |||
| { | |||
| newP.setValue( p.getValue() ); | |||
| } | |||
| if( p.getFile() != null ) | |||
| { | |||
| newP.setFile( p.getFile() ); | |||
| } | |||
| if( p.getResource() != null ) | |||
| { | |||
| newP.setResource( p.getResource() ); | |||
| } | |||
| properties.setElementAt( newP, i ); | |||
| } | |||
| } | |||
| /** | |||
| * Helper class that implements the nested <reference> element of | |||
| * <ant> and <antcall>. | |||
| * | |||
| * @author RT | |||
| */ | |||
| public static class Reference | |||
| extends org.apache.tools.ant.types.Reference | |||
| { | |||
| private String targetid = null; | |||
| public Reference() | |||
| { | |||
| super(); | |||
| } | |||
| public void setToRefid( String targetid ) | |||
| { | |||
| this.targetid = targetid; | |||
| } | |||
| public String getToRefid() | |||
| { | |||
| return targetid; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,124 +0,0 @@ | |||
| /* | |||
| * 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 file. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Task; | |||
| /** | |||
| * Call another target in the same project. <pre> | |||
| * <target name="foo"> | |||
| * <antcall target="bar"> | |||
| * <param name="property1" value="aaaaa" /> | |||
| * <param name="foo" value="baz" /> | |||
| * </antcall> | |||
| * </target> | |||
| * | |||
| * <target name="bar" depends="init"> | |||
| * <echo message="prop is ${property1} ${foo}" /> | |||
| * </target> | |||
| * </pre> <p> | |||
| * | |||
| * This only works as expected if neither property1 nor foo are defined in the | |||
| * project itself. | |||
| * | |||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| */ | |||
| public class CallTarget extends Task | |||
| { | |||
| private boolean initialized = false; | |||
| private boolean inheritAll = true; | |||
| private Ant callee; | |||
| private String subTarget; | |||
| /** | |||
| * If true, inherit all properties from parent Project If false, inherit | |||
| * only userProperties and those defined inside the antcall call itself | |||
| * | |||
| * @param inherit The new InheritAll value | |||
| */ | |||
| public void setInheritAll( boolean inherit ) | |||
| { | |||
| inheritAll = inherit; | |||
| } | |||
| public void setTarget( String target ) | |||
| { | |||
| subTarget = target; | |||
| } | |||
| /** | |||
| * create a reference element that identifies a data type that should be | |||
| * carried over to the new project. | |||
| * | |||
| * @param r The feature to be added to the Reference attribute | |||
| */ | |||
| public void addReference( Ant.Reference r ) | |||
| { | |||
| callee.addReference( r ); | |||
| } | |||
| public Property createParam() | |||
| { | |||
| return callee.createProperty(); | |||
| } | |||
| public void execute() | |||
| { | |||
| if( !initialized ) | |||
| { | |||
| init(); | |||
| } | |||
| if( subTarget == null ) | |||
| { | |||
| throw new BuildException( "Attribute target is required." ); | |||
| } | |||
| callee.setDir( project.getBaseDir() ); | |||
| callee.setAntfile( project.getProperty( "ant.file" ) ); | |||
| callee.setTarget( subTarget ); | |||
| callee.setInheritAll( inheritAll ); | |||
| callee.execute(); | |||
| }//-- setInheritAll | |||
| public void init() | |||
| { | |||
| callee = ( Ant )project.createTask( "ant" ); | |||
| callee.setOwningTarget( target ); | |||
| callee.setTaskName( getTaskName() ); | |||
| callee.setLocation( location ); | |||
| callee.init(); | |||
| initialized = true; | |||
| } | |||
| protected void handleErrorOutput( String line ) | |||
| { | |||
| if( callee != null ) | |||
| { | |||
| callee.handleErrorOutput( line ); | |||
| } | |||
| else | |||
| { | |||
| super.handleErrorOutput( line ); | |||
| } | |||
| } | |||
| protected void handleOutput( String line ) | |||
| { | |||
| if( callee != null ) | |||
| { | |||
| callee.handleOutput( line ); | |||
| } | |||
| else | |||
| { | |||
| super.handleOutput( line ); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,215 +0,0 @@ | |||
| /* | |||
| * 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 file. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Enumeration; | |||
| import java.util.Properties; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.tools.ant.AntClassLoader; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.types.Path; | |||
| import org.apache.tools.ant.types.Reference; | |||
| /** | |||
| * Base class for Taskdef and Typedef - does all the classpath handling and and | |||
| * class loading. | |||
| * | |||
| * @author Costin Manolache | |||
| * @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| */ | |||
| public abstract class Definer extends Task | |||
| { | |||
| private boolean reverseLoader = false; | |||
| private Path classpath; | |||
| private File file; | |||
| private String name; | |||
| private String resource; | |||
| private String value; | |||
| public void setClassname( String v ) | |||
| { | |||
| value = v; | |||
| } | |||
| public void setClasspath( Path classpath ) | |||
| { | |||
| if( this.classpath == null ) | |||
| { | |||
| this.classpath = classpath; | |||
| } | |||
| else | |||
| { | |||
| this.classpath.append( classpath ); | |||
| } | |||
| } | |||
| public void setClasspathRef( Reference r ) | |||
| { | |||
| createClasspath().setRefid( r ); | |||
| } | |||
| public void setFile( File file ) | |||
| { | |||
| this.file = file; | |||
| } | |||
| public void setName( String name ) | |||
| { | |||
| this.name = name; | |||
| } | |||
| public void setResource( String res ) | |||
| { | |||
| this.resource = res; | |||
| } | |||
| public String getClassname() | |||
| { | |||
| return value; | |||
| } | |||
| public Path createClasspath() | |||
| { | |||
| if( this.classpath == null ) | |||
| { | |||
| this.classpath = new Path( project ); | |||
| } | |||
| return this.classpath.createPath(); | |||
| } | |||
| public void execute() | |||
| throws TaskException | |||
| { | |||
| AntClassLoader al = createLoader(); | |||
| if( file == null && resource == null ) | |||
| { | |||
| // simple case - one definition | |||
| if( name == null || value == null ) | |||
| { | |||
| String msg = "name or classname attributes of " | |||
| + getTaskName() + " element " | |||
| + "are undefined"; | |||
| throw new TaskException( msg ); | |||
| } | |||
| addDefinition( al, name, value ); | |||
| } | |||
| else | |||
| { | |||
| try | |||
| { | |||
| if( name != null || value != null ) | |||
| { | |||
| String msg = "You must not specify name or value " | |||
| + "together with file or resource."; | |||
| throw new TaskException( msg ); | |||
| } | |||
| if( file != null && resource != null ) | |||
| { | |||
| String msg = "You must not specify both, file and resource."; | |||
| throw new TaskException( msg ); | |||
| } | |||
| Properties props = new Properties(); | |||
| InputStream is = null; | |||
| if( file != null ) | |||
| { | |||
| log( "Loading definitions from file " + file, | |||
| Project.MSG_VERBOSE ); | |||
| is = new FileInputStream( file ); | |||
| if( is == null ) | |||
| { | |||
| log( "Could not load definitions from file " + file | |||
| + ". It doesn\'t exist.", Project.MSG_WARN ); | |||
| } | |||
| } | |||
| if( resource != null ) | |||
| { | |||
| log( "Loading definitions from resource " + resource, | |||
| Project.MSG_VERBOSE ); | |||
| is = al.getResourceAsStream( resource ); | |||
| if( is == null ) | |||
| { | |||
| log( "Could not load definitions from resource " | |||
| + resource + ". It could not be found.", | |||
| Project.MSG_WARN ); | |||
| } | |||
| } | |||
| if( is != null ) | |||
| { | |||
| props.load( is ); | |||
| Enumeration keys = props.keys(); | |||
| while( keys.hasMoreElements() ) | |||
| { | |||
| String n = (String)keys.nextElement(); | |||
| String v = props.getProperty( n ); | |||
| addDefinition( al, n, v ); | |||
| } | |||
| } | |||
| } | |||
| catch( IOException ex ) | |||
| { | |||
| throw new TaskException( "Error", ex ); | |||
| } | |||
| } | |||
| } | |||
| protected abstract void addDefinition( String name, Class c ); | |||
| private void addDefinition( ClassLoader al, String name, String value ) | |||
| throws TaskException | |||
| { | |||
| try | |||
| { | |||
| Class c = al.loadClass( value ); | |||
| AntClassLoader.initializeClass( c ); | |||
| addDefinition( name, c ); | |||
| } | |||
| catch( ClassNotFoundException cnfe ) | |||
| { | |||
| String msg = getTaskName() + " class " + value + | |||
| " cannot be found"; | |||
| throw new TaskException( msg, cnfe ); | |||
| } | |||
| catch( NoClassDefFoundError ncdfe ) | |||
| { | |||
| String msg = getTaskName() + " class " + value + | |||
| " cannot be found"; | |||
| throw new TaskException( msg, ncdfe ); | |||
| } | |||
| } | |||
| private AntClassLoader createLoader() | |||
| throws TaskException | |||
| { | |||
| AntClassLoader al = null; | |||
| if( classpath != null ) | |||
| { | |||
| al = new AntClassLoader( project, classpath, !reverseLoader ); | |||
| } | |||
| else | |||
| { | |||
| al = new AntClassLoader( project, Path.systemClasspath, !reverseLoader ); | |||
| } | |||
| // need to load Task via system classloader or the new | |||
| // task we want to define will never be a Task but always | |||
| // be wrapped into a TaskAdapter. | |||
| al.addSystemPackageRoot( "org.apache.tools.ant" ); | |||
| return al; | |||
| } | |||
| } | |||
| @@ -1,23 +0,0 @@ | |||
| /* | |||
| * 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 file. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import org.apache.tools.ant.BuildException; | |||
| /** | |||
| * Define a new task. | |||
| * | |||
| * @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| */ | |||
| public class Taskdef extends Definer | |||
| { | |||
| protected void addDefinition( String name, Class c ) | |||
| throws BuildException | |||
| { | |||
| project.addTaskDefinition( name, c ); | |||
| } | |||
| } | |||
| @@ -1,23 +0,0 @@ | |||
| /* | |||
| * 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 file. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import org.apache.tools.ant.BuildException; | |||
| /** | |||
| * Define a new data type. | |||
| * | |||
| * @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| */ | |||
| public class Typedef extends Definer | |||
| { | |||
| protected void addDefinition( String name, Class c ) | |||
| throws BuildException | |||
| { | |||
| project.addDataTypeDefinition( name, c ); | |||
| } | |||
| } | |||
| @@ -1,551 +0,0 @@ | |||
| /* | |||
| * 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 file. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import java.io.File; | |||
| import java.io.FileOutputStream; | |||
| import java.io.IOException; | |||
| import java.io.PrintStream; | |||
| import java.lang.reflect.Method; | |||
| import java.util.Enumeration; | |||
| import java.util.Hashtable; | |||
| import java.util.Vector; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.BuildListener; | |||
| import org.apache.tools.ant.DefaultLogger; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.ProjectComponent; | |||
| import org.apache.tools.ant.ProjectHelper; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| /** | |||
| * 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 | |||
| */ | |||
| 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(); | |||
| /** | |||
| * the temporary project created to run the build file | |||
| */ | |||
| private Project newProject; | |||
| /** | |||
| * 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> . | |||
| * | |||
| * @param s The new Antfile value | |||
| */ | |||
| 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; | |||
| } | |||
| /** | |||
| * ... | |||
| * | |||
| * @param d The new Dir value | |||
| */ | |||
| public void setDir( File d ) | |||
| { | |||
| this.dir = d; | |||
| } | |||
| /** | |||
| * If true, inherit all properties from parent Project If false, inherit | |||
| * only userProperties and those defined inside the ant call itself | |||
| * | |||
| * @param value The new InheritAll value | |||
| */ | |||
| 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 | |||
| * | |||
| * @param value The new InheritRefs value | |||
| */ | |||
| public void setInheritRefs( boolean value ) | |||
| { | |||
| inheritRefs = value; | |||
| } | |||
| public void setOutput( String s ) | |||
| { | |||
| this.output = s; | |||
| } | |||
| /** | |||
| * set the target to execute. If none is defined it will execute the default | |||
| * target of the build file | |||
| * | |||
| * @param s The new Target value | |||
| */ | |||
| public void setTarget( String s ) | |||
| { | |||
| this.target = s; | |||
| } | |||
| /** | |||
| * create a reference element that identifies a data type that should be | |||
| * carried over to the new project. | |||
| * | |||
| * @param r The feature to be added to the Reference attribute | |||
| */ | |||
| public void addReference( Reference r ) | |||
| { | |||
| references.addElement( r ); | |||
| } | |||
| /** | |||
| * create a property to pass to the new project as a 'user property' | |||
| * | |||
| * @return Description of the Returned Value | |||
| */ | |||
| public Property createProperty() | |||
| { | |||
| if( newProject == null ) | |||
| { | |||
| reinit(); | |||
| } | |||
| Property p = new Property( true ); | |||
| p.setProject( newProject ); | |||
| p.setTaskName( "property" ); | |||
| properties.addElement( p ); | |||
| return p; | |||
| } | |||
| /** | |||
| * Do the execution. | |||
| * | |||
| * @exception TaskException Description of Exception | |||
| */ | |||
| public void execute() | |||
| throws TaskException | |||
| { | |||
| try | |||
| { | |||
| if( newProject == null ) | |||
| { | |||
| reinit(); | |||
| } | |||
| if( ( dir == null ) && ( inheritAll == true ) ) | |||
| { | |||
| dir = project.getBaseDir(); | |||
| } | |||
| initializeProject(); | |||
| if( dir != null ) | |||
| { | |||
| newProject.setBaseDir( dir ); | |||
| newProject.setUserProperty( "basedir", dir.getAbsolutePath() ); | |||
| } | |||
| else | |||
| { | |||
| dir = project.getBaseDir(); | |||
| } | |||
| overrideProperties(); | |||
| if( antFile == null ) | |||
| { | |||
| antFile = "build.xml"; | |||
| } | |||
| File file = FileUtils.newFileUtils().resolveFile( dir, antFile ); | |||
| antFile = file.getAbsolutePath(); | |||
| newProject.setUserProperty( "ant.file", antFile ); | |||
| ProjectHelper.configureProject( newProject, new File( antFile ) ); | |||
| if( target == null ) | |||
| { | |||
| target = newProject.getDefaultTarget(); | |||
| } | |||
| addReferences(); | |||
| // Are we trying to call the target in which we are defined? | |||
| if( newProject.getBaseDir().equals( project.getBaseDir() ) && | |||
| newProject.getProperty( "ant.file" ).equals( project.getProperty( "ant.file" ) ) && | |||
| getOwningTarget() != null && | |||
| target.equals( this.getOwningTarget().getName() ) ) | |||
| { | |||
| throw new TaskException( "ant task calling its own parent target" ); | |||
| } | |||
| newProject.executeTarget( target ); | |||
| } | |||
| finally | |||
| { | |||
| // help the gc | |||
| newProject = null; | |||
| } | |||
| } | |||
| public void init() | |||
| { | |||
| newProject = new Project(); | |||
| newProject.setJavaVersionProperty(); | |||
| newProject.addTaskDefinition( "property", | |||
| ( Class )project.getTaskDefinitions().get( "property" ) ); | |||
| } | |||
| protected void handleErrorOutput( String line ) | |||
| { | |||
| if( newProject != null ) | |||
| { | |||
| newProject.demuxOutput( line, true ); | |||
| } | |||
| else | |||
| { | |||
| super.handleErrorOutput( line ); | |||
| } | |||
| } | |||
| protected void handleOutput( String line ) | |||
| { | |||
| if( newProject != null ) | |||
| { | |||
| newProject.demuxOutput( line, false ); | |||
| } | |||
| else | |||
| { | |||
| super.handleOutput( line ); | |||
| } | |||
| } | |||
| /** | |||
| * Add the references explicitly defined as nested elements to the new | |||
| * project. Also copy over all references that don't override existing | |||
| * references in the new project if inheritall has been requested. | |||
| * | |||
| * @exception TaskException Description of Exception | |||
| */ | |||
| private void addReferences() | |||
| throws TaskException | |||
| { | |||
| Hashtable thisReferences = ( Hashtable )project.getReferences().clone(); | |||
| Hashtable newReferences = newProject.getReferences(); | |||
| Enumeration e; | |||
| if( references.size() > 0 ) | |||
| { | |||
| for( e = references.elements(); e.hasMoreElements(); ) | |||
| { | |||
| Reference ref = ( Reference )e.nextElement(); | |||
| String refid = ref.getRefId(); | |||
| if( refid == null ) | |||
| { | |||
| throw new TaskException( "the refid attribute is required for reference elements" ); | |||
| } | |||
| if( !thisReferences.containsKey( refid ) ) | |||
| { | |||
| log( "Parent project doesn't contain any reference '" | |||
| + refid + "'", | |||
| Project.MSG_WARN ); | |||
| continue; | |||
| } | |||
| Object o = thisReferences.remove( refid ); | |||
| String toRefid = ref.getToRefid(); | |||
| if( toRefid == null ) | |||
| { | |||
| toRefid = refid; | |||
| } | |||
| copyReference( refid, toRefid ); | |||
| } | |||
| } | |||
| // Now add all references that are not defined in the | |||
| // subproject, if inheritRefs is true | |||
| if( inheritRefs ) | |||
| { | |||
| for( e = thisReferences.keys(); e.hasMoreElements(); ) | |||
| { | |||
| String key = ( String )e.nextElement(); | |||
| if( newReferences.containsKey( key ) ) | |||
| { | |||
| continue; | |||
| } | |||
| copyReference( key, key ); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Try to clone and reconfigure the object referenced by oldkey in the | |||
| * parent project and add it to the new project with the key newkey. <p> | |||
| * | |||
| * If we cannot clone it, copy the referenced object itself and keep our | |||
| * fingers crossed.</p> | |||
| * | |||
| * @param oldKey Description of Parameter | |||
| * @param newKey Description of Parameter | |||
| */ | |||
| private void copyReference( String oldKey, String newKey ) | |||
| { | |||
| Object orig = project.getReference( oldKey ); | |||
| Class c = orig.getClass(); | |||
| Object copy = orig; | |||
| try | |||
| { | |||
| Method cloneM = c.getMethod( "clone", new Class[0] ); | |||
| if( cloneM != null ) | |||
| { | |||
| copy = cloneM.invoke( orig, new Object[0] ); | |||
| } | |||
| } | |||
| catch( Exception e ) | |||
| { | |||
| // not Clonable | |||
| } | |||
| if( copy instanceof ProjectComponent ) | |||
| { | |||
| ( ( ProjectComponent )copy ).setProject( newProject ); | |||
| } | |||
| else | |||
| { | |||
| try | |||
| { | |||
| Method setProjectM = | |||
| c.getMethod( "setProject", new Class[]{Project.class} ); | |||
| if( setProjectM != null ) | |||
| { | |||
| setProjectM.invoke( copy, new Object[]{newProject} ); | |||
| } | |||
| } | |||
| catch( NoSuchMethodException e ) | |||
| { | |||
| // ignore this if the class being referenced does not have | |||
| // a set project method. | |||
| } | |||
| catch( Exception e2 ) | |||
| { | |||
| String msg = "Error setting new project instance for reference with id " | |||
| + oldKey; | |||
| throw new TaskException( msg, e2, location ); | |||
| } | |||
| } | |||
| newProject.addReference( newKey, copy ); | |||
| } | |||
| private void initializeProject() | |||
| { | |||
| Vector listeners = project.getBuildListeners(); | |||
| for( int i = 0; i < listeners.size(); i++ ) | |||
| { | |||
| newProject.addBuildListener( ( BuildListener )listeners.elementAt( i ) ); | |||
| } | |||
| if( output != null ) | |||
| { | |||
| try | |||
| { | |||
| PrintStream out = new PrintStream( new FileOutputStream( output ) ); | |||
| DefaultLogger logger = new DefaultLogger(); | |||
| logger.setMessageOutputLevel( Project.MSG_INFO ); | |||
| logger.setOutputPrintStream( out ); | |||
| logger.setErrorPrintStream( out ); | |||
| newProject.addBuildListener( logger ); | |||
| } | |||
| catch( IOException ex ) | |||
| { | |||
| log( "Ant: Can't set output to " + output ); | |||
| } | |||
| } | |||
| Hashtable taskdefs = project.getTaskDefinitions(); | |||
| Enumeration et = taskdefs.keys(); | |||
| while( et.hasMoreElements() ) | |||
| { | |||
| String taskName = ( String )et.nextElement(); | |||
| if( taskName.equals( "property" ) ) | |||
| { | |||
| // we have already added this taskdef in #init | |||
| continue; | |||
| } | |||
| Class taskClass = ( Class )taskdefs.get( taskName ); | |||
| newProject.addTaskDefinition( taskName, taskClass ); | |||
| } | |||
| Hashtable typedefs = project.getDataTypeDefinitions(); | |||
| Enumeration e = typedefs.keys(); | |||
| while( e.hasMoreElements() ) | |||
| { | |||
| String typeName = ( String )e.nextElement(); | |||
| Class typeClass = ( Class )typedefs.get( typeName ); | |||
| newProject.addDataTypeDefinition( typeName, typeClass ); | |||
| } | |||
| // set user-defined or all properties from calling project | |||
| Hashtable prop1; | |||
| if( inheritAll == true ) | |||
| { | |||
| prop1 = project.getProperties(); | |||
| } | |||
| else | |||
| { | |||
| prop1 = project.getUserProperties(); | |||
| // set Java built-in properties separately, | |||
| // b/c we won't inherit them. | |||
| newProject.setSystemProperties(); | |||
| } | |||
| e = prop1.keys(); | |||
| while( e.hasMoreElements() ) | |||
| { | |||
| String arg = ( String )e.nextElement(); | |||
| if( "basedir".equals( arg ) || "ant.file".equals( arg ) ) | |||
| { | |||
| // basedir and ant.file get special treatment in execute() | |||
| continue; | |||
| } | |||
| String value = ( String )prop1.get( arg ); | |||
| if( inheritAll == true ) | |||
| { | |||
| newProject.setProperty( arg, value ); | |||
| } | |||
| else | |||
| { | |||
| newProject.setUserProperty( arg, value ); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Override the properties in the new project with the one explicitly | |||
| * defined as nested elements here. | |||
| * | |||
| * @exception TaskException Description of Exception | |||
| */ | |||
| private void overrideProperties() | |||
| throws TaskException | |||
| { | |||
| Enumeration e = properties.elements(); | |||
| while( e.hasMoreElements() ) | |||
| { | |||
| Property p = ( Property )e.nextElement(); | |||
| p.setProject( newProject ); | |||
| p.execute(); | |||
| } | |||
| } | |||
| private void reinit() | |||
| { | |||
| init(); | |||
| for( int i = 0; i < properties.size(); i++ ) | |||
| { | |||
| Property p = ( Property )properties.elementAt( i ); | |||
| Property newP = ( Property )newProject.createTask( "property" ); | |||
| newP.setName( p.getName() ); | |||
| if( p.getValue() != null ) | |||
| { | |||
| newP.setValue( p.getValue() ); | |||
| } | |||
| if( p.getFile() != null ) | |||
| { | |||
| newP.setFile( p.getFile() ); | |||
| } | |||
| if( p.getResource() != null ) | |||
| { | |||
| newP.setResource( p.getResource() ); | |||
| } | |||
| properties.setElementAt( newP, i ); | |||
| } | |||
| } | |||
| /** | |||
| * Helper class that implements the nested <reference> element of | |||
| * <ant> and <antcall>. | |||
| * | |||
| * @author RT | |||
| */ | |||
| public static class Reference | |||
| extends org.apache.tools.ant.types.Reference | |||
| { | |||
| private String targetid = null; | |||
| public Reference() | |||
| { | |||
| super(); | |||
| } | |||
| public void setToRefid( String targetid ) | |||
| { | |||
| this.targetid = targetid; | |||
| } | |||
| public String getToRefid() | |||
| { | |||
| return targetid; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,124 +0,0 @@ | |||
| /* | |||
| * 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 file. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Task; | |||
| /** | |||
| * Call another target in the same project. <pre> | |||
| * <target name="foo"> | |||
| * <antcall target="bar"> | |||
| * <param name="property1" value="aaaaa" /> | |||
| * <param name="foo" value="baz" /> | |||
| * </antcall> | |||
| * </target> | |||
| * | |||
| * <target name="bar" depends="init"> | |||
| * <echo message="prop is ${property1} ${foo}" /> | |||
| * </target> | |||
| * </pre> <p> | |||
| * | |||
| * This only works as expected if neither property1 nor foo are defined in the | |||
| * project itself. | |||
| * | |||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| */ | |||
| public class CallTarget extends Task | |||
| { | |||
| private boolean initialized = false; | |||
| private boolean inheritAll = true; | |||
| private Ant callee; | |||
| private String subTarget; | |||
| /** | |||
| * If true, inherit all properties from parent Project If false, inherit | |||
| * only userProperties and those defined inside the antcall call itself | |||
| * | |||
| * @param inherit The new InheritAll value | |||
| */ | |||
| public void setInheritAll( boolean inherit ) | |||
| { | |||
| inheritAll = inherit; | |||
| } | |||
| public void setTarget( String target ) | |||
| { | |||
| subTarget = target; | |||
| } | |||
| /** | |||
| * create a reference element that identifies a data type that should be | |||
| * carried over to the new project. | |||
| * | |||
| * @param r The feature to be added to the Reference attribute | |||
| */ | |||
| public void addReference( Ant.Reference r ) | |||
| { | |||
| callee.addReference( r ); | |||
| } | |||
| public Property createParam() | |||
| { | |||
| return callee.createProperty(); | |||
| } | |||
| public void execute() | |||
| { | |||
| if( !initialized ) | |||
| { | |||
| init(); | |||
| } | |||
| if( subTarget == null ) | |||
| { | |||
| throw new BuildException( "Attribute target is required." ); | |||
| } | |||
| callee.setDir( project.getBaseDir() ); | |||
| callee.setAntfile( project.getProperty( "ant.file" ) ); | |||
| callee.setTarget( subTarget ); | |||
| callee.setInheritAll( inheritAll ); | |||
| callee.execute(); | |||
| }//-- setInheritAll | |||
| public void init() | |||
| { | |||
| callee = ( Ant )project.createTask( "ant" ); | |||
| callee.setOwningTarget( target ); | |||
| callee.setTaskName( getTaskName() ); | |||
| callee.setLocation( location ); | |||
| callee.init(); | |||
| initialized = true; | |||
| } | |||
| protected void handleErrorOutput( String line ) | |||
| { | |||
| if( callee != null ) | |||
| { | |||
| callee.handleErrorOutput( line ); | |||
| } | |||
| else | |||
| { | |||
| super.handleErrorOutput( line ); | |||
| } | |||
| } | |||
| protected void handleOutput( String line ) | |||
| { | |||
| if( callee != null ) | |||
| { | |||
| callee.handleOutput( line ); | |||
| } | |||
| else | |||
| { | |||
| super.handleOutput( line ); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,215 +0,0 @@ | |||
| /* | |||
| * 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 file. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Enumeration; | |||
| import java.util.Properties; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.tools.ant.AntClassLoader; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.types.Path; | |||
| import org.apache.tools.ant.types.Reference; | |||
| /** | |||
| * Base class for Taskdef and Typedef - does all the classpath handling and and | |||
| * class loading. | |||
| * | |||
| * @author Costin Manolache | |||
| * @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| */ | |||
| public abstract class Definer extends Task | |||
| { | |||
| private boolean reverseLoader = false; | |||
| private Path classpath; | |||
| private File file; | |||
| private String name; | |||
| private String resource; | |||
| private String value; | |||
| public void setClassname( String v ) | |||
| { | |||
| value = v; | |||
| } | |||
| public void setClasspath( Path classpath ) | |||
| { | |||
| if( this.classpath == null ) | |||
| { | |||
| this.classpath = classpath; | |||
| } | |||
| else | |||
| { | |||
| this.classpath.append( classpath ); | |||
| } | |||
| } | |||
| public void setClasspathRef( Reference r ) | |||
| { | |||
| createClasspath().setRefid( r ); | |||
| } | |||
| public void setFile( File file ) | |||
| { | |||
| this.file = file; | |||
| } | |||
| public void setName( String name ) | |||
| { | |||
| this.name = name; | |||
| } | |||
| public void setResource( String res ) | |||
| { | |||
| this.resource = res; | |||
| } | |||
| public String getClassname() | |||
| { | |||
| return value; | |||
| } | |||
| public Path createClasspath() | |||
| { | |||
| if( this.classpath == null ) | |||
| { | |||
| this.classpath = new Path( project ); | |||
| } | |||
| return this.classpath.createPath(); | |||
| } | |||
| public void execute() | |||
| throws TaskException | |||
| { | |||
| AntClassLoader al = createLoader(); | |||
| if( file == null && resource == null ) | |||
| { | |||
| // simple case - one definition | |||
| if( name == null || value == null ) | |||
| { | |||
| String msg = "name or classname attributes of " | |||
| + getTaskName() + " element " | |||
| + "are undefined"; | |||
| throw new TaskException( msg ); | |||
| } | |||
| addDefinition( al, name, value ); | |||
| } | |||
| else | |||
| { | |||
| try | |||
| { | |||
| if( name != null || value != null ) | |||
| { | |||
| String msg = "You must not specify name or value " | |||
| + "together with file or resource."; | |||
| throw new TaskException( msg ); | |||
| } | |||
| if( file != null && resource != null ) | |||
| { | |||
| String msg = "You must not specify both, file and resource."; | |||
| throw new TaskException( msg ); | |||
| } | |||
| Properties props = new Properties(); | |||
| InputStream is = null; | |||
| if( file != null ) | |||
| { | |||
| log( "Loading definitions from file " + file, | |||
| Project.MSG_VERBOSE ); | |||
| is = new FileInputStream( file ); | |||
| if( is == null ) | |||
| { | |||
| log( "Could not load definitions from file " + file | |||
| + ". It doesn\'t exist.", Project.MSG_WARN ); | |||
| } | |||
| } | |||
| if( resource != null ) | |||
| { | |||
| log( "Loading definitions from resource " + resource, | |||
| Project.MSG_VERBOSE ); | |||
| is = al.getResourceAsStream( resource ); | |||
| if( is == null ) | |||
| { | |||
| log( "Could not load definitions from resource " | |||
| + resource + ". It could not be found.", | |||
| Project.MSG_WARN ); | |||
| } | |||
| } | |||
| if( is != null ) | |||
| { | |||
| props.load( is ); | |||
| Enumeration keys = props.keys(); | |||
| while( keys.hasMoreElements() ) | |||
| { | |||
| String n = (String)keys.nextElement(); | |||
| String v = props.getProperty( n ); | |||
| addDefinition( al, n, v ); | |||
| } | |||
| } | |||
| } | |||
| catch( IOException ex ) | |||
| { | |||
| throw new TaskException( "Error", ex ); | |||
| } | |||
| } | |||
| } | |||
| protected abstract void addDefinition( String name, Class c ); | |||
| private void addDefinition( ClassLoader al, String name, String value ) | |||
| throws TaskException | |||
| { | |||
| try | |||
| { | |||
| Class c = al.loadClass( value ); | |||
| AntClassLoader.initializeClass( c ); | |||
| addDefinition( name, c ); | |||
| } | |||
| catch( ClassNotFoundException cnfe ) | |||
| { | |||
| String msg = getTaskName() + " class " + value + | |||
| " cannot be found"; | |||
| throw new TaskException( msg, cnfe ); | |||
| } | |||
| catch( NoClassDefFoundError ncdfe ) | |||
| { | |||
| String msg = getTaskName() + " class " + value + | |||
| " cannot be found"; | |||
| throw new TaskException( msg, ncdfe ); | |||
| } | |||
| } | |||
| private AntClassLoader createLoader() | |||
| throws TaskException | |||
| { | |||
| AntClassLoader al = null; | |||
| if( classpath != null ) | |||
| { | |||
| al = new AntClassLoader( project, classpath, !reverseLoader ); | |||
| } | |||
| else | |||
| { | |||
| al = new AntClassLoader( project, Path.systemClasspath, !reverseLoader ); | |||
| } | |||
| // need to load Task via system classloader or the new | |||
| // task we want to define will never be a Task but always | |||
| // be wrapped into a TaskAdapter. | |||
| al.addSystemPackageRoot( "org.apache.tools.ant" ); | |||
| return al; | |||
| } | |||
| } | |||
| @@ -1,23 +0,0 @@ | |||
| /* | |||
| * 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 file. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import org.apache.tools.ant.BuildException; | |||
| /** | |||
| * Define a new task. | |||
| * | |||
| * @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| */ | |||
| public class Taskdef extends Definer | |||
| { | |||
| protected void addDefinition( String name, Class c ) | |||
| throws BuildException | |||
| { | |||
| project.addTaskDefinition( name, c ); | |||
| } | |||
| } | |||
| @@ -1,23 +0,0 @@ | |||
| /* | |||
| * 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 file. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import org.apache.tools.ant.BuildException; | |||
| /** | |||
| * Define a new data type. | |||
| * | |||
| * @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| */ | |||
| public class Typedef extends Definer | |||
| { | |||
| protected void addDefinition( String name, Class c ) | |||
| throws BuildException | |||
| { | |||
| project.addDataTypeDefinition( name, c ); | |||
| } | |||
| } | |||