Made conditions (if/unless interpreted in a context) git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268342 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -27,7 +27,7 @@ import org.apache.ant.project.Project; | |||
| import org.apache.ant.project.ProjectBuilder; | |||
| import org.apache.ant.project.ProjectEngine; | |||
| import org.apache.ant.project.ProjectListener; | |||
| import org.apache.ant.project.ProjectToListenerAdapter; | |||
| import org.apache.ant.project.LogTargetToListenerAdapter; | |||
| import org.apache.ant.tasklet.JavaVersion; | |||
| import org.apache.ant.tasklet.TaskletContext; | |||
| import org.apache.ant.tasklet.engine.TaskletEngine; | |||
| @@ -232,7 +232,8 @@ public class Main | |||
| new CLOptionDescriptor( "define", | |||
| CLOptionDescriptor.ARGUMENTS_REQUIRED_2, | |||
| DEFINE_OPT, | |||
| "Define a variable (ie -Dfoo=var)" ); | |||
| "Define a variable (ie -Dfoo=var)", | |||
| new int[ 0 ] ); | |||
| return options; | |||
| } | |||
| @@ -481,7 +482,7 @@ public class Main | |||
| protected void setupListener( final String listenerName ) | |||
| { | |||
| m_listener = createListener( listenerName ); | |||
| m_logger.addLogTarget( new ProjectToListenerAdapter( m_listener ) ); | |||
| m_logger.addLogTarget( new LogTargetToListenerAdapter( m_listener ) ); | |||
| } | |||
| /** | |||
| @@ -566,7 +567,6 @@ public class Main | |||
| defines.put( AntContextResources.LIB_DIR, m_libDir ); | |||
| defines.put( AntContextResources.TASKLIB_DIR, m_taskLibDir ); | |||
| //defines.put( AntContextResources.USER_DIR, m_userDir ); | |||
| defines.put( TaskletContext.LOGGER, m_logger ); | |||
| defines.put( TaskletContext.JAVA_VERSION, getJavaVersion() ); | |||
| final TaskletContext context = project.getContext(); | |||
| @@ -19,8 +19,10 @@ import org.apache.avalon.ComponentNotFoundException; | |||
| import org.apache.avalon.Composer; | |||
| import org.apache.avalon.ConfigurationException; | |||
| import org.apache.avalon.Context; | |||
| import org.apache.avalon.Loggable; | |||
| import org.apache.avalon.util.PropertyException; | |||
| import org.apache.avalon.util.PropertyUtil; | |||
| import org.apache.log.Logger; | |||
| /** | |||
| * Class used to configure tasks. | |||
| @@ -28,7 +30,7 @@ import org.apache.avalon.util.PropertyUtil; | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class DefaultConfigurer | |||
| implements Configurer, Composer | |||
| implements Configurer, Composer, Loggable | |||
| { | |||
| protected final static String RESERVED_ATTRIBUTES[] = | |||
| { | |||
| @@ -40,7 +42,14 @@ public class DefaultConfigurer | |||
| "content" | |||
| }; | |||
| protected final static boolean DEBUG = false; | |||
| protected Converter m_converter; | |||
| protected Logger m_logger; | |||
| public void setLogger( final Logger logger ) | |||
| { | |||
| m_logger = logger; | |||
| } | |||
| public void compose( final ComponentManager componentManager ) | |||
| throws ComponentNotFoundException, ComponentNotAccessibleException | |||
| @@ -66,18 +75,39 @@ public class DefaultConfigurer | |||
| final Context context ) | |||
| throws ConfigurationException | |||
| { | |||
| if( DEBUG ) | |||
| { | |||
| m_logger.debug( "Configuring " + object ); | |||
| } | |||
| if( object instanceof Configurable ) | |||
| { | |||
| if( DEBUG ) | |||
| { | |||
| m_logger.debug( "Configuring object via Configurable interface" ); | |||
| } | |||
| ((Configurable)object).configure( configuration ); | |||
| } | |||
| else | |||
| { | |||
| final Iterator attributes = configuration.getAttributeNames(); | |||
| if( DEBUG ) | |||
| { | |||
| m_logger.debug( "Configuring object via Configurable reflection" ); | |||
| } | |||
| final Iterator attributes = configuration.getAttributeNames(); | |||
| while( attributes.hasNext() ) | |||
| { | |||
| final String name = (String)attributes.next(); | |||
| final String value = configuration.getAttribute( name ); | |||
| if( DEBUG ) | |||
| { | |||
| m_logger.debug( "Configuring attribute name=" + name + | |||
| " value=" + value ); | |||
| } | |||
| configureAttribute( object, name, value, context ); | |||
| } | |||
| @@ -86,6 +116,12 @@ public class DefaultConfigurer | |||
| while( elements.hasNext() ) | |||
| { | |||
| final Configuration element = (Configuration)elements.next(); | |||
| if( DEBUG ) | |||
| { | |||
| m_logger.debug( "Configuring subelement name=" + element.getName() ); | |||
| } | |||
| configureElement( object, element, context ); | |||
| } | |||
| @@ -95,6 +131,11 @@ public class DefaultConfigurer | |||
| { | |||
| if( !content.trim().equals( "" ) ) | |||
| { | |||
| if( DEBUG ) | |||
| { | |||
| m_logger.debug( "Configuring content " + content ); | |||
| } | |||
| configureContent( object, content, context ); | |||
| } | |||
| } | |||
| @@ -206,22 +247,24 @@ public class DefaultConfigurer | |||
| parameterType = getComplexTypeFor( parameterType ); | |||
| } | |||
| if( !parameterType.isAssignableFrom( sourceClass ) ) | |||
| try | |||
| { | |||
| try | |||
| { | |||
| value = m_converter.convert( parameterType, object ); | |||
| } | |||
| catch( final ConverterException ce ) | |||
| { | |||
| return false; | |||
| } | |||
| catch( final Exception e ) | |||
| value = m_converter.convert( parameterType, value ); | |||
| } | |||
| catch( final ConverterException ce ) | |||
| { | |||
| if( DEBUG ) | |||
| { | |||
| throw new ConfigurationException( "Error converting attribute for " + | |||
| method.getName(), | |||
| e ); | |||
| m_logger.debug( "Failed to find converter ", ce ); | |||
| } | |||
| return false; | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new ConfigurationException( "Error converting attribute for " + | |||
| method.getName(), | |||
| e ); | |||
| } | |||
| try | |||
| @@ -15,6 +15,6 @@ import org.apache.log.Logger; | |||
| public interface ConverterEngine | |||
| extends Component, Converter, Loggable | |||
| { | |||
| LocatorRegistry getLocatorRegistry(); | |||
| ConverterRegistry getConverterRegistry(); | |||
| LocatorRegistry getRegistry(); | |||
| ConverterRegistry getInfoRegistry(); | |||
| } | |||
| @@ -19,9 +19,10 @@ import org.apache.log.Logger; | |||
| public class DefaultConverterEngine | |||
| implements ConverterEngine, Initializable | |||
| { | |||
| protected final static boolean DEBUG = false; | |||
| protected DefaultFactory m_factory; | |||
| protected LocatorRegistry m_locatorRegistry; | |||
| protected ConverterRegistry m_converterRegistry; | |||
| protected LocatorRegistry m_registry; | |||
| protected ConverterRegistry m_infoRegistry; | |||
| protected Logger m_logger; | |||
| public void setLogger( final Logger logger ) | |||
| @@ -29,30 +30,30 @@ public class DefaultConverterEngine | |||
| m_logger = logger; | |||
| } | |||
| public LocatorRegistry getLocatorRegistry() | |||
| public LocatorRegistry getRegistry() | |||
| { | |||
| return m_locatorRegistry; | |||
| return m_registry; | |||
| } | |||
| public ConverterRegistry getConverterRegistry() | |||
| public ConverterRegistry getInfoRegistry() | |||
| { | |||
| return m_converterRegistry; | |||
| return m_infoRegistry; | |||
| } | |||
| public void init() | |||
| throws Exception | |||
| { | |||
| m_converterRegistry = createConverterRegistry(); | |||
| m_locatorRegistry = createLocatorRegistry(); | |||
| m_infoRegistry = createInfoRegistry(); | |||
| m_registry = createRegistry(); | |||
| m_factory = createFactory(); | |||
| } | |||
| protected ConverterRegistry createConverterRegistry() | |||
| protected ConverterRegistry createInfoRegistry() | |||
| { | |||
| return new DefaultConverterRegistry(); | |||
| } | |||
| protected LocatorRegistry createLocatorRegistry() | |||
| protected LocatorRegistry createRegistry() | |||
| { | |||
| return new DefaultLocatorRegistry(); | |||
| } | |||
| @@ -65,18 +66,31 @@ public class DefaultConverterEngine | |||
| public Object convert( Class destination, final Object original ) | |||
| throws Exception | |||
| { | |||
| final Class originalClass = original.getClass(); | |||
| if( destination.isAssignableFrom( originalClass ) ) | |||
| { | |||
| return original; | |||
| } | |||
| if( DEBUG ) | |||
| { | |||
| m_logger.debug( "Looking for converter from " + originalClass.getName() + | |||
| " to " + destination.getName() ); | |||
| } | |||
| final String name = | |||
| m_converterRegistry.getConverterInfoName( original.getClass().getName(), | |||
| destination.getName() ); | |||
| m_infoRegistry.getConverterInfoName( originalClass.getName(), | |||
| destination.getName() ); | |||
| if( null == name ) | |||
| { | |||
| throw new ConverterException( "Unable to find converter for " + | |||
| original.getClass() + " to " + destination + | |||
| " conversion" ); | |||
| originalClass.getName() + " to " + | |||
| destination.getName() + " conversion" ); | |||
| } | |||
| final Locator locator = m_locatorRegistry.getLocator( name ); | |||
| final Locator locator = m_registry.getLocator( name ); | |||
| final Converter converter = (Converter)m_factory.create( locator, Converter.class ); | |||
| return converter.convert( destination, original ); | |||
| } | |||
| @@ -0,0 +1,71 @@ | |||
| /* | |||
| * 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.ant.datatypes; | |||
| import org.apache.ant.AntException; | |||
| import org.apache.avalon.Component; | |||
| import org.apache.avalon.Context; | |||
| import org.apache.avalon.util.PropertyException; | |||
| import org.apache.avalon.util.PropertyUtil; | |||
| /** | |||
| * Class representing a condition. | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class Condition | |||
| implements Component | |||
| { | |||
| protected String m_condition; | |||
| protected boolean m_isIfCondition; | |||
| public Condition( final boolean isIfCondition, final String condition ) | |||
| { | |||
| m_isIfCondition = isIfCondition; | |||
| m_condition = condition; | |||
| } | |||
| public String getCondition() | |||
| { | |||
| return m_condition; | |||
| } | |||
| public boolean isIfCondition() | |||
| { | |||
| return m_isIfCondition; | |||
| } | |||
| public boolean evaluate( final Context context ) | |||
| { | |||
| try | |||
| { | |||
| final Object resolved = | |||
| PropertyUtil.resolveProperty( m_condition, context, false ); | |||
| boolean result = false; | |||
| if( null != resolved ) | |||
| { | |||
| result = ( null != context.get( resolved ) ); | |||
| } | |||
| if( !m_isIfCondition ) | |||
| { | |||
| result = !result; | |||
| } | |||
| return result; | |||
| } | |||
| catch( final PropertyException pe ) | |||
| { | |||
| throw new AntException( "Error resolving " + m_condition, pe ); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,22 @@ | |||
| /* | |||
| * 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.ant.datatypes; | |||
| import org.apache.avalon.Component; | |||
| /** | |||
| * Base class for those classes that can appear inside the build file | |||
| * as stand alone data types. | |||
| * | |||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public interface DataType | |||
| extends Component | |||
| { | |||
| } | |||
| @@ -0,0 +1,23 @@ | |||
| /* | |||
| * 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.ant.datatypes; | |||
| import org.apache.avalon.Component; | |||
| import org.apache.avalon.Loggable; | |||
| import org.apache.avalon.camelot.FactoryException; | |||
| import org.apache.avalon.camelot.LocatorRegistry; | |||
| import org.apache.avalon.camelot.RegistryException; | |||
| public interface DataTypeEngine | |||
| extends Component, Loggable | |||
| { | |||
| LocatorRegistry getRegistry(); | |||
| DataType createDataType( String name ) | |||
| throws RegistryException, FactoryException; | |||
| } | |||
| @@ -0,0 +1,73 @@ | |||
| /* | |||
| * 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.ant.datatypes; | |||
| import org.apache.ant.AntException; | |||
| import org.apache.avalon.Initializable; | |||
| import org.apache.avalon.Loggable; | |||
| import org.apache.avalon.camelot.DefaultFactory; | |||
| import org.apache.avalon.camelot.DefaultLocatorRegistry; | |||
| import org.apache.avalon.camelot.Locator; | |||
| import org.apache.avalon.camelot.LocatorRegistry; | |||
| import org.apache.avalon.camelot.RegistryException; | |||
| import org.apache.avalon.camelot.FactoryException; | |||
| import org.apache.log.Logger; | |||
| public class DefaultDataTypeEngine | |||
| implements DataTypeEngine, Initializable | |||
| { | |||
| protected DefaultFactory m_factory; | |||
| protected LocatorRegistry m_registry; | |||
| protected Logger m_logger; | |||
| public void setLogger( final Logger logger ) | |||
| { | |||
| m_logger = logger; | |||
| } | |||
| public LocatorRegistry getRegistry() | |||
| { | |||
| return m_registry; | |||
| } | |||
| public void init() | |||
| throws Exception | |||
| { | |||
| m_registry = createRegistry(); | |||
| setupComponent( m_registry ); | |||
| m_factory = createFactory(); | |||
| setupComponent( m_factory ); | |||
| } | |||
| protected void setupComponent( final Object object ) | |||
| throws Exception | |||
| { | |||
| if( object instanceof Loggable ) | |||
| { | |||
| ((Loggable)object).setLogger( m_logger ); | |||
| } | |||
| } | |||
| protected LocatorRegistry createRegistry() | |||
| { | |||
| return new DefaultLocatorRegistry(); | |||
| } | |||
| protected DefaultFactory createFactory() | |||
| { | |||
| return new DefaultFactory(); | |||
| } | |||
| public DataType createDataType( final String name ) | |||
| throws RegistryException, FactoryException | |||
| { | |||
| final Locator locator = m_registry.getLocator( name ); | |||
| return (DataType)m_factory.create( locator, DataType.class ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,60 @@ | |||
| /* | |||
| * 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.ant.datatypes; | |||
| import org.apache.ant.AntException; | |||
| /** | |||
| * Basic data type for holding patterns. | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class Pattern | |||
| implements DataType | |||
| { | |||
| protected String m_name; | |||
| protected Condition m_condition; | |||
| public String getName() | |||
| { | |||
| return m_name; | |||
| } | |||
| public Condition getCondition() | |||
| { | |||
| return m_condition; | |||
| } | |||
| public void setName( final String name ) | |||
| { | |||
| m_name = name; | |||
| } | |||
| public void setIf( final String condition ) | |||
| throws AntException | |||
| { | |||
| verifyConditionNull(); | |||
| m_condition = new Condition( true, condition ); | |||
| } | |||
| public void setUnless( final String condition ) | |||
| throws AntException | |||
| { | |||
| verifyConditionNull(); | |||
| m_condition = new Condition( false, condition ); | |||
| } | |||
| protected void verifyConditionNull() | |||
| throws AntException | |||
| { | |||
| if( null != m_condition ) | |||
| { | |||
| throw new AntException( "Can only set one of if/else for pattern data type" ); | |||
| } | |||
| } | |||
| } | |||
| @@ -13,6 +13,7 @@ import java.util.Iterator; | |||
| import org.apache.ant.AntException; | |||
| import org.apache.ant.configuration.Configuration; | |||
| import org.apache.ant.configuration.ConfigurationBuilder; | |||
| import org.apache.ant.datatypes.Condition; | |||
| import org.apache.ant.tasklet.TaskletContext; | |||
| import org.apache.avalon.ConfigurationException; | |||
| import org.apache.log.Logger; | |||
| @@ -133,21 +134,21 @@ public class DefaultProjectBuilder | |||
| "unless condition at " + configuration.getLocation() ); | |||
| } | |||
| final DefaultTarget target = new DefaultTarget(); | |||
| Condition condition = null; | |||
| if( null != ifCondition ) | |||
| { | |||
| m_logger.debug( "Target if condition: " + ifCondition ); | |||
| target.setIfCondition( true ); | |||
| target.setCondition( ifCondition ); | |||
| condition = new Condition( true, ifCondition ); | |||
| } | |||
| else if( null != unlessCondition ) | |||
| { | |||
| m_logger.debug( "Target unless condition: " + unlessCondition ); | |||
| target.setIfCondition( false ); | |||
| target.setCondition( unlessCondition ); | |||
| condition = new Condition( false, unlessCondition ); | |||
| } | |||
| final DefaultTarget target = new DefaultTarget( condition ); | |||
| if( null != depends ) | |||
| { | |||
| int start = 0; | |||
| @@ -11,6 +11,7 @@ import java.util.ArrayList; | |||
| import java.util.Iterator; | |||
| import org.apache.ant.AntException; | |||
| import org.apache.ant.configuration.Configuration; | |||
| import org.apache.ant.datatypes.Condition; | |||
| import org.apache.ant.tasklet.DefaultTaskletContext; | |||
| import org.apache.ant.tasklet.TaskletContext; | |||
| import org.apache.ant.tasklet.engine.DefaultTaskletEngine; | |||
| @@ -100,13 +101,9 @@ public class DefaultProjectEngine | |||
| m_listenerSupport.projectStarted( projectName ); | |||
| executeTargetWork( "<init>", project.getImplicitTarget(), context ); | |||
| //context = new DefaultTaskletContext( context ); | |||
| //placing logger lower (at targetlevel or at task level) | |||
| //is possible if you want more fine grained control | |||
| context.setProperty( TaskletContext.LOGGER, m_logger ); | |||
| executeTargetWork( "<init>", project.getImplicitTarget(), context ); | |||
| execute( project, target, context ); | |||
| @@ -168,6 +165,18 @@ public class DefaultProjectEngine | |||
| final Target target, | |||
| final TaskletContext context ) | |||
| { | |||
| final Condition condition = target.getCondition(); | |||
| if( null != condition ) | |||
| { | |||
| if( false == condition.evaluate( context ) ) | |||
| { | |||
| m_logger.debug( "Skipping target " + name + | |||
| " as it does not satisfy condition" ); | |||
| return; | |||
| } | |||
| } | |||
| m_logger.debug( "Executing target " + name ); | |||
| final Iterator tasks = target.getTasks(); | |||
| @@ -10,43 +10,38 @@ package org.apache.ant.project; | |||
| import java.util.ArrayList; | |||
| import java.util.Iterator; | |||
| import org.apache.ant.configuration.Configuration; | |||
| import org.apache.ant.datatypes.Condition; | |||
| public class DefaultTarget | |||
| implements Target | |||
| { | |||
| protected ArrayList m_dependencies = new ArrayList(); | |||
| protected ArrayList m_tasks = new ArrayList(); | |||
| protected String m_condition; | |||
| protected boolean m_isIfCondition; | |||
| protected final ArrayList m_dependencies = new ArrayList(); | |||
| protected final ArrayList m_tasks = new ArrayList(); | |||
| protected final Condition m_condition; | |||
| public Iterator getDependencies() | |||
| public DefaultTarget( final Condition condition ) | |||
| { | |||
| return m_dependencies.iterator(); | |||
| m_condition = condition; | |||
| } | |||
| public Iterator getTasks() | |||
| public DefaultTarget() | |||
| { | |||
| return m_tasks.iterator(); | |||
| this( null ); | |||
| } | |||
| public String getCondition() | |||
| public Condition getCondition() | |||
| { | |||
| return m_condition; | |||
| } | |||
| public void setCondition( final String condition ) | |||
| { | |||
| m_condition = condition; | |||
| } | |||
| public boolean isIfCondition() | |||
| public Iterator getDependencies() | |||
| { | |||
| return m_isIfCondition; | |||
| return m_dependencies.iterator(); | |||
| } | |||
| public void setIfCondition( final boolean isIfCondition ) | |||
| public Iterator getTasks() | |||
| { | |||
| m_isIfCondition = isIfCondition; | |||
| return m_tasks.iterator(); | |||
| } | |||
| public void addDependency( final String dependency ) | |||
| @@ -10,13 +10,13 @@ package org.apache.ant.project; | |||
| import org.apache.log.LogEntry; | |||
| import org.apache.log.LogTarget; | |||
| public class ProjectToListenerAdapter | |||
| public class LogTargetToListenerAdapter | |||
| implements LogTarget | |||
| { | |||
| protected final ProjectListener m_listener; | |||
| public ProjectToListenerAdapter( final ProjectListener listener ) | |||
| public LogTargetToListenerAdapter( final ProjectListener listener ) | |||
| { | |||
| m_listener = listener; | |||
| } | |||
| @@ -9,14 +9,14 @@ package org.apache.ant.project; | |||
| import java.util.Iterator; | |||
| import org.apache.avalon.Component; | |||
| import org.apache.ant.datatypes.Condition; | |||
| public interface Target | |||
| extends Component | |||
| { | |||
| Iterator getDependencies(); | |||
| Iterator getTasks(); | |||
| String getCondition(); | |||
| boolean isIfCondition(); | |||
| Condition getCondition(); | |||
| } | |||
| @@ -26,6 +26,16 @@ public abstract class AbstractTasklet | |||
| private TaskletContext m_context; | |||
| private Logger m_logger; | |||
| /** | |||
| * Receive logger from container. | |||
| * | |||
| * @param logger the logger | |||
| */ | |||
| public void setLogger( final Logger logger ) | |||
| { | |||
| m_logger = logger; | |||
| } | |||
| /** | |||
| * Retrieve context from container. | |||
| * | |||
| @@ -34,7 +44,6 @@ public abstract class AbstractTasklet | |||
| public void contextualize( final Context context ) | |||
| { | |||
| m_context = (TaskletContext)context; | |||
| m_logger = (Logger)m_context.getLogger(); | |||
| } | |||
| /** | |||
| @@ -13,7 +13,6 @@ import org.apache.avalon.DefaultContext; | |||
| import org.apache.avalon.util.PropertyException; | |||
| import org.apache.avalon.util.PropertyUtil; | |||
| import org.apache.avalon.util.io.FileUtil; | |||
| import org.apache.log.Logger; | |||
| /** | |||
| * Default implementation of TaskletContext. | |||
| @@ -68,16 +67,6 @@ public class DefaultTaskletContext | |||
| return (String)get( NAME ); | |||
| } | |||
| /** | |||
| * Retrieve Logger associated with task. | |||
| * | |||
| * @return the logger | |||
| */ | |||
| public Logger getLogger() | |||
| { | |||
| return (Logger)get( LOGGER ); | |||
| } | |||
| /** | |||
| * Retrieve base directory. | |||
| * | |||
| @@ -209,13 +198,7 @@ public class DefaultTaskletContext | |||
| protected void checkPropertyValid( final String name, final Object value ) | |||
| throws AntException | |||
| { | |||
| if( LOGGER.equals( name ) && !( value instanceof Logger ) ) | |||
| { | |||
| throw new AntException( "property " + LOGGER + | |||
| " must have a value of type " + | |||
| Logger.class.getName() ); | |||
| } | |||
| else if( BASE_DIRECTORY.equals( name ) && !( value instanceof File ) ) | |||
| if( BASE_DIRECTORY.equals( name ) && !( value instanceof File ) ) | |||
| { | |||
| throw new AntException( "Property " + BASE_DIRECTORY + | |||
| " must have a value of type " + | |||
| @@ -9,6 +9,7 @@ package org.apache.ant.tasklet; | |||
| import org.apache.avalon.Component; | |||
| import org.apache.avalon.Contextualizable; | |||
| import org.apache.avalon.Loggable; | |||
| /** | |||
| * This represents the individual tasks. | |||
| @@ -23,6 +24,6 @@ import org.apache.avalon.Contextualizable; | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public interface Tasklet | |||
| extends Component, Contextualizable, Runnable | |||
| extends Component, Contextualizable, Runnable, Loggable | |||
| { | |||
| } | |||
| @@ -11,7 +11,6 @@ import java.io.File; | |||
| import org.apache.avalon.Context; | |||
| import org.apache.avalon.util.Enum; | |||
| import org.apache.avalon.util.ValuedEnum; | |||
| import org.apache.log.Logger; | |||
| /** | |||
| * This represents the *Context* in which a task can be executed. | |||
| @@ -30,7 +29,6 @@ public interface TaskletContext | |||
| //these are the names of properties that every TaskContext must contain | |||
| String JAVA_VERSION = "ant.java.version"; | |||
| String BASE_DIRECTORY = "ant.base.directory"; | |||
| String LOGGER = "ant.logger"; | |||
| String NAME = "ant.task.name"; | |||
| /** | |||
| @@ -46,13 +44,6 @@ public interface TaskletContext | |||
| * @return the name | |||
| */ | |||
| String getName(); | |||
| /** | |||
| * Retrieve Logger associated with task. | |||
| * | |||
| * @return the logger | |||
| */ | |||
| Logger getLogger(); | |||
| /** | |||
| * Retrieve base directory. | |||
| @@ -14,6 +14,7 @@ import org.apache.ant.configuration.Configuration; | |||
| import org.apache.ant.configuration.Configurer; | |||
| import org.apache.ant.configuration.DefaultConfigurer; | |||
| import org.apache.ant.convert.ConverterEngine; | |||
| import org.apache.ant.datatypes.DataTypeEngine; | |||
| import org.apache.ant.tasklet.Tasklet; | |||
| import org.apache.ant.tasklet.TaskletContext; | |||
| import org.apache.avalon.Component; | |||
| @@ -23,13 +24,13 @@ import org.apache.avalon.Context; | |||
| import org.apache.avalon.Contextualizable; | |||
| import org.apache.avalon.DefaultComponentManager; | |||
| import org.apache.avalon.Disposable; | |||
| import org.apache.avalon.Loggable; | |||
| import org.apache.avalon.Initializable; | |||
| import org.apache.avalon.Loggable; | |||
| import org.apache.avalon.camelot.DefaultFactory; | |||
| import org.apache.avalon.camelot.DefaultLocatorRegistry; | |||
| import org.apache.avalon.camelot.FactoryException; | |||
| import org.apache.avalon.camelot.LocatorRegistry; | |||
| import org.apache.avalon.camelot.Locator; | |||
| import org.apache.avalon.camelot.DefaultLocatorRegistry; | |||
| import org.apache.avalon.camelot.LocatorRegistry; | |||
| import org.apache.avalon.camelot.RegistryException; | |||
| import org.apache.log.Logger; | |||
| @@ -41,6 +42,7 @@ public class DefaultTaskletEngine | |||
| protected LocatorRegistry m_locatorRegistry; | |||
| protected Configurer m_configurer; | |||
| protected Logger m_logger; | |||
| protected DataTypeEngine m_dataTypeEngine; | |||
| protected ConverterEngine m_converterEngine; | |||
| public void setLogger( final Logger logger ) | |||
| @@ -58,27 +60,41 @@ public class DefaultTaskletEngine | |||
| return m_converterEngine; | |||
| } | |||
| public LocatorRegistry getLocatorRegistry() | |||
| public LocatorRegistry getRegistry() | |||
| { | |||
| return m_locatorRegistry; | |||
| } | |||
| /** | |||
| * Retrieve datatype engine. | |||
| * | |||
| * @return the DataTypeEngine | |||
| */ | |||
| public DataTypeEngine getDataTypeEngine() | |||
| { | |||
| return m_dataTypeEngine; | |||
| } | |||
| public void init() | |||
| throws Exception | |||
| { | |||
| m_locatorRegistry = createLocatorRegistry(); | |||
| m_factory = createFactory(); | |||
| setupSubComponent( m_factory ); | |||
| //converter must be created before configurerer | |||
| //so that it gets placed in configurers componentManager | |||
| m_converterEngine = createConverterEngine(); | |||
| m_converterEngine.setLogger( m_logger ); | |||
| setupSubComponent( m_converterEngine ); | |||
| m_configurer = createConfigurer(); | |||
| setupSubComponent( m_configurer ); | |||
| m_locatorRegistry = createLocatorRegistry(); | |||
| m_factory = createFactory(); | |||
| setupSubComponent( m_factory ); | |||
| m_dataTypeEngine = createDataTypeEngine(); | |||
| setupSubComponent( m_dataTypeEngine ); | |||
| m_tskDeployer = createTskDeployer(); | |||
| m_tskDeployer.setLogger( m_logger ); | |||
| setupSubComponent( m_tskDeployer ); | |||
| } | |||
| @@ -93,10 +109,10 @@ public class DefaultTaskletEngine | |||
| if( component instanceof Composer ) | |||
| { | |||
| final DefaultComponentManager componentManager = new DefaultComponentManager(); | |||
| componentManager.put( "org.apache.ant.convert.Converter", | |||
| getConverterEngine() ); | |||
| componentManager.put( "org.apache.ant.convert.ConverterEngine", | |||
| componentManager.put( "org.apache.ant.convert.Converter", | |||
| getConverterEngine() ); | |||
| componentManager.put( "org.apache.ant.configuration.Configurer", | |||
| m_configurer ); | |||
| componentManager.put( "org.apache.ant.tasklet.engine.TaskletEngine", | |||
| this ); | |||
| @@ -108,6 +124,13 @@ public class DefaultTaskletEngine | |||
| ((Initializable)component).init(); | |||
| } | |||
| } | |||
| protected DataTypeEngine createDataTypeEngine() | |||
| { | |||
| final TaskletDataTypeEngine engine = new TaskletDataTypeEngine(); | |||
| engine.setFactory( m_factory ); | |||
| return engine; | |||
| } | |||
| protected TskDeployer createTskDeployer() | |||
| { | |||
| @@ -143,9 +166,9 @@ public class DefaultTaskletEngine | |||
| final ComponentManager componentManager ) | |||
| throws AntException | |||
| { | |||
| m_logger.debug( "Creating" ); | |||
| final Tasklet tasklet = createTasklet( task ); | |||
| final Tasklet tasklet = createTasklet( task.getName() ); | |||
| tasklet.setLogger( m_logger ); | |||
| m_logger.debug( "Contextualizing" ); | |||
| doContextualize( tasklet, task, context ); | |||
| @@ -185,9 +208,15 @@ public class DefaultTaskletEngine | |||
| final ComponentManager componentManager ) | |||
| throws AntException | |||
| { | |||
| final DefaultComponentManager subComponentManager = | |||
| new DefaultComponentManager( componentManager ); | |||
| subComponentManager.put( "org.apache.ant.configuration.Configurer", m_configurer ); | |||
| if( tasklet instanceof Composer ) | |||
| { | |||
| try { ((Composer)tasklet).compose( componentManager ); } | |||
| try { ((Composer)tasklet).compose( subComponentManager ); } | |||
| catch( final Throwable throwable ) | |||
| { | |||
| throw new AntException( "Error composing task " + task.getName() + " at " + | |||
| @@ -244,10 +273,9 @@ public class DefaultTaskletEngine | |||
| } | |||
| } | |||
| protected Tasklet createTasklet( final Configuration configuration ) | |||
| protected Tasklet createTasklet( final String name ) | |||
| throws AntException | |||
| { | |||
| final String name = configuration.getName(); | |||
| try | |||
| { | |||
| final Locator locator = m_locatorRegistry.getLocator( name ); | |||
| @@ -45,6 +45,7 @@ public class DefaultTskDeployer | |||
| { | |||
| protected final static String TSKDEF_FILE = "TASK-LIB/taskdefs.xml"; | |||
| protected LocatorRegistry m_dataTypeRegistry; | |||
| protected LocatorRegistry m_taskletRegistry; | |||
| protected LocatorRegistry m_converterRegistry; | |||
| protected ConverterRegistry m_converterInfoRegistry; | |||
| @@ -69,16 +70,17 @@ public class DefaultTskDeployer | |||
| public void compose( final ComponentManager componentManager ) | |||
| throws ComponentNotFoundException, ComponentNotAccessibleException | |||
| { | |||
| final ConverterEngine converterEngine = (ConverterEngine)componentManager. | |||
| lookup( "org.apache.ant.convert.ConverterEngine" ); | |||
| m_converterInfoRegistry = converterEngine.getConverterRegistry(); | |||
| m_converterRegistry = converterEngine.getLocatorRegistry(); | |||
| final TaskletEngine taskletEngine = (TaskletEngine)componentManager. | |||
| lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | |||
| m_taskletRegistry = taskletEngine.getLocatorRegistry(); | |||
| final ConverterEngine converterEngine = taskletEngine.getConverterEngine(); | |||
| m_converterInfoRegistry = converterEngine.getInfoRegistry(); | |||
| m_converterRegistry = converterEngine.getRegistry(); | |||
| m_taskletRegistry = taskletEngine.getRegistry(); | |||
| m_dataTypeRegistry = taskletEngine.getDataTypeEngine().getRegistry(); | |||
| } | |||
| public void setLogger( final Logger logger ) | |||
| @@ -106,6 +108,13 @@ public class DefaultTskDeployer | |||
| final Configuration converter = (Configuration)converters.next(); | |||
| handleConverter( converter, url ); | |||
| } | |||
| final Iterator datatypes = taskdefs.getChildren( "datatype" ); | |||
| while( datatypes.hasNext() ) | |||
| { | |||
| final Configuration datatype = (Configuration)datatypes.next(); | |||
| handleDataType( datatype, url ); | |||
| } | |||
| } | |||
| catch( final ConfigurationException ce ) | |||
| { | |||
| @@ -138,6 +147,11 @@ public class DefaultTskDeployer | |||
| throw new DeploymentException( "Malformed taskdefs.xml", ce ); | |||
| } | |||
| } | |||
| public void deployDataType( final String name, final String location, final URL url ) | |||
| throws DeploymentException | |||
| { | |||
| } | |||
| public void deployTasklet( final String name, final String location, final URL url ) | |||
| throws DeploymentException | |||
| @@ -213,4 +227,22 @@ public class DefaultTskDeployer | |||
| m_logger.debug( "Registered tasklet " + name + " as " + classname ); | |||
| } | |||
| protected void handleDataType( final Configuration datatype, final URL url ) | |||
| throws DeploymentException, ConfigurationException | |||
| { | |||
| final String name = datatype.getAttribute( "name" ); | |||
| final String classname = datatype.getAttribute( "classname" ); | |||
| final DefaultLocator info = new DefaultLocator( classname, url ); | |||
| try { m_dataTypeRegistry.register( name, info ); } | |||
| catch( final RegistryException re ) | |||
| { | |||
| throw new DeploymentException( "Error registering " + name + " due to " + re, | |||
| re ); | |||
| } | |||
| m_logger.debug( "Registered datatype " + name + " as " + classname ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,29 @@ | |||
| /* | |||
| * 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.ant.tasklet.engine; | |||
| import org.apache.ant.datatypes.DefaultDataTypeEngine; | |||
| import org.apache.avalon.camelot.DefaultFactory; | |||
| public class TaskletDataTypeEngine | |||
| extends DefaultDataTypeEngine | |||
| { | |||
| /** | |||
| * Set the DataTypeFactory. | |||
| * Package access intended. | |||
| */ | |||
| void setFactory( final DefaultFactory factory ) | |||
| { | |||
| m_factory = factory; | |||
| } | |||
| protected DefaultFactory createFactory() | |||
| { | |||
| return m_factory; | |||
| } | |||
| } | |||
| @@ -10,10 +10,11 @@ package org.apache.ant.tasklet.engine; | |||
| import org.apache.ant.AntException; | |||
| import org.apache.ant.configuration.Configuration; | |||
| import org.apache.ant.convert.ConverterEngine; | |||
| import org.apache.ant.datatypes.DataTypeEngine; | |||
| import org.apache.ant.tasklet.TaskletContext; | |||
| import org.apache.avalon.Component; | |||
| import org.apache.avalon.Loggable; | |||
| import org.apache.avalon.ComponentManager; | |||
| import org.apache.avalon.Loggable; | |||
| import org.apache.avalon.camelot.LocatorRegistry; | |||
| import org.apache.log.Logger; | |||
| @@ -37,7 +38,7 @@ public interface TaskletEngine | |||
| * | |||
| * @return the LocatorRegistry | |||
| */ | |||
| LocatorRegistry getLocatorRegistry(); | |||
| LocatorRegistry getRegistry(); | |||
| /** | |||
| * Retrieve converter engine. | |||
| @@ -46,6 +47,13 @@ public interface TaskletEngine | |||
| */ | |||
| ConverterEngine getConverterEngine(); | |||
| /** | |||
| * Retrieve datatype engine. | |||
| * | |||
| * @return the DataTypeEngine | |||
| */ | |||
| DataTypeEngine getDataTypeEngine(); | |||
| /** | |||
| * execute a task. | |||
| * | |||
| @@ -23,7 +23,10 @@ public interface TskDeployer | |||
| { | |||
| void deployConverter( String name, String location, URL url ) | |||
| throws DeploymentException; | |||
| void deployDataType( String name, String location, URL url ) | |||
| throws DeploymentException; | |||
| void deployTasklet( String name, String location, URL url ) | |||
| throws DeploymentException; | |||
| } | |||
| @@ -15,6 +15,7 @@ import org.apache.ant.tasklet.AbstractTasklet; | |||
| import org.apache.ant.tasklet.DefaultTaskletContext; | |||
| import org.apache.ant.tasklet.TaskletContext; | |||
| import org.apache.avalon.ComponentManager; | |||
| import org.apache.avalon.Context; | |||
| import org.apache.avalon.ComponentNotAccessibleException; | |||
| import org.apache.avalon.ComponentNotFoundException; | |||
| import org.apache.avalon.Composer; | |||
| @@ -32,10 +33,19 @@ public class AntCall | |||
| protected Project m_project; | |||
| protected String m_target; | |||
| protected ArrayList m_properties = new ArrayList(); | |||
| protected TaskletContext m_childContext; | |||
| protected ComponentManager m_componentManager; | |||
| public void contextualize( final Context context ) | |||
| { | |||
| super.contextualize( context ); | |||
| m_childContext = new DefaultTaskletContext( getContext() ); | |||
| } | |||
| public void compose( final ComponentManager componentManager ) | |||
| throws ComponentNotFoundException, ComponentNotAccessibleException | |||
| { | |||
| m_componentManager = componentManager; | |||
| m_projectEngine = (ProjectEngine)componentManager. | |||
| lookup( "org.apache.ant.project.ProjectEngine" ); | |||
| m_project = (Project)componentManager.lookup( "org.apache.ant.project.Project" ); | |||
| @@ -47,8 +57,12 @@ public class AntCall | |||
| } | |||
| public Property createParam() | |||
| throws Exception | |||
| { | |||
| final Property property = new Property(); | |||
| property.setLogger( getLogger() ); | |||
| property.contextualize( m_childContext ); | |||
| property.compose( m_componentManager ); | |||
| m_properties.add( property ); | |||
| return property; | |||
| } | |||
| @@ -61,17 +75,14 @@ public class AntCall | |||
| throw new AntException( "Target attribute must be specified" ); | |||
| } | |||
| final TaskletContext context = new DefaultTaskletContext( getContext() ); | |||
| final int size = m_properties.size(); | |||
| for( int i = 0; i < size; i++ ) | |||
| { | |||
| final Property property = (Property)m_properties.get( i ); | |||
| property.contextualize( context ); | |||
| property.run(); | |||
| } | |||
| getLogger().info( "Calling target " + m_target ); | |||
| m_projectEngine.execute( m_project, m_target, context ); | |||
| m_projectEngine.execute( m_project, m_target, m_childContext ); | |||
| } | |||
| } | |||
| @@ -7,27 +7,130 @@ | |||
| */ | |||
| package org.apache.ant.tasks.core; | |||
| import java.util.Iterator; | |||
| import org.apache.ant.AntException; | |||
| import org.apache.ant.configuration.Configurable; | |||
| import org.apache.ant.configuration.Configuration; | |||
| import org.apache.ant.configuration.Configurer; | |||
| import org.apache.ant.convert.Converter; | |||
| import org.apache.ant.datatypes.DataType; | |||
| import org.apache.ant.datatypes.DataTypeEngine; | |||
| import org.apache.ant.tasklet.AbstractTasklet; | |||
| import org.apache.ant.tasklet.TaskletContext; | |||
| import org.apache.ant.tasklet.engine.TaskletEngine; | |||
| import org.apache.avalon.ComponentManager; | |||
| import org.apache.avalon.ComponentNotAccessibleException; | |||
| import org.apache.avalon.ComponentNotFoundException; | |||
| import org.apache.avalon.Composer; | |||
| import org.apache.avalon.ConfigurationException; | |||
| import org.apache.avalon.Resolvable; | |||
| /** | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class Property | |||
| extends AbstractTasklet | |||
| implements Configurable, Composer | |||
| { | |||
| protected String m_name; | |||
| protected String m_value; | |||
| protected Object m_value; | |||
| protected boolean m_localScope = true; | |||
| protected DataTypeEngine m_engine; | |||
| protected Converter m_converter; | |||
| protected Configurer m_configurer; | |||
| public void compose( final ComponentManager componentManager ) | |||
| throws ComponentNotFoundException, ComponentNotAccessibleException | |||
| { | |||
| m_configurer = (Configurer)componentManager. | |||
| lookup( "org.apache.ant.configuration.Configurer" ); | |||
| final TaskletEngine taskletEngine = (TaskletEngine)componentManager. | |||
| lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | |||
| m_engine = taskletEngine.getDataTypeEngine(); | |||
| m_converter = taskletEngine.getConverterEngine(); | |||
| } | |||
| public void configure( final Configuration configuration ) | |||
| throws ConfigurationException | |||
| { | |||
| final Iterator attributes = configuration.getAttributeNames(); | |||
| while( attributes.hasNext() ) | |||
| { | |||
| final String name = (String)attributes.next(); | |||
| final String value = configuration.getAttribute( name ); | |||
| final Object object = getContext().resolveValue( value ); | |||
| if( null == object ) | |||
| { | |||
| throw new AntException( "Value for attribute " + name + "resolved to null" ); | |||
| } | |||
| if( name.equals( "name" ) ) | |||
| { | |||
| try { setName( (String)m_converter.convert( String.class, object ) ); } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new ConfigurationException( "Error converting value", e ); | |||
| } | |||
| } | |||
| else if( name.equals( "value" ) ) | |||
| { | |||
| setValue( object ); | |||
| } | |||
| else if( name.equals( "local-scope" ) ) | |||
| { | |||
| try | |||
| { | |||
| final Boolean localScope = | |||
| (Boolean)m_converter.convert( Boolean.class, object ); | |||
| setLocalScope( Boolean.TRUE == localScope ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new ConfigurationException( "Error converting value", e ); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| throw new ConfigurationException( "Unknown attribute " + name ); | |||
| } | |||
| } | |||
| final Iterator children = configuration.getChildren(); | |||
| while( children.hasNext() ) | |||
| { | |||
| final Configuration child = (Configuration)children.next(); | |||
| try | |||
| { | |||
| final DataType value = m_engine.createDataType( child.getName() ); | |||
| setValue( value ); | |||
| m_configurer.configure( value, child, getContext() ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new ConfigurationException( "Unable to set datatype", e ); | |||
| } | |||
| } | |||
| } | |||
| public void setName( final String name ) | |||
| { | |||
| m_name = name; | |||
| } | |||
| public void setValue( final String value ) | |||
| public void setValue( final Object value ) | |||
| throws AntException | |||
| { | |||
| if( null != m_value ) | |||
| { | |||
| throw new AntException( "Value can not be set multiple times" ); | |||
| } | |||
| m_value = value; | |||
| } | |||
| @@ -50,7 +153,18 @@ public class Property | |||
| } | |||
| final TaskletContext context = getContext(); | |||
| final Object value = context.resolveValue( m_value ); | |||
| Object value = m_value; | |||
| if( value instanceof String ) | |||
| { | |||
| value = context.resolveValue( (String)value ); | |||
| } | |||
| while( null != value && value instanceof Resolvable ) | |||
| { | |||
| value = ((Resolvable)value).resolve( context ); | |||
| } | |||
| if( m_localScope ) | |||
| { | |||
| @@ -112,10 +112,8 @@ public class RegisterConverter | |||
| try | |||
| { | |||
| m_engine.getConverterEngine(). | |||
| getConverterRegistry().register( m_classname, info ); | |||
| m_engine.getConverterEngine(). | |||
| getLocatorRegistry().register( m_classname, locator ); | |||
| m_engine.getConverterEngine().getInfoRegistry().register( m_classname, info ); | |||
| m_engine.getConverterEngine().getRegistry().register( m_classname, locator ); | |||
| } | |||
| catch( final RegistryException re ) | |||
| { | |||
| @@ -37,7 +37,7 @@ public class RegisterTasklet | |||
| else | |||
| { | |||
| final DefaultLocator locator = new DefaultLocator( classname, url ); | |||
| m_engine.getLocatorRegistry().register( name, locator ); | |||
| m_engine.getRegistry().register( name, locator ); | |||
| } | |||
| } | |||
| } | |||
| @@ -20,12 +20,13 @@ Legal: | |||
| <target name="main" depends="property-test" /> | |||
| <!-- | |||
| =================================================================== | |||
| Help on usage | |||
| =================================================================== | |||
| --> | |||
| <target name="option-test"> | |||
| <target name="no-test-target" unless="do-tests"> | |||
| <echo message="No tests done here"/> | |||
| </target> | |||
| <target name="test-target" depends="no-test-target" if="do-tests"> | |||
| <echo message="Tests away"/> | |||
| <prim-test | |||
| integer="1" | |||
| @@ -54,7 +55,7 @@ Legal: | |||
| </target> | |||
| <target name="property-test"> | |||
| <target name="property-test" depends="test-target"> | |||
| <property name="blah" value="fred" /> | |||
| <property name="${blah}" value="barney" /> | |||
| @@ -77,6 +78,12 @@ Legal: | |||
| <param name="blah" value="blah-value" /> | |||
| </ant-call> | |||
| <property name="foo"> | |||
| <pattern name="*.java"/> | |||
| </property> | |||
| <echo message="foo=${foo}" /> | |||
| </target> | |||
| <target name="property-test2"> | |||
| @@ -9,6 +9,8 @@ | |||
| <task name="register-converter" classname="org.apache.ant.tasks.core.RegisterConverter" /> | |||
| <task name="ant-call" classname="org.apache.ant.tasks.core.AntCall" /> | |||
| <datatype name="pattern" classname="org.apache.ant.datatypes.Pattern" /> | |||
| <converter classname="org.apache.ant.convert.core.StringToLongConverter" | |||
| source="java.lang.String" | |||
| destination="java.lang.Long" /> | |||